diff --git a/src/main/kotlin/dev/usbharu/hideout/query/PostQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/query/PostQueryServiceImpl.kt index dc3d3d9a..718cae24 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/PostQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/PostQueryServiceImpl.kt @@ -4,27 +4,32 @@ import dev.usbharu.hideout.domain.model.hideout.entity.Post import dev.usbharu.hideout.exception.FailedToGetResourcesException import dev.usbharu.hideout.repository.Posts import dev.usbharu.hideout.repository.PostsMedia -import dev.usbharu.hideout.repository.toPost +import dev.usbharu.hideout.repository.QueryMapper +import dev.usbharu.hideout.repository.ResultRowMapper import dev.usbharu.hideout.util.singleOr import org.jetbrains.exposed.sql.select import org.springframework.stereotype.Repository @Repository -class PostQueryServiceImpl : PostQueryService { +class PostQueryServiceImpl( + private val postResultRowMapper: ResultRowMapper, + private val postQueryMapper: QueryMapper +) : PostQueryService { override suspend fun findById(id: Long): Post = Posts.leftJoin(PostsMedia) .select { Posts.id eq id } - .singleOr { FailedToGetResourcesException("id: $id is duplicate or does not exist.", it) }.toPost() + .singleOr { FailedToGetResourcesException("id: $id is duplicate or does not exist.", it) } + .let(postResultRowMapper::map)!! override suspend fun findByUrl(url: String): Post = Posts.leftJoin(PostsMedia) .select { Posts.url eq url } - .toPost() + .let(postQueryMapper::map) .singleOr { FailedToGetResourcesException("url: $url is duplicate or does not exist.", it) } override suspend fun findByApId(string: String): Post = Posts.leftJoin(PostsMedia) .select { Posts.apId eq string } - .toPost() + .let(postQueryMapper::map) .singleOr { FailedToGetResourcesException("apId: $string is duplicate or does not exist.", it) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/query/activitypub/NoteQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/query/activitypub/NoteQueryServiceImpl.kt index 93992395..26f5d23c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/activitypub/NoteQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/activitypub/NoteQueryServiceImpl.kt @@ -13,14 +13,15 @@ import org.springframework.stereotype.Repository import java.time.Instant @Repository -class NoteQueryServiceImpl(private val postRepository: PostRepository) : NoteQueryService { +class NoteQueryServiceImpl(private val postRepository: PostRepository, private val postQueryMapper: QueryMapper) : + NoteQueryService { override suspend fun findById(id: Long): Pair { return Posts .leftJoin(Users) .leftJoin(PostsMedia) .leftJoin(Media) .select { Posts.id eq id } - .let { it.toNote() to it.toPost().first() } + .let { it.toNote() to postQueryMapper.map(it).first() } } diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/PostQueryMapper.kt b/src/main/kotlin/dev/usbharu/hideout/repository/PostQueryMapper.kt new file mode 100644 index 00000000..158adb7e --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/repository/PostQueryMapper.kt @@ -0,0 +1,17 @@ +package dev.usbharu.hideout.repository + +import dev.usbharu.hideout.domain.model.hideout.entity.Post +import org.jetbrains.exposed.sql.Query +import org.springframework.stereotype.Component + +@Component +class PostQueryMapper(private val postResultRowMapper: ResultRowMapper) : QueryMapper { + override fun map(query: Query): List { + return query.groupBy { it[Posts.id] } + .map { it.value } + .map { + it.first().let(postResultRowMapper::map)!! + .copy(mediaIds = it.mapNotNull { it.getOrNull(PostsMedia.mediaId) }) + } + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt index 9100422a..c13c90a7 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt @@ -9,7 +9,10 @@ import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.springframework.stereotype.Repository @Repository -class PostRepositoryImpl(private val idGenerateService: IdGenerateService) : PostRepository { +class PostRepositoryImpl( + private val idGenerateService: IdGenerateService, + private val postQueryMapper: QueryMapper +) : PostRepository { override suspend fun generateId(): Long = idGenerateService.generateId() @@ -65,7 +68,7 @@ class PostRepositoryImpl(private val idGenerateService: IdGenerateService) : Pos override suspend fun findById(id: Long): Post = Posts.innerJoin(PostsMedia, onColumn = { Posts.id }, otherColumn = { PostsMedia.postId }) .select { Posts.id eq id } - .toPost() + .let(postQueryMapper::map) .singleOrNull() ?: throw FailedToGetResourcesException("id: $id was not found.") @@ -95,6 +98,7 @@ object PostsMedia : Table() { override val primaryKey = PrimaryKey(postId, mediaId) } +@Deprecated("toPost is depracated") fun ResultRow.toPost(): Post { return Post.of( id = this[Posts.id], @@ -111,6 +115,7 @@ fun ResultRow.toPost(): Post { ) } +@Deprecated("toPost is deprecated") fun Query.toPost(): List { return this.groupBy { it[Posts.id] } .map { it.value } diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/PostResultRowMapper.kt b/src/main/kotlin/dev/usbharu/hideout/repository/PostResultRowMapper.kt new file mode 100644 index 00000000..7949e401 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/repository/PostResultRowMapper.kt @@ -0,0 +1,25 @@ +package dev.usbharu.hideout.repository + +import dev.usbharu.hideout.domain.model.hideout.entity.Post +import dev.usbharu.hideout.domain.model.hideout.entity.Visibility +import org.jetbrains.exposed.sql.ResultRow +import org.springframework.stereotype.Component + +@Component +class PostResultRowMapper(private val postBuilder: Post.PostBuilder) : ResultRowMapper { + override fun map(resultRow: ResultRow): Post { + return postBuilder.of( + id = resultRow[Posts.id], + userId = resultRow[Posts.userId], + overview = resultRow[Posts.overview], + text = resultRow[Posts.text], + createdAt = resultRow[Posts.createdAt], + visibility = Visibility.values().first { visibility -> visibility.ordinal == resultRow[Posts.visibility] }, + url = resultRow[Posts.url], + repostId = resultRow[Posts.repostId], + replyId = resultRow[Posts.replyId], + sensitive = resultRow[Posts.sensitive], + apId = resultRow[Posts.apId], + ) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/QueryMapper.kt b/src/main/kotlin/dev/usbharu/hideout/repository/QueryMapper.kt new file mode 100644 index 00000000..b5b5fdad --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/repository/QueryMapper.kt @@ -0,0 +1,7 @@ +package dev.usbharu.hideout.repository + +import org.jetbrains.exposed.sql.Query + +interface QueryMapper { + fun map(query: Query): List +} diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/ResultRowMapper.kt b/src/main/kotlin/dev/usbharu/hideout/repository/ResultRowMapper.kt new file mode 100644 index 00000000..2a338e98 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/repository/ResultRowMapper.kt @@ -0,0 +1,7 @@ +package dev.usbharu.hideout.repository + +import org.jetbrains.exposed.sql.ResultRow + +interface ResultRowMapper { + fun map(resultRow: ResultRow): T? +}