From a011d225877f0467f6024989115c36d0e94e045c Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sun, 10 Dec 2023 15:55:09 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=B8=8D=E8=A6=81=E3=81=AA?= =?UTF-8?q?=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=82=92=E5=89=8A=E9=99=A4?= =?UTF-8?q?=E3=80=81FollowQueryService=E3=81=AE=E5=AE=9F=E4=BD=93=E3=82=92?= =?UTF-8?q?RelationshipQueryService=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activity/accept/ApAcceptProcessor.kt | 2 - .../core/domain/model/user/UserRepository.kt | 4 - .../exposedquery/FollowerQueryServiceImpl.kt | 243 +----------------- .../exposedrepository/UserRepositoryImpl.kt | 28 -- .../core/query/FollowerQueryService.kt | 6 +- .../core/query/RelationshipQueryService.kt | 8 + .../account/AccountApiServiceImplTest.kt | 1 - 7 files changed, 21 insertions(+), 271 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/query/RelationshipQueryService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessor.kt index bf5c0f8a..b1838ed4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessor.kt @@ -9,14 +9,12 @@ import dev.usbharu.hideout.activitypub.service.common.ActivityType import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.core.query.UserQueryService import dev.usbharu.hideout.core.service.relationship.RelationshipService -import dev.usbharu.hideout.core.service.user.UserService import org.springframework.stereotype.Service @Service class ApAcceptProcessor( transaction: Transaction, private val userQueryService: UserQueryService, - private val userService: UserService, private val relationshipService: RelationshipService ) : AbstractActivityPubProcessor(transaction) { diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/user/UserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/user/UserRepository.kt index bbc0d346..f37d45fe 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/user/UserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/user/UserRepository.kt @@ -10,9 +10,5 @@ interface UserRepository { suspend fun delete(id: Long) - suspend fun deleteFollowRequest(id: Long, follower: Long) - - suspend fun findFollowRequestsById(id: Long, follower: Long): Boolean - suspend fun nextId(): Long } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/FollowerQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/FollowerQueryServiceImpl.kt index 4c62003e..f8c6bb6e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/FollowerQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/FollowerQueryServiceImpl.kt @@ -1,242 +1,23 @@ package dev.usbharu.hideout.core.infrastructure.exposedquery +import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository import dev.usbharu.hideout.core.domain.model.user.User -import dev.usbharu.hideout.core.infrastructure.exposedrepository.Users -import dev.usbharu.hideout.core.infrastructure.exposedrepository.UsersFollowers import dev.usbharu.hideout.core.query.FollowerQueryService -import org.jetbrains.exposed.sql.* -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import dev.usbharu.hideout.core.query.RelationshipQueryService +import dev.usbharu.hideout.core.query.UserQueryService import org.springframework.stereotype.Repository -import java.time.Instant @Repository -class FollowerQueryServiceImpl(private val userBuilder: User.UserBuilder) : FollowerQueryService { +class FollowerQueryServiceImpl( + private val relationshipQueryService: RelationshipQueryService, + private val userQueryService: UserQueryService, + private val relationshipRepository: RelationshipRepository +) : FollowerQueryService { override suspend fun findFollowersById(id: Long): List { - val followers = Users.alias("FOLLOWERS") - return Users.innerJoin( - otherTable = UsersFollowers, - onColumn = { Users.id }, - otherColumn = { userId } - ) - .innerJoin( - otherTable = followers, - onColumn = { UsersFollowers.followerId }, - otherColumn = { followers[Users.id] } - ) - .slice( - followers[Users.id], - followers[Users.name], - followers[Users.domain], - followers[Users.screenName], - followers[Users.description], - followers[Users.password], - followers[Users.inbox], - followers[Users.outbox], - followers[Users.url], - followers[Users.publicKey], - followers[Users.privateKey], - followers[Users.createdAt], - followers[Users.keyId], - followers[Users.following], - followers[Users.followers], - followers[Users.instance] - ) - .select { Users.id eq id } - .map { - userBuilder.of( - id = it[followers[Users.id]], - name = it[followers[Users.name]], - domain = it[followers[Users.domain]], - screenName = it[followers[Users.screenName]], - description = it[followers[Users.description]], - password = it[followers[Users.password]], - inbox = it[followers[Users.inbox]], - outbox = it[followers[Users.outbox]], - url = it[followers[Users.url]], - publicKey = it[followers[Users.publicKey]], - privateKey = it[followers[Users.privateKey]], - createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]), - keyId = it[followers[Users.keyId]], - followers = it[followers[Users.followers]], - following = it[followers[Users.following]], - instance = it[followers[Users.instance]] - ) - } + return userQueryService.findByIds( + relationshipQueryService.findByTargetIdAndFollowing(id, true).map { it.userId }) } - override suspend fun findFollowersByNameAndDomain(name: String, domain: String): List { - val followers = Users.alias("FOLLOWERS") - return Users.innerJoin( - otherTable = UsersFollowers, - onColumn = { id }, - otherColumn = { userId } - ) - .innerJoin( - otherTable = followers, - onColumn = { UsersFollowers.followerId }, - otherColumn = { followers[Users.id] } - ) - .slice( - followers[Users.id], - followers[Users.name], - followers[Users.domain], - followers[Users.screenName], - followers[Users.description], - followers[Users.password], - followers[Users.inbox], - followers[Users.outbox], - followers[Users.url], - followers[Users.publicKey], - followers[Users.privateKey], - followers[Users.createdAt], - followers[Users.keyId], - followers[Users.following], - followers[Users.followers], - followers[Users.instance] - ) - .select { Users.name eq name and (Users.domain eq domain) } - .map { - userBuilder.of( - id = it[followers[Users.id]], - name = it[followers[Users.name]], - domain = it[followers[Users.domain]], - screenName = it[followers[Users.screenName]], - description = it[followers[Users.description]], - password = it[followers[Users.password]], - inbox = it[followers[Users.inbox]], - outbox = it[followers[Users.outbox]], - url = it[followers[Users.url]], - publicKey = it[followers[Users.publicKey]], - privateKey = it[followers[Users.privateKey]], - createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]), - keyId = it[followers[Users.keyId]], - followers = it[followers[Users.followers]], - following = it[followers[Users.following]], - instance = it[followers[Users.instance]] - ) - } - } - - override suspend fun findFollowingById(id: Long): List { - val followers = Users.alias("FOLLOWERS") - return Users.innerJoin( - otherTable = UsersFollowers, - onColumn = { Users.id }, - otherColumn = { userId } - ) - .innerJoin( - otherTable = followers, - onColumn = { UsersFollowers.followerId }, - otherColumn = { followers[Users.id] } - ) - .slice( - followers[Users.id], - followers[Users.name], - followers[Users.domain], - followers[Users.screenName], - followers[Users.description], - followers[Users.password], - followers[Users.inbox], - followers[Users.outbox], - followers[Users.url], - followers[Users.publicKey], - followers[Users.privateKey], - followers[Users.createdAt], - followers[Users.keyId], - followers[Users.following], - followers[Users.followers], - followers[Users.instance] - ) - .select { followers[Users.id] eq id } - .map { - userBuilder.of( - id = it[followers[Users.id]], - name = it[followers[Users.name]], - domain = it[followers[Users.domain]], - screenName = it[followers[Users.screenName]], - description = it[followers[Users.description]], - password = it[followers[Users.password]], - inbox = it[followers[Users.inbox]], - outbox = it[followers[Users.outbox]], - url = it[followers[Users.url]], - publicKey = it[followers[Users.publicKey]], - privateKey = it[followers[Users.privateKey]], - createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]), - keyId = it[followers[Users.keyId]], - followers = it[followers[Users.followers]], - following = it[followers[Users.following]], - instance = it[followers[Users.instance]] - ) - } - } - - override suspend fun findFollowingByNameAndDomain(name: String, domain: String): List { - val followers = Users.alias("FOLLOWERS") - return Users.innerJoin( - otherTable = UsersFollowers, - onColumn = { id }, - otherColumn = { userId } - ) - .innerJoin( - otherTable = followers, - onColumn = { UsersFollowers.followerId }, - otherColumn = { followers[Users.id] } - ) - .slice( - followers[Users.id], - followers[Users.name], - followers[Users.domain], - followers[Users.screenName], - followers[Users.description], - followers[Users.password], - followers[Users.inbox], - followers[Users.outbox], - followers[Users.url], - followers[Users.publicKey], - followers[Users.privateKey], - followers[Users.createdAt], - followers[Users.keyId], - followers[Users.following], - followers[Users.followers], - followers[Users.instance] - ) - .select { followers[Users.name] eq name and (followers[Users.domain] eq domain) } - .map { - userBuilder.of( - id = it[followers[Users.id]], - name = it[followers[Users.name]], - domain = it[followers[Users.domain]], - screenName = it[followers[Users.screenName]], - description = it[followers[Users.description]], - password = it[followers[Users.password]], - inbox = it[followers[Users.inbox]], - outbox = it[followers[Users.outbox]], - url = it[followers[Users.url]], - publicKey = it[followers[Users.publicKey]], - privateKey = it[followers[Users.privateKey]], - createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]), - keyId = it[followers[Users.keyId]], - followers = it[followers[Users.followers]], - following = it[followers[Users.following]], - instance = it[followers[Users.instance]] - ) - } - } - - override suspend fun appendFollower(user: Long, follower: Long) { - UsersFollowers.insert { - it[userId] = user - it[followerId] = follower - } - } - - override suspend fun removeFollower(user: Long, follower: Long) { - UsersFollowers.deleteWhere { userId eq user and (followerId eq follower) } - } - - override suspend fun alreadyFollow(userId: Long, followerId: Long): Boolean { - return UsersFollowers.select { UsersFollowers.userId eq userId or (UsersFollowers.followerId eq followerId) } - .empty() - .not() - } + override suspend fun alreadyFollow(userId: Long, followerId: Long): Boolean = + relationshipRepository.findByUserIdAndTargetUserId(followerId, userId)?.following ?: false } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserRepositoryImpl.kt index ecd910a6..b4adbaad 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserRepositoryImpl.kt @@ -4,7 +4,6 @@ import dev.usbharu.hideout.application.infrastructure.exposed.ResultRowMapper import dev.usbharu.hideout.application.service.id.IdGenerateService import dev.usbharu.hideout.core.domain.model.user.User import dev.usbharu.hideout.core.domain.model.user.UserRepository -import org.jetbrains.exposed.dao.id.LongIdTable import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.springframework.stereotype.Repository @@ -62,15 +61,6 @@ class UserRepositoryImpl( override suspend fun findById(id: Long): User? = Users.select { Users.id eq id }.singleOrNull()?.let(userResultRowMapper::map) - override suspend fun deleteFollowRequest(id: Long, follower: Long) { - FollowRequests.deleteWhere { userId.eq(id) and followerId.eq(follower) } - } - - override suspend fun findFollowRequestsById(id: Long, follower: Long): Boolean { - return FollowRequests.select { (FollowRequests.userId eq id) and (FollowRequests.followerId eq follower) } - .singleOrNull() != null - } - override suspend fun delete(id: Long) { Users.deleteWhere { Users.id.eq(id) } } @@ -108,21 +98,3 @@ object Users : Table("users") { uniqueIndex(name, domain) } } - -object UsersFollowers : LongIdTable("users_followers") { - val userId: Column = long("user_id").references(Users.id).index() - val followerId: Column = long("follower_id").references(Users.id) - - init { - uniqueIndex(userId, followerId) - } -} - -object FollowRequests : LongIdTable("follow_requests") { - val userId: Column = long("user_id").references(Users.id) - val followerId: Column = long("follower_id").references(Users.id) - - init { - uniqueIndex(userId, followerId) - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/FollowerQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/FollowerQueryService.kt index e5935576..8d3d5bb4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/query/FollowerQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/query/FollowerQueryService.kt @@ -2,12 +2,8 @@ package dev.usbharu.hideout.core.query import dev.usbharu.hideout.core.domain.model.user.User +@Deprecated("Use RelationshipQueryService") interface FollowerQueryService { suspend fun findFollowersById(id: Long): List - suspend fun findFollowersByNameAndDomain(name: String, domain: String): List - suspend fun findFollowingById(id: Long): List - suspend fun findFollowingByNameAndDomain(name: String, domain: String): List - suspend fun appendFollower(user: Long, follower: Long) - suspend fun removeFollower(user: Long, follower: Long) suspend fun alreadyFollow(userId: Long, followerId: Long): Boolean } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/RelationshipQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/RelationshipQueryService.kt new file mode 100644 index 00000000..5f051397 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/query/RelationshipQueryService.kt @@ -0,0 +1,8 @@ +package dev.usbharu.hideout.core.query + +import dev.usbharu.hideout.core.domain.model.relationship.Relationship + +interface RelationshipQueryService { + + suspend fun findByTargetIdAndFollowing(targetId: Long, following: Boolean): List +} diff --git a/src/test/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiServiceImplTest.kt index a34ed5dc..19834065 100644 --- a/src/test/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiServiceImplTest.kt @@ -305,7 +305,6 @@ class AccountApiServiceImplTest { assertThat(relationships).hasSize(0) verify(followerQueryService, never()).alreadyFollow(any(), any()) - verify(userRepository, never()).findFollowRequestsById(any(), any()) } @Test