mirror of https://github.com/usbharu/Hideout.git
refactor: RelationshipRepositoryをPagination APIに変更
This commit is contained in:
parent
ba6e21decd
commit
deb2d5b0b5
|
@ -1,5 +1,6 @@
|
||||||
package dev.usbharu.hideout.application.infrastructure.exposed
|
package dev.usbharu.hideout.application.infrastructure.exposed
|
||||||
|
|
||||||
|
import org.jetbrains.exposed.dao.id.EntityID
|
||||||
import org.jetbrains.exposed.sql.ExpressionWithColumnType
|
import org.jetbrains.exposed.sql.ExpressionWithColumnType
|
||||||
import org.jetbrains.exposed.sql.Query
|
import org.jetbrains.exposed.sql.Query
|
||||||
import org.jetbrains.exposed.sql.SortOrder
|
import org.jetbrains.exposed.sql.SortOrder
|
||||||
|
@ -7,11 +8,24 @@ import org.jetbrains.exposed.sql.andWhere
|
||||||
|
|
||||||
fun Query.pagination(page: Page, exp: ExpressionWithColumnType<Long>): Query {
|
fun Query.pagination(page: Page, exp: ExpressionWithColumnType<Long>): Query {
|
||||||
if (page.minId != null) {
|
if (page.minId != null) {
|
||||||
page.maxId?.let { andWhere { exp.lessEq(it) } }
|
page.maxId?.let { andWhere { exp.less(it) } }
|
||||||
page.minId?.let { andWhere { exp.greaterEq(it) } }
|
page.minId?.let { andWhere { exp.greater(it) } }
|
||||||
} else {
|
} else {
|
||||||
page.maxId?.let { andWhere { exp.lessEq(it) } }
|
page.maxId?.let { andWhere { exp.less(it) } }
|
||||||
page.sinceId?.let { andWhere { exp.greaterEq(it) } }
|
page.sinceId?.let { andWhere { exp.greater(it) } }
|
||||||
|
this.orderBy(exp, SortOrder.DESC)
|
||||||
|
}
|
||||||
|
page.limit?.let { limit(it) }
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Query.pagination(page: Page, exp: ExpressionWithColumnType<EntityID<Long>>): Query {
|
||||||
|
if (page.minId != null) {
|
||||||
|
page.maxId?.let { andWhere { exp.less(it) } }
|
||||||
|
page.minId?.let { andWhere { exp.greater(it) } }
|
||||||
|
} else {
|
||||||
|
page.maxId?.let { andWhere { exp.less(it) } }
|
||||||
|
page.sinceId?.let { andWhere { exp.greater(it) } }
|
||||||
this.orderBy(exp, SortOrder.DESC)
|
this.orderBy(exp, SortOrder.DESC)
|
||||||
}
|
}
|
||||||
page.limit?.let { limit(it) }
|
page.limit?.let { limit(it) }
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package dev.usbharu.hideout.core.domain.model.relationship
|
package dev.usbharu.hideout.core.domain.model.relationship
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.application.infrastructure.exposed.Page
|
||||||
|
import dev.usbharu.hideout.application.infrastructure.exposed.PaginationList
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [Relationship]の永続化
|
* [Relationship]の永続化
|
||||||
*
|
*
|
||||||
|
@ -43,6 +46,13 @@ interface RelationshipRepository {
|
||||||
ignoreFollowRequest: Boolean
|
ignoreFollowRequest: Boolean
|
||||||
): List<Relationship>
|
): List<Relationship>
|
||||||
|
|
||||||
|
suspend fun findByTargetIdAndFollowRequestAndIgnoreFollowRequest(
|
||||||
|
targetIdLong: Long,
|
||||||
|
followRequest: Boolean,
|
||||||
|
ignoreFollowRequest: Boolean,
|
||||||
|
page: Page.PageByMaxId
|
||||||
|
): PaginationList<Relationship, Long>
|
||||||
|
|
||||||
@Suppress("FunctionMaxLength")
|
@Suppress("FunctionMaxLength")
|
||||||
suspend fun findByActorIdAntMutingAndMaxIdAndSinceId(
|
suspend fun findByActorIdAntMutingAndMaxIdAndSinceId(
|
||||||
actorId: Long,
|
actorId: Long,
|
||||||
|
@ -51,4 +61,10 @@ interface RelationshipRepository {
|
||||||
sinceId: Long?,
|
sinceId: Long?,
|
||||||
limit: Int
|
limit: Int
|
||||||
): List<Relationship>
|
): List<Relationship>
|
||||||
|
|
||||||
|
suspend fun findByActorIdAndMuting(
|
||||||
|
actorId: Long,
|
||||||
|
muting: Boolean,
|
||||||
|
page: Page.PageByMaxId
|
||||||
|
): PaginationList<Relationship, Long>
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package dev.usbharu.hideout.core.domain.model.relationship
|
package dev.usbharu.hideout.core.domain.model.relationship
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.application.infrastructure.exposed.Page
|
||||||
|
import dev.usbharu.hideout.application.infrastructure.exposed.PaginationList
|
||||||
|
import dev.usbharu.hideout.application.infrastructure.exposed.pagination
|
||||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.AbstractRepository
|
import dev.usbharu.hideout.core.infrastructure.exposedrepository.AbstractRepository
|
||||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Actors
|
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Actors
|
||||||
import org.jetbrains.exposed.dao.id.LongIdTable
|
import org.jetbrains.exposed.dao.id.LongIdTable
|
||||||
|
@ -97,6 +100,26 @@ class RelationshipRepositoryImpl : RelationshipRepository, AbstractRepository()
|
||||||
return@query query.map { it.toRelationships() }
|
return@query query.map { it.toRelationships() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun findByTargetIdAndFollowRequestAndIgnoreFollowRequest(
|
||||||
|
targetId: Long,
|
||||||
|
followRequest: Boolean,
|
||||||
|
ignoreFollowRequest: Boolean,
|
||||||
|
page: Page.PageByMaxId
|
||||||
|
): PaginationList<Relationship, Long> = query {
|
||||||
|
val query = Relationships.select {
|
||||||
|
Relationships.targetActorId.eq(targetId).and(Relationships.followRequest.eq(followRequest))
|
||||||
|
.and(Relationships.ignoreFollowRequestFromTarget.eq(ignoreFollowRequest))
|
||||||
|
}
|
||||||
|
|
||||||
|
val resultRowList = query.pagination(page, Relationships.id).toList()
|
||||||
|
|
||||||
|
return@query PaginationList(
|
||||||
|
query.map { it.toRelationships() },
|
||||||
|
resultRowList.lastOrNull()?.getOrNull(Relationships.id)?.value,
|
||||||
|
resultRowList.firstOrNull()?.getOrNull(Relationships.id)?.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun findByActorIdAntMutingAndMaxIdAndSinceId(
|
override suspend fun findByActorIdAntMutingAndMaxIdAndSinceId(
|
||||||
actorId: Long,
|
actorId: Long,
|
||||||
muting: Boolean,
|
muting: Boolean,
|
||||||
|
@ -119,6 +142,24 @@ class RelationshipRepositoryImpl : RelationshipRepository, AbstractRepository()
|
||||||
return@query query.map { it.toRelationships() }
|
return@query query.map { it.toRelationships() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun findByActorIdAndMuting(
|
||||||
|
actorId: Long,
|
||||||
|
muting: Boolean,
|
||||||
|
page: Page.PageByMaxId
|
||||||
|
): PaginationList<Relationship, Long> = query {
|
||||||
|
val query = Relationships.select {
|
||||||
|
Relationships.actorId.eq(actorId).and(Relationships.muting.eq(muting))
|
||||||
|
}
|
||||||
|
|
||||||
|
val resultRowList = query.pagination(page, Relationships.id).toList()
|
||||||
|
|
||||||
|
return@query PaginationList(
|
||||||
|
query.map { it.toRelationships() },
|
||||||
|
resultRowList.lastOrNull()?.getOrNull(Relationships.id)?.value,
|
||||||
|
resultRowList.firstOrNull()?.getOrNull(Relationships.id)?.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val logger = LoggerFactory.getLogger(RelationshipRepositoryImpl::class.java)
|
private val logger = LoggerFactory.getLogger(RelationshipRepositoryImpl::class.java)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package dev.usbharu.hideout.mastodon.interfaces.api.account
|
package dev.usbharu.hideout.mastodon.interfaces.api.account
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.application.config.ApplicationConfig
|
||||||
import dev.usbharu.hideout.application.external.Transaction
|
import dev.usbharu.hideout.application.external.Transaction
|
||||||
|
import dev.usbharu.hideout.application.infrastructure.exposed.Page
|
||||||
|
import dev.usbharu.hideout.application.infrastructure.exposed.toHttpHeader
|
||||||
import dev.usbharu.hideout.controller.mastodon.generated.AccountApi
|
import dev.usbharu.hideout.controller.mastodon.generated.AccountApi
|
||||||
import dev.usbharu.hideout.core.infrastructure.springframework.security.LoginUserContextHolder
|
import dev.usbharu.hideout.core.infrastructure.springframework.security.LoginUserContextHolder
|
||||||
import dev.usbharu.hideout.core.service.user.UserCreateDto
|
import dev.usbharu.hideout.core.service.user.UserCreateDto
|
||||||
|
@ -19,12 +22,12 @@ import java.net.URI
|
||||||
class MastodonAccountApiController(
|
class MastodonAccountApiController(
|
||||||
private val accountApiService: AccountApiService,
|
private val accountApiService: AccountApiService,
|
||||||
private val transaction: Transaction,
|
private val transaction: Transaction,
|
||||||
private val loginUserContextHolder: LoginUserContextHolder
|
private val loginUserContextHolder: LoginUserContextHolder,
|
||||||
|
private val applicationConfig: ApplicationConfig
|
||||||
) : AccountApi {
|
) : AccountApi {
|
||||||
|
|
||||||
override suspend fun apiV1AccountsIdFollowPost(
|
override suspend fun apiV1AccountsIdFollowPost(
|
||||||
id: String,
|
id: String, followRequestBody: FollowRequestBody?
|
||||||
followRequestBody: FollowRequestBody?
|
|
||||||
): ResponseEntity<Relationship> {
|
): ResponseEntity<Relationship> {
|
||||||
val userid = loginUserContextHolder.getLoginUserId()
|
val userid = loginUserContextHolder.getLoginUserId()
|
||||||
|
|
||||||
|
@ -35,17 +38,11 @@ class MastodonAccountApiController(
|
||||||
ResponseEntity.ok(accountApiService.account(id.toLong()))
|
ResponseEntity.ok(accountApiService.account(id.toLong()))
|
||||||
|
|
||||||
override suspend fun apiV1AccountsVerifyCredentialsGet(): ResponseEntity<CredentialAccount> = ResponseEntity(
|
override suspend fun apiV1AccountsVerifyCredentialsGet(): ResponseEntity<CredentialAccount> = ResponseEntity(
|
||||||
accountApiService.verifyCredentials(loginUserContextHolder.getLoginUserId()),
|
accountApiService.verifyCredentials(loginUserContextHolder.getLoginUserId()), HttpStatus.OK
|
||||||
HttpStatus.OK
|
|
||||||
)
|
)
|
||||||
|
|
||||||
override suspend fun apiV1AccountsPost(
|
override suspend fun apiV1AccountsPost(
|
||||||
username: String,
|
username: String, password: String, email: String?, agreement: Boolean?, locale: Boolean?, reason: String?
|
||||||
password: String,
|
|
||||||
email: String?,
|
|
||||||
agreement: Boolean?,
|
|
||||||
locale: Boolean?,
|
|
||||||
reason: String?
|
|
||||||
): ResponseEntity<Unit> {
|
): ResponseEntity<Unit> {
|
||||||
transaction.transaction {
|
transaction.transaction {
|
||||||
accountApiService.registerAccount(UserCreateDto(username, username, "", password))
|
accountApiService.registerAccount(UserCreateDto(username, username, "", password))
|
||||||
|
@ -85,8 +82,7 @@ class MastodonAccountApiController(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun apiV1AccountsRelationshipsGet(
|
override fun apiV1AccountsRelationshipsGet(
|
||||||
id: List<String>?,
|
id: List<String>?, withSuspended: Boolean
|
||||||
withSuspended: Boolean
|
|
||||||
): ResponseEntity<Flow<Relationship>> = runBlocking {
|
): ResponseEntity<Flow<Relationship>> = runBlocking {
|
||||||
val userid = loginUserContextHolder.getLoginUserId()
|
val userid = loginUserContextHolder.getLoginUserId()
|
||||||
|
|
||||||
|
@ -128,8 +124,7 @@ class MastodonAccountApiController(
|
||||||
return ResponseEntity.ok(removeFromFollowers)
|
return ResponseEntity.ok(removeFromFollowers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun apiV1AccountsUpdateCredentialsPatch(updateCredentials: UpdateCredentials?):
|
override suspend fun apiV1AccountsUpdateCredentialsPatch(updateCredentials: UpdateCredentials?): ResponseEntity<Account> {
|
||||||
ResponseEntity<Account> {
|
|
||||||
val userid = loginUserContextHolder.getLoginUserId()
|
val userid = loginUserContextHolder.getLoginUserId()
|
||||||
|
|
||||||
val removeFromFollowers = accountApiService.updateProfile(userid, updateCredentials)
|
val removeFromFollowers = accountApiService.updateProfile(userid, updateCredentials)
|
||||||
|
@ -157,10 +152,23 @@ class MastodonAccountApiController(
|
||||||
runBlocking {
|
runBlocking {
|
||||||
val userid = loginUserContextHolder.getLoginUserId()
|
val userid = loginUserContextHolder.getLoginUserId()
|
||||||
|
|
||||||
val accountFlow =
|
val followRequests = accountApiService.followRequests(
|
||||||
accountApiService.followRequests(userid, maxId?.toLong(), sinceId?.toLong(), limit ?: 20, false)
|
userid, false, Page.PageByMaxId(
|
||||||
.asFlow()
|
maxId?.toLongOrNull(), sinceId?.toLongOrNull(), limit?.coerceIn(0, 80) ?: 40
|
||||||
ResponseEntity.ok(accountFlow)
|
)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
val httpHeader = followRequests.toHttpHeader(
|
||||||
|
{ "${applicationConfig.url}/api/v1/follow_requests?max_id=$it" },
|
||||||
|
{ "${applicationConfig.url}/api/v1/follow_requests?min_id=$it" },
|
||||||
|
)
|
||||||
|
|
||||||
|
if (httpHeader != null) {
|
||||||
|
return@runBlocking ResponseEntity.ok().header("Link", httpHeader).body(followRequests.asFlow())
|
||||||
|
}
|
||||||
|
|
||||||
|
ResponseEntity.ok(followRequests.asFlow())
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun apiV1AccountsIdMutePost(id: String): ResponseEntity<Relationship> {
|
override suspend fun apiV1AccountsIdMutePost(id: String): ResponseEntity<Relationship> {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package dev.usbharu.hideout.mastodon.service.account
|
package dev.usbharu.hideout.mastodon.service.account
|
||||||
|
|
||||||
import dev.usbharu.hideout.application.external.Transaction
|
import dev.usbharu.hideout.application.external.Transaction
|
||||||
|
import dev.usbharu.hideout.application.infrastructure.exposed.Page
|
||||||
|
import dev.usbharu.hideout.application.infrastructure.exposed.PaginationList
|
||||||
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
|
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
|
||||||
import dev.usbharu.hideout.core.service.media.MediaService
|
import dev.usbharu.hideout.core.service.media.MediaService
|
||||||
import dev.usbharu.hideout.core.service.relationship.RelationshipService
|
import dev.usbharu.hideout.core.service.relationship.RelationshipService
|
||||||
|
@ -58,11 +60,18 @@ interface AccountApiService {
|
||||||
withIgnore: Boolean
|
withIgnore: Boolean
|
||||||
): List<Account>
|
): List<Account>
|
||||||
|
|
||||||
|
suspend fun followRequests(
|
||||||
|
loginUser: Long,
|
||||||
|
withIgnore: Boolean,
|
||||||
|
pageByMaxId: Page.PageByMaxId
|
||||||
|
): PaginationList<Account, Long>
|
||||||
|
|
||||||
suspend fun acceptFollowRequest(loginUser: Long, target: Long): Relationship
|
suspend fun acceptFollowRequest(loginUser: Long, target: Long): Relationship
|
||||||
suspend fun rejectFollowRequest(loginUser: Long, target: Long): Relationship
|
suspend fun rejectFollowRequest(loginUser: Long, target: Long): Relationship
|
||||||
suspend fun mute(userid: Long, target: Long): Relationship
|
suspend fun mute(userid: Long, target: Long): Relationship
|
||||||
suspend fun unmute(userid: Long, target: Long): Relationship
|
suspend fun unmute(userid: Long, target: Long): Relationship
|
||||||
suspend fun mutesAccount(userid: Long, maxId: Long?, sinceId: Long?, limit: Int): List<Account>
|
suspend fun mutesAccount(userid: Long, maxId: Long?, sinceId: Long?, limit: Int): List<Account>
|
||||||
|
suspend fun mutesAccount(userid: Long, pageByMaxId: Page.PageByMaxId): PaginationList<Account, Long>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@ -236,6 +245,23 @@ class AccountApiServiceImpl(
|
||||||
return@transaction accountService.findByIds(actorIdList)
|
return@transaction accountService.findByIds(actorIdList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun followRequests(
|
||||||
|
loginUser: Long,
|
||||||
|
withIgnore: Boolean,
|
||||||
|
pageByMaxId: Page.PageByMaxId
|
||||||
|
): PaginationList<Account, Long> = transaction.transaction {
|
||||||
|
val request =
|
||||||
|
relationshipRepository.findByTargetIdAndFollowRequestAndIgnoreFollowRequest(
|
||||||
|
loginUser,
|
||||||
|
true,
|
||||||
|
withIgnore,
|
||||||
|
pageByMaxId
|
||||||
|
)
|
||||||
|
val actorIds = request.map { it.actorId }
|
||||||
|
|
||||||
|
return@transaction PaginationList(accountService.findByIds(actorIds), request.next, request.prev)
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun acceptFollowRequest(loginUser: Long, target: Long): Relationship = transaction.transaction {
|
override suspend fun acceptFollowRequest(loginUser: Long, target: Long): Relationship = transaction.transaction {
|
||||||
relationshipService.acceptFollowRequest(loginUser, target)
|
relationshipService.acceptFollowRequest(loginUser, target)
|
||||||
|
|
||||||
|
@ -267,6 +293,16 @@ class AccountApiServiceImpl(
|
||||||
return accountService.findByIds(mutedAccounts.map { it.targetActorId })
|
return accountService.findByIds(mutedAccounts.map { it.targetActorId })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun mutesAccount(userid: Long, pageByMaxId: Page.PageByMaxId): PaginationList<Account, Long> {
|
||||||
|
val mutedAccounts = relationshipRepository.findByActorIdAndMuting(userid, true, pageByMaxId)
|
||||||
|
|
||||||
|
return PaginationList(
|
||||||
|
accountService.findByIds(mutedAccounts.map { it.targetActorId }),
|
||||||
|
mutedAccounts.next,
|
||||||
|
mutedAccounts.prev
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun from(account: Account): CredentialAccount {
|
private fun from(account: Account): CredentialAccount {
|
||||||
return CredentialAccount(
|
return CredentialAccount(
|
||||||
id = account.id,
|
id = account.id,
|
||||||
|
|
Loading…
Reference in New Issue