feat: ページネーションを実装

This commit is contained in:
usbharu 2024-07-20 00:41:16 +09:00
parent 3057d9cc5a
commit b61282a058
Signed by: usbharu
GPG Key ID: 6556747BF94EEBC8
6 changed files with 99 additions and 12 deletions

View File

@ -17,11 +17,13 @@
package dev.usbharu.hideout.core.domain.model.post package dev.usbharu.hideout.core.domain.model.post
import dev.usbharu.hideout.core.domain.model.actor.ActorId import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.support.page.Page
import dev.usbharu.hideout.core.domain.model.support.page.PaginationList
interface PostRepository { interface PostRepository {
suspend fun save(post: Post): Post suspend fun save(post: Post): Post
suspend fun saveAll(posts: List<Post>): List<Post> suspend fun saveAll(posts: List<Post>): List<Post>
suspend fun findById(id: PostId): Post? suspend fun findById(id: PostId): Post?
suspend fun findByActorId(id: ActorId): List<Post> suspend fun findByActorId(id: ActorId, page: Page? = null): PaginationList<Post, PostId>
suspend fun delete(post: Post) suspend fun delete(post: Post)
} }

View File

@ -0,0 +1,46 @@
package dev.usbharu.hideout.core.domain.model.support.page
sealed class Page {
abstract val maxId: Long?
abstract val sinceId: Long?
abstract val minId: Long?
abstract val limit: Int?
data class PageByMaxId(
override val maxId: Long?,
override val sinceId: Long?,
override val limit: Int?
) : Page() {
override val minId: Long? = null
}
data class PageByMinId(
override val maxId: Long?,
override val minId: Long?,
override val limit: Int?
) : Page() {
override val sinceId: Long? = null
}
companion object {
fun of(
maxId: Long? = null,
sinceId: Long? = null,
minId: Long? = null,
limit: Int? = null
): Page =
if (minId != null) {
PageByMinId(
maxId,
minId,
limit
)
} else {
PageByMaxId(
maxId,
sinceId,
limit
)
}
}
}

View File

@ -0,0 +1,3 @@
package dev.usbharu.hideout.core.domain.model.support.page
class PaginationList<T, ID>(list: List<T>, val next: ID?, val prev: ID?) : List<T> by list

View File

@ -55,6 +55,8 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe
protected abstract suspend fun insertTimelineObject(timelineObjectList: List<TimelineObject>) protected abstract suspend fun insertTimelineObject(timelineObjectList: List<TimelineObject>)
protected abstract suspend fun updateTimelineObject(timelineObjectList: List<TimelineObject>)
protected abstract suspend fun getTimelineObjectByPostId(postId: PostId): List<TimelineObject> protected abstract suspend fun getTimelineObjectByPostId(postId: PostId): List<TimelineObject>
protected abstract suspend fun removeTimelineObject(postId: PostId) protected abstract suspend fun removeTimelineObject(postId: PostId)
@ -66,19 +68,27 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe
protected abstract suspend fun getPosts(timelineRelationshipList: List<TimelineRelationship>): List<Post> protected abstract suspend fun getPosts(timelineRelationshipList: List<TimelineRelationship>): List<Post>
override suspend fun updatePost(post: Post) { override suspend fun updatePost(post: Post) {
val timelineObjectByPostId = getTimelineObjectByPostId(post.id) val timelineObjectByPostId = getTimelineObjectByPostId(post.id)
val repost = post.repostId?.let { getPost(it) } val repost = post.repostId?.let { getPost(it) }
if (repost != null) { val timelineObjectList = if (repost != null) {
timelineObjectByPostId.map { timelineObjectByPostId.map {
val filters = getFilters(it.userDetailId) val filters = getFilters(it.userDetailId)
val applyFilters = applyFilters(post, filters) val applyFilters = applyFilters(post, filters)
it.updateWith(post, repost, applyFilters.filterResults) it.updateWith(post, repost, applyFilters.filterResults)
it
}
} else {
timelineObjectByPostId.map {
val filters = getFilters(it.userDetailId)
val applyFilters = applyFilters(post, filters)
it.updateWith(post, applyFilters.filterResults)
it
} }
} }
updateTimelineObject(timelineObjectList)
} }
protected abstract suspend fun getActorPost(actorId: ActorId): List<Post> protected abstract suspend fun getActorPost(actorId: ActorId): List<Post>

View File

@ -9,6 +9,7 @@ import dev.usbharu.hideout.core.domain.model.filter.FilteredPost
import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.Post
import dev.usbharu.hideout.core.domain.model.post.PostId import dev.usbharu.hideout.core.domain.model.post.PostId
import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.domain.model.post.PostRepository
import dev.usbharu.hideout.core.domain.model.support.page.Page
import dev.usbharu.hideout.core.domain.model.timeline.Timeline import dev.usbharu.hideout.core.domain.model.timeline.Timeline
import dev.usbharu.hideout.core.domain.model.timeline.TimelineId import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository
@ -28,7 +29,8 @@ open class DefaultTimelineStore(
private val postRepository: PostRepository, private val postRepository: PostRepository,
private val filterDomainService: FilterDomainService, private val filterDomainService: FilterDomainService,
idGenerateService: IdGenerateService, idGenerateService: IdGenerateService,
private val defaultTimelineStoreConfig: DefaultTimelineStoreConfig private val defaultTimelineStoreConfig: DefaultTimelineStoreConfig,
private val internalTimelineObjectRepository: InternalTimelineObjectRepository
) : AbstractTimelineStore(idGenerateService) { ) : AbstractTimelineStore(idGenerateService) {
override suspend fun getTimelines(actorId: ActorId): List<Timeline> { override suspend fun getTimelines(actorId: ActorId): List<Timeline> {
return timelineRepository.findByIds( return timelineRepository.findByIds(
@ -56,30 +58,34 @@ open class DefaultTimelineStore(
} }
override suspend fun insertTimelineObject(timelineObjectList: List<TimelineObject>) { override suspend fun insertTimelineObject(timelineObjectList: List<TimelineObject>) {
TODO("Not yet implemented") internalTimelineObjectRepository.saveAll(timelineObjectList)
}
override suspend fun updateTimelineObject(timelineObjectList: List<TimelineObject>) {
internalTimelineObjectRepository.saveAll(timelineObjectList)
} }
override suspend fun getTimelineObjectByPostId(postId: PostId): List<TimelineObject> { override suspend fun getTimelineObjectByPostId(postId: PostId): List<TimelineObject> {
TODO("Not yet implemented") return internalTimelineObjectRepository.findByPostId(postId)
} }
override suspend fun removeTimelineObject(postId: PostId) { override suspend fun removeTimelineObject(postId: PostId) {
TODO("Not yet implemented") internalTimelineObjectRepository.deleteByPostId(postId)
} }
override suspend fun removeTimelineObject(timelineId: TimelineId, actorId: ActorId) { override suspend fun removeTimelineObject(timelineId: TimelineId, actorId: ActorId) {
TODO("Not yet implemented") internalTimelineObjectRepository.deleteByTimelineIdAndActorId(timelineId, actorId)
} }
override suspend fun removeTimelineObject(timelineId: TimelineId) { override suspend fun removeTimelineObject(timelineId: TimelineId) {
TODO("Not yet implemented") internalTimelineObjectRepository.deleteByTimelineId(timelineId)
} }
override suspend fun getPosts(timelineRelationshipList: List<TimelineRelationship>): List<Post> { override suspend fun getPosts(timelineRelationshipList: List<TimelineRelationship>): List<Post> {
TODO("Not yet implemented") return timelineRelationshipList.map { it.actorId }.flatMap { getActorPost(it) }
} }
override suspend fun getActorPost(actorId: ActorId): List<Post> { override suspend fun getActorPost(actorId: ActorId): List<Post> {
postRepository.findByActorId() return postRepository.findByActorId(actorId, Page.of(limit = defaultTimelineStoreConfig.actorPostsCount))
} }
} }

View File

@ -0,0 +1,20 @@
package dev.usbharu.hideout.core.infrastructure.timeline
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.post.PostId
import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
import dev.usbharu.hideout.core.domain.model.timelineobject.TimelineObject
interface InternalTimelineObjectRepository {
suspend fun save(timelineObject: TimelineObject): TimelineObject
suspend fun saveAll(timelineObjectList: List<TimelineObject>): List<TimelineObject>
suspend fun findByPostId(postId: PostId): List<TimelineObject>
suspend fun deleteByPostId(postId: PostId)
suspend fun deleteByTimelineIdAndActorId(timelineId: TimelineId, actorId: ActorId)
suspend fun deleteByTimelineId(timelineId: TimelineId)
}