feat: AbstractRepositoryを継承していないRepositoryで継承するように

This commit is contained in:
usbharu 2023-12-21 14:28:17 +09:00
parent 0e547fce3d
commit 2105c47b03
6 changed files with 146 additions and 85 deletions

View File

@ -1,20 +1,23 @@
package dev.usbharu.hideout.core.domain.model.relationship
import dev.usbharu.hideout.core.infrastructure.exposedrepository.AbstractRepository
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Actors
import org.jetbrains.exposed.dao.id.LongIdTable
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@Service
class RelationshipRepositoryImpl : RelationshipRepository {
override suspend fun save(relationship: Relationship): Relationship {
class RelationshipRepositoryImpl : RelationshipRepository, AbstractRepository() {
override suspend fun save(relationship: Relationship): Relationship = query {
val singleOrNull =
Relationships
.select {
(Relationships.actorId eq relationship.actorId)
.and(Relationships.targetActorId eq relationship.targetActorId)
}
}.forUpdate()
.singleOrNull()
if (singleOrNull == null) {
@ -40,32 +43,32 @@ class RelationshipRepositoryImpl : RelationshipRepository {
it[ignoreFollowRequestFromTarget] = relationship.ignoreFollowRequestToTarget
}
}
return relationship
return@query relationship
}
override suspend fun delete(relationship: Relationship) {
override suspend fun delete(relationship: Relationship): Unit = query {
Relationships.deleteWhere {
(Relationships.actorId eq relationship.actorId)
.and(Relationships.targetActorId eq relationship.targetActorId)
}
}
override suspend fun findByUserIdAndTargetUserId(actorId: Long, targetActorId: Long): Relationship? {
return Relationships.select {
override suspend fun findByUserIdAndTargetUserId(actorId: Long, targetActorId: Long): Relationship? = query {
return@query Relationships.select {
(Relationships.actorId eq actorId)
.and(Relationships.targetActorId eq targetActorId)
}.singleOrNull()
?.toRelationships()
}
override suspend fun deleteByActorIdOrTargetActorId(actorId: Long, targetActorId: Long) {
override suspend fun deleteByActorIdOrTargetActorId(actorId: Long, targetActorId: Long): Unit = query {
Relationships.deleteWhere {
Relationships.actorId.eq(actorId).or(Relationships.targetActorId.eq(targetActorId))
}
}
override suspend fun findByTargetIdAndFollowing(targetId: Long, following: Boolean): List<Relationship> {
return Relationships.select { Relationships.targetActorId eq targetId and (Relationships.following eq following) }
override suspend fun findByTargetIdAndFollowing(targetId: Long, following: Boolean): List<Relationship> = query {
return@query Relationships.select { Relationships.targetActorId eq targetId and (Relationships.following eq following) }
.map { it.toRelationships() }
}
@ -76,7 +79,7 @@ class RelationshipRepositoryImpl : RelationshipRepository {
targetId: Long,
followRequest: Boolean,
ignoreFollowRequest: Boolean
): List<Relationship> {
): List<Relationship> = query {
val query = Relationships.select {
Relationships.targetActorId.eq(targetId)
.and(Relationships.followRequest.eq(followRequest))
@ -91,7 +94,14 @@ class RelationshipRepositoryImpl : RelationshipRepository {
query.andWhere { Relationships.id greaterEq sinceId }
}
return query.map { it.toRelationships() }
return@query query.map { it.toRelationships() }
}
override val logger: Logger
get() = Companion.logger
companion object {
private val logger = LoggerFactory.getLogger(RelationshipRepositoryImpl::class.java)
}
}

View File

@ -5,6 +5,8 @@ import dev.usbharu.hideout.core.domain.model.post.Visibility
import dev.usbharu.hideout.core.domain.model.timeline.Timeline
import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository
import org.jetbrains.exposed.sql.*
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.stereotype.Repository
@ -12,11 +14,12 @@ import org.springframework.stereotype.Repository
@Repository
@Qualifier("jdbc")
@ConditionalOnProperty("hideout.use-mongodb", havingValue = "false", matchIfMissing = true)
class ExposedTimelineRepository(private val idGenerateService: IdGenerateService) : TimelineRepository {
class ExposedTimelineRepository(private val idGenerateService: IdGenerateService) : TimelineRepository,
AbstractRepository() {
override suspend fun generateId(): Long = idGenerateService.generateId()
override suspend fun save(timeline: Timeline): Timeline {
if (Timelines.select { Timelines.id eq timeline.id }.singleOrNull() == null) {
override suspend fun save(timeline: Timeline): Timeline = query {
if (Timelines.select { Timelines.id eq timeline.id }.forUpdate().singleOrNull() == null) {
Timelines.insert {
it[id] = timeline.id
it[userId] = timeline.userId
@ -48,10 +51,10 @@ class ExposedTimelineRepository(private val idGenerateService: IdGenerateService
it[mediaIds] = timeline.mediaIds.joinToString(",")
}
}
return timeline
return@query timeline
}
override suspend fun saveAll(timelines: List<Timeline>): List<Timeline> {
override suspend fun saveAll(timelines: List<Timeline>): List<Timeline> = query {
Timelines.batchInsert(timelines, true, false) {
this[Timelines.id] = it.id
this[Timelines.userId] = it.userId
@ -67,20 +70,28 @@ class ExposedTimelineRepository(private val idGenerateService: IdGenerateService
this[Timelines.isPureRepost] = it.isPureRepost
this[Timelines.mediaIds] = it.mediaIds.joinToString(",")
}
return timelines
return@query timelines
}
override suspend fun findByUserId(id: Long): List<Timeline> =
Timelines.select { Timelines.userId eq id }.map { it.toTimeline() }
override suspend fun findByUserId(id: Long): List<Timeline> = query {
return@query Timelines.select { Timelines.userId eq id }.map { it.toTimeline() }
}
override suspend fun findByUserIdAndTimelineId(userId: Long, timelineId: Long): List<Timeline> =
Timelines.select { Timelines.userId eq userId and (Timelines.timelineId eq timelineId) }
override suspend fun findByUserIdAndTimelineId(userId: Long, timelineId: Long): List<Timeline> = query {
return@query Timelines.select { Timelines.userId eq userId and (Timelines.timelineId eq timelineId) }
.map { it.toTimeline() }
}
override val logger: Logger
get() = Companion.logger
companion object {
private val logger = LoggerFactory.getLogger(ExposedTimelineRepository::class.java)
}
}
fun ResultRow.toTimeline(): Timeline {
return Timeline(
id = this[Timelines.id],
return Timeline(id = this[Timelines.id],
userId = this[Timelines.userId],
timelineId = this[Timelines.timelineId],
postId = this[Timelines.postId],
@ -92,8 +103,7 @@ fun ResultRow.toTimeline(): Timeline {
sensitive = this[Timelines.sensitive],
isLocal = this[Timelines.isLocal],
isPureRepost = this[Timelines.isPureRepost],
mediaIds = this[Timelines.mediaIds].split(",").mapNotNull { it.toLongOrNull() }
)
mediaIds = this[Timelines.mediaIds].split(",").mapNotNull { it.toLongOrNull() })
}
object Timelines : Table("timelines") {

View File

@ -5,15 +5,18 @@ import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.javatime.timestamp
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Repository
import dev.usbharu.hideout.core.domain.model.instance.Instance as InstanceEntity
@Repository
class InstanceRepositoryImpl(private val idGenerateService: IdGenerateService) : InstanceRepository {
class InstanceRepositoryImpl(private val idGenerateService: IdGenerateService) : InstanceRepository,
AbstractRepository() {
override suspend fun generateId(): Long = idGenerateService.generateId()
override suspend fun save(instance: InstanceEntity): InstanceEntity {
if (Instance.select { Instance.id.eq(instance.id) }.empty()) {
override suspend fun save(instance: InstanceEntity): InstanceEntity = query {
if (Instance.select { Instance.id.eq(instance.id) }.forUpdate().empty()) {
Instance.insert {
it[id] = instance.id
it[name] = instance.name
@ -43,20 +46,27 @@ class InstanceRepositoryImpl(private val idGenerateService: IdGenerateService) :
it[createdAt] = instance.createdAt
}
}
return instance
return@query instance
}
override suspend fun findById(id: Long): InstanceEntity? {
return Instance.select { Instance.id eq id }
override suspend fun findById(id: Long): InstanceEntity? = query {
return@query Instance.select { Instance.id eq id }
.singleOrNull()?.toInstance()
}
override suspend fun delete(instance: InstanceEntity) {
override suspend fun delete(instance: InstanceEntity): Unit = query {
Instance.deleteWhere { id eq instance.id }
}
override suspend fun findByUrl(url: String): dev.usbharu.hideout.core.domain.model.instance.Instance? {
return Instance.select { Instance.url eq url }.singleOrNull()?.toInstance()
override suspend fun findByUrl(url: String): dev.usbharu.hideout.core.domain.model.instance.Instance? = query {
return@query Instance.select { Instance.url eq url }.singleOrNull()?.toInstance()
}
override val logger: Logger
get() = Companion.logger
companion object {
private val logger = LoggerFactory.getLogger(InstanceRepositoryImpl::class.java)
}
}

View File

@ -7,14 +7,16 @@ import dev.usbharu.hideout.core.service.media.FileType
import dev.usbharu.hideout.core.service.media.MimeType
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Repository
import dev.usbharu.hideout.core.domain.model.media.Media as EntityMedia
@Repository
class MediaRepositoryImpl(private val idGenerateService: IdGenerateService) : MediaRepository {
class MediaRepositoryImpl(private val idGenerateService: IdGenerateService) : MediaRepository, AbstractRepository() {
override suspend fun generateId(): Long = idGenerateService.generateId()
override suspend fun save(media: EntityMedia): EntityMedia {
override suspend fun save(media: EntityMedia): EntityMedia = query {
if (Media.select {
Media.id eq media.id
}.forUpdate().singleOrNull() != null
@ -42,11 +44,11 @@ class MediaRepositoryImpl(private val idGenerateService: IdGenerateService) : Me
it[description] = media.description
}
}
return media
return@query media
}
override suspend fun findById(id: Long): EntityMedia? {
return Media
override suspend fun findById(id: Long): EntityMedia? = query {
return@query Media
.select {
Media.id eq id
}
@ -54,14 +56,22 @@ class MediaRepositoryImpl(private val idGenerateService: IdGenerateService) : Me
?.toMedia()
}
override suspend fun delete(id: Long) {
override suspend fun delete(id: Long): Unit = query {
Media.deleteWhere {
Media.id eq id
}
}
override suspend fun findByRemoteUrl(remoteUrl: String): dev.usbharu.hideout.core.domain.model.media.Media? {
return Media.select { Media.remoteUrl eq remoteUrl }.singleOrNull()?.toMedia()
override suspend fun findByRemoteUrl(remoteUrl: String): dev.usbharu.hideout.core.domain.model.media.Media? =
query {
return@query Media.select { Media.remoteUrl eq remoteUrl }.singleOrNull()?.toMedia()
}
override val logger: Logger
get() = Companion.logger
companion object {
private val logger = LoggerFactory.getLogger(MediaRepositoryImpl::class.java)
}
}

View File

@ -6,17 +6,19 @@ import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository
import org.jetbrains.exposed.dao.id.LongIdTable
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Repository
@Repository
class ReactionRepositoryImpl(
private val idGenerateService: IdGenerateService
) : ReactionRepository {
) : ReactionRepository, AbstractRepository() {
override suspend fun generateId(): Long = idGenerateService.generateId()
override suspend fun save(reaction: Reaction): Reaction {
if (Reactions.select { Reactions.id eq reaction.id }.empty()) {
override suspend fun save(reaction: Reaction): Reaction = query {
if (Reactions.select { Reactions.id eq reaction.id }.forUpdate().empty()) {
Reactions.insert {
it[id] = reaction.id
it[emojiId] = reaction.emojiId
@ -30,69 +32,79 @@ class ReactionRepositoryImpl(
it[actorId] = reaction.actorId
}
}
return reaction
return@query reaction
}
override suspend fun delete(reaction: Reaction): Reaction {
override suspend fun delete(reaction: Reaction): Reaction = query {
Reactions.deleteWhere {
id.eq(reaction.id)
.and(postId.eq(reaction.postId))
.and(actorId.eq(reaction.actorId))
id.eq(reaction.id).and(postId.eq(reaction.postId)).and(actorId.eq(reaction.actorId))
.and(emojiId.eq(reaction.emojiId))
}
return reaction
return@query reaction
}
override suspend fun deleteByPostId(postId: Long): Int {
return Reactions.deleteWhere {
override suspend fun deleteByPostId(postId: Long): Int = query {
return@query Reactions.deleteWhere {
Reactions.postId eq postId
}
}
override suspend fun deleteByActorId(actorId: Long): Int {
return Reactions.deleteWhere {
override suspend fun deleteByActorId(actorId: Long): Int = query {
return@query Reactions.deleteWhere {
Reactions.actorId eq actorId
}
}
override suspend fun findByPostId(postId: Long): List<Reaction> {
return Reactions.select { Reactions.postId eq postId }.map { it.toReaction() }
override suspend fun findByPostId(postId: Long): List<Reaction> = query {
return@query Reactions.select { Reactions.postId eq postId }.map { it.toReaction() }
}
override suspend fun findByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Reaction? {
return Reactions.select {
Reactions.postId eq postId and (Reactions.actorId eq actorId).and(
Reactions.emojiId.eq(
emojiId
override suspend fun findByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Reaction? =
query {
return@query Reactions.select {
Reactions.postId eq postId and (Reactions.actorId eq actorId).and(
Reactions.emojiId.eq(
emojiId
)
)
)
}.singleOrNull()?.toReaction()
}.singleOrNull()?.toReaction()
}
override suspend fun existByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Boolean =
query {
return@query Reactions.select {
Reactions.postId
.eq(postId)
.and(Reactions.actorId.eq(actorId))
.and(Reactions.emojiId.eq(emojiId))
}.empty().not()
}
override suspend fun findByPostIdAndActorId(postId: Long, actorId: Long): List<Reaction> = query {
return@query Reactions.select { Reactions.postId eq postId and (Reactions.actorId eq actorId) }
.map { it.toReaction() }
}
override suspend fun existByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Boolean {
TODO("Not yet implemented")
}
override val logger: Logger
get() = Companion.logger
override suspend fun findByPostIdAndActorId(postId: Long, actorId: Long): List<Reaction> {
TODO("Not yet implemented")
companion object {
private val logger = LoggerFactory.getLogger(ReactionRepositoryImpl::class.java)
}
}
fun ResultRow.toReaction(): Reaction {
return Reaction(
this[Reactions.id].value,
this[Reactions.emojiId],
this[Reactions.postId],
this[Reactions.actorId]
this[Reactions.id].value, this[Reactions.emojiId], this[Reactions.postId], this[Reactions.actorId]
)
}
object Reactions : LongIdTable("reactions") {
val emojiId: Column<Long> = long("emoji_id")
val postId: Column<Long> = long("post_id")
.references(Posts.id, onDelete = ReferenceOption.CASCADE, onUpdate = ReferenceOption.CASCADE)
val actorId: Column<Long> = long("actor_id")
.references(Actors.id, onDelete = ReferenceOption.CASCADE, onUpdate = ReferenceOption.CASCADE)
val postId: Column<Long> =
long("post_id").references(Posts.id, onDelete = ReferenceOption.CASCADE, onUpdate = ReferenceOption.CASCADE)
val actorId: Column<Long> =
long("actor_id").references(Actors.id, onDelete = ReferenceOption.CASCADE, onUpdate = ReferenceOption.CASCADE)
init {
uniqueIndex(emojiId, postId, actorId)

View File

@ -8,12 +8,14 @@ import org.jetbrains.exposed.sql.deleteWhere
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.update
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Repository
@Repository
class UserDetailRepositoryImpl : UserDetailRepository {
override suspend fun save(userDetail: UserDetail): UserDetail {
val singleOrNull = UserDetails.select { UserDetails.actorId eq userDetail.actorId }.singleOrNull()
class UserDetailRepositoryImpl : UserDetailRepository, AbstractRepository() {
override suspend fun save(userDetail: UserDetail): UserDetail = query {
val singleOrNull = UserDetails.select { UserDetails.actorId eq userDetail.actorId }.forUpdate().singleOrNull()
if (singleOrNull == null) {
UserDetails.insert {
it[actorId] = userDetail.actorId
@ -26,15 +28,15 @@ class UserDetailRepositoryImpl : UserDetailRepository {
it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest
}
}
return userDetail
return@query userDetail
}
override suspend fun delete(userDetail: UserDetail) {
override suspend fun delete(userDetail: UserDetail): Unit = query {
UserDetails.deleteWhere { UserDetails.actorId eq userDetail.actorId }
}
override suspend fun findByActorId(actorId: Long): UserDetail? {
return UserDetails
override suspend fun findByActorId(actorId: Long): UserDetail? = query {
return@query UserDetails
.select { UserDetails.actorId eq actorId }
.singleOrNull()
?.let {
@ -45,6 +47,13 @@ class UserDetailRepositoryImpl : UserDetailRepository {
)
}
}
override val logger: Logger
get() = Companion.logger
companion object {
private val logger = LoggerFactory.getLogger(UserDetailRepositoryImpl::class.java)
}
}
object UserDetails : LongIdTable("user_details") {