refactor: Actorsテーブルにフォロワー数情報とフォロー数情報を追加

This commit is contained in:
usbharu 2023-12-14 00:16:45 +09:00
parent e0368ab7c5
commit 77d79e2279
4 changed files with 121 additions and 31 deletions

View File

@ -22,7 +22,11 @@ data class Actor private constructor(
val followers: String? = null,
val following: String? = null,
val instance: Long? = null,
val locked: Boolean
val locked: Boolean,
val followersCount: Int = 0,
val followingCount: Int = 0,
val postsCount: Int = 0,
val lastPostDate: Instant? = null
) {
@Component
@ -47,7 +51,11 @@ data class Actor private constructor(
following: String? = null,
followers: String? = null,
instance: Long? = null,
locked: Boolean
locked: Boolean,
followersCount: Int,
followingCount: Int,
postsCount: Int,
lastPostDate: Instant?
): Actor {
// idは0未満ではいけない
require(id >= 0) { "id must be greater than or equal to 0." }
@ -123,6 +131,18 @@ data class Actor private constructor(
"keyId must contain non-blank characters."
}
require(postsCount >= 0) {
"postsCount must be greater than or equal to 0"
}
require(followersCount >= 0) {
"followersCount must be greater than or equal to 0"
}
require(followingCount >= 0) {
"followingCount must be greater than or equal to 0"
}
return Actor(
id = id,
name = limitedName,
@ -139,29 +159,47 @@ data class Actor private constructor(
followers = followers,
following = following,
instance = instance,
locked
locked = locked,
followersCount = followersCount,
followingCount = followingCount,
postsCount = postsCount,
lastPostDate = lastPostDate
)
}
}
fun incrementFollowing(): Actor = this.copy(followingCount = this.followingCount + 1)
fun decrementFollowing(): Actor = this.copy(followingCount = this.followingCount - 1)
fun incrementFollowers(): Actor = this.copy(followersCount = this.followersCount + 1)
fun decrementFollowers(): Actor = this.copy(followersCount = this.followersCount - 1)
fun incrementPostsCount(): Actor = this.copy(postsCount = this.postsCount + 1)
fun decrementPostsCount(): Actor = this.copy(postsCount = this.postsCount - 1)
fun withLastPostAt(lastPostDate: Instant): Actor = this.copy(lastPostDate = lastPostDate)
override fun toString(): String {
return "Actor(" +
"id=$id, " +
"name='$name', " +
"domain='$domain', " +
"screenName='$screenName', " +
"description='$description', " +
"inbox='$inbox', " +
"outbox='$outbox', " +
"url='$url', " +
"publicKey='$publicKey', " +
"privateKey=$privateKey, " +
"createdAt=$createdAt, " +
"keyId='$keyId', " +
"followers=$followers, " +
"following=$following, " +
"instance=$instance, " +
"locked=$locked" +
")"
"id=$id, " +
"name='$name', " +
"domain='$domain', " +
"screenName='$screenName', " +
"description='$description', " +
"inbox='$inbox', " +
"outbox='$outbox', " +
"url='$url', " +
"publicKey='$publicKey', " +
"privateKey=$privateKey, " +
"createdAt=$createdAt, " +
"keyId='$keyId', " +
"followers=$followers, " +
"following=$following, " +
"instance=$instance, " +
"locked=$locked" +
")"
}
}

View File

@ -26,7 +26,11 @@ class UserResultRowMapper(private val actorBuilder: Actor.UserBuilder) : ResultR
followers = resultRow[Actors.followers],
following = resultRow[Actors.following],
instance = resultRow[Actors.instance],
locked = resultRow[Actors.locked]
locked = resultRow[Actors.locked],
followingCount = resultRow[Actors.followingCount],
followersCount = resultRow[Actors.followersCount],
postsCount = resultRow[Actors.postsCount],
lastPostDate = resultRow[Actors.lastPostAt],
)
}
}

View File

@ -6,6 +6,7 @@ import dev.usbharu.hideout.core.domain.model.actor.Actor
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.javatime.timestamp
import org.springframework.stereotype.Repository
@Repository
@ -35,6 +36,10 @@ class ActorRepositoryImpl(
it[followers] = actor.followers
it[instance] = actor.instance
it[locked] = actor.locked
it[followersCount] = actor.followersCount
it[followingCount] = actor.followingCount
it[postsCount] = actor.postsCount
it[lastPostAt] = actor.lastPostDate
}
} else {
Actors.update({ Actors.id eq actor.id }) {
@ -53,6 +58,10 @@ class ActorRepositoryImpl(
it[followers] = actor.followers
it[instance] = actor.instance
it[locked] = actor.locked
it[followersCount] = actor.followersCount
it[followingCount] = actor.followingCount
it[postsCount] = actor.postsCount
it[lastPostAt] = actor.lastPostDate
}
}
return actor
@ -91,6 +100,10 @@ object Actors : Table("actors") {
val followers = varchar("followers", length = 1000).nullable()
val instance = long("instance").references(Instance.id).nullable()
val locked = bool("locked")
val followingCount = integer("following_count")
val followersCount = integer("followers_count")
val postsCount = integer("posts_count")
val lastPostAt = timestamp("last_post_at").nullable()
override val primaryKey: PrimaryKey = PrimaryKey(id)

View File

@ -8,6 +8,7 @@ import dev.usbharu.hideout.activitypub.service.activity.undo.APSendUndoService
import dev.usbharu.hideout.application.config.ApplicationConfig
import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException
import dev.usbharu.hideout.core.domain.model.actor.Actor
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.relationship.Relationship
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
import dev.usbharu.hideout.core.query.ActorQueryService
@ -24,7 +25,8 @@ class RelationshipServiceImpl(
private val apSendBlockService: APSendBlockService,
private val apSendAcceptService: ApSendAcceptService,
private val apSendRejectService: ApSendRejectService,
private val apSendUndoService: APSendUndoService
private val apSendUndoService: APSendUndoService,
private val actorRepository: ActorRepository
) : RelationshipService {
override suspend fun followRequest(actorId: Long, targetId: Long) {
logger.info("START Follow Request userId: {} targetId: {}", actorId, targetId)
@ -90,6 +92,15 @@ class RelationshipServiceImpl(
override suspend fun block(actorId: Long, targetId: Long) {
val relationship = relationshipRepository.findByUserIdAndTargetUserId(actorId, targetId)
val user = actorQueryService.findById(actorId)
val targetActor = actorQueryService.findById(targetId)
if (relationship?.following == true) {
actorRepository.save(user.decrementFollowing())
actorRepository.save(targetActor.decrementFollowers())
}
val blockedRelationship = relationship
?.copy(blocking = true, followRequest = false, following = false) ?: Relationship(
actorId = actorId,
targetActorId = targetId,
@ -101,17 +112,26 @@ class RelationshipServiceImpl(
)
val inverseRelationship = relationshipRepository.findByUserIdAndTargetUserId(targetId, actorId)
if (inverseRelationship?.following == true) {
actorRepository.save(targetActor.decrementFollowing())
actorRepository.save(user.decrementFollowers())
}
val blockedInverseRelationship = inverseRelationship
?.copy(followRequest = false, following = false)
relationshipRepository.save(relationship)
if (inverseRelationship != null) {
relationshipRepository.save(inverseRelationship)
relationshipRepository.save(blockedRelationship)
if (blockedInverseRelationship != null) {
relationshipRepository.save(blockedInverseRelationship)
}
val remoteUser = isRemoteUser(targetId)
if (remoteUser != null) {
val user = actorQueryService.findById(actorId)
apSendBlockService.sendBlock(user, remoteUser)
}
}
@ -157,13 +177,18 @@ class RelationshipServiceImpl(
val copy = relationship.copy(followRequest = false, following = true, blocking = false)
val user = actorQueryService.findById(actorId)
actorRepository.save(user.incrementFollowers())
relationshipRepository.save(copy)
val remoteUser = isRemoteUser(targetId)
val remoteActor = actorQueryService.findById(targetId)
if (remoteUser != null) {
val user = actorQueryService.findById(actorId)
apSendAcceptService.sendAcceptFollow(user, remoteUser)
actorRepository.save(remoteActor.incrementFollowing())
if (isRemoteActor(remoteActor)) {
apSendAcceptService.sendAcceptFollow(user, remoteActor)
}
}
@ -216,6 +241,14 @@ class RelationshipServiceImpl(
return
}
val user = actorQueryService.findById(actorId)
val targetActor = actorQueryService.findById(targetId)
if (relationship.following) {
actorRepository.save(user.decrementFollowing())
actorRepository.save(targetActor.decrementFollowers())
}
if (relationship.following.not()) {
logger.warn("SUCCESS User already unfollow. userId: {} targetId: {}", actorId, targetId)
return
@ -228,7 +261,7 @@ class RelationshipServiceImpl(
val remoteUser = isRemoteUser(targetId)
if (remoteUser != null) {
val user = actorQueryService.findById(actorId)
apSendUndoService.sendUndoFollow(user, remoteUser)
}
}
@ -282,6 +315,8 @@ class RelationshipServiceImpl(
relationshipRepository.save(relationship)
}
private fun isRemoteActor(actor: Actor): Boolean = actor.domain != applicationConfig.url.host
private suspend fun isRemoteUser(userId: Long): Actor? {
logger.trace("isRemoteUser({})", userId)
val user = try {