mirror of https://github.com/usbharu/Hideout.git
feat: AccountQueryServiceを作成し、アカウントAPIから取得される情報を正確に
This commit is contained in:
parent
ef6c97b08c
commit
69a889a8d7
|
@ -0,0 +1,100 @@
|
|||
package dev.usbharu.hideout.mastodon.infrastructure.exposedquery
|
||||
|
||||
import dev.usbharu.hideout.application.config.ApplicationConfig
|
||||
import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException
|
||||
import dev.usbharu.hideout.core.domain.model.relationship.Relationships
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Actors
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts
|
||||
import dev.usbharu.hideout.domain.mastodon.model.generated.Account
|
||||
import dev.usbharu.hideout.mastodon.query.AccountQueryService
|
||||
import dev.usbharu.hideout.util.singleOr
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.springframework.stereotype.Repository
|
||||
import java.time.Instant
|
||||
|
||||
@Repository
|
||||
class AccountQueryServiceImpl(private val applicationConfig: ApplicationConfig) : AccountQueryService {
|
||||
override suspend fun findById(accountId: Long): Account {
|
||||
val followingCount = Count(Relationships.actorId.eq(Actors.id), true).alias("following_count")
|
||||
val followersCount = Count(Relationships.targetActorId.eq(Actors.id), true).alias("followers_count")
|
||||
val postsCount = Posts.id.countDistinct().alias("posts_count")
|
||||
val lastCreated = Posts.createdAt.max().alias("last_created")
|
||||
val query = Actors
|
||||
.join(Relationships, JoinType.LEFT) {
|
||||
Actors.id eq Relationships.actorId or (Actors.id eq Relationships.targetActorId)
|
||||
}
|
||||
.leftJoin(Posts)
|
||||
.slice(
|
||||
followingCount,
|
||||
followersCount,
|
||||
*(Actors.realFields.toTypedArray()),
|
||||
lastCreated,
|
||||
postsCount
|
||||
)
|
||||
.select { Actors.id eq accountId and (Relationships.following eq true or (Relationships.following.isNull())) }
|
||||
.groupBy(Actors.id)
|
||||
|
||||
return query
|
||||
.singleOr { FailedToGetResourcesException("accountId: $accountId wad not exist or duplicate", it) }
|
||||
.let { toAccount(it, followingCount, followersCount, postsCount, lastCreated) }
|
||||
}
|
||||
|
||||
override suspend fun findByIds(accountIds: List<Long>): List<Account> {
|
||||
val followingCount = Count(Relationships.actorId.eq(Actors.id), true).alias("following_count")
|
||||
val followersCount = Count(Relationships.targetActorId.eq(Actors.id), true).alias("followers_count")
|
||||
val postsCount = Posts.id.countDistinct().alias("posts_count")
|
||||
val lastCreated = Posts.createdAt.max().alias("last_created")
|
||||
val query = Actors
|
||||
.join(Relationships, JoinType.LEFT) {
|
||||
Actors.id eq Relationships.actorId or (Actors.id eq Relationships.targetActorId)
|
||||
}
|
||||
.leftJoin(Posts)
|
||||
.slice(
|
||||
followingCount,
|
||||
followersCount,
|
||||
*(Actors.realFields.toTypedArray()),
|
||||
lastCreated,
|
||||
postsCount
|
||||
)
|
||||
.select { Actors.id inList accountIds and (Relationships.following eq true or (Relationships.following.isNull())) }
|
||||
.groupBy(Actors.id)
|
||||
|
||||
return query
|
||||
.map { toAccount(it, followingCount, followersCount, postsCount, lastCreated) }
|
||||
}
|
||||
|
||||
private fun toAccount(
|
||||
resultRow: ResultRow,
|
||||
followingCount: ExpressionAlias<Long>,
|
||||
followersCount: ExpressionAlias<Long>,
|
||||
postsCount: ExpressionAlias<Long>,
|
||||
lastCreated: ExpressionAlias<Long?>
|
||||
): Account {
|
||||
val userUrl = "${applicationConfig.url}/users/${resultRow[Actors.id]}"
|
||||
|
||||
return Account(
|
||||
id = resultRow[Actors.id].toString(),
|
||||
username = resultRow[Actors.name],
|
||||
acct = "${resultRow[Actors.name]}@${resultRow[Actors.domain]}",
|
||||
url = resultRow[Actors.url],
|
||||
displayName = resultRow[Actors.screenName],
|
||||
note = resultRow[Actors.description],
|
||||
avatar = userUrl + "/icon.jpg",
|
||||
avatarStatic = userUrl + "/icon.jpg",
|
||||
header = userUrl + "/header.jpg",
|
||||
headerStatic = userUrl + "/header.jpg",
|
||||
locked = resultRow[Actors.locked],
|
||||
fields = emptyList(),
|
||||
emojis = emptyList(),
|
||||
bot = false,
|
||||
group = false,
|
||||
discoverable = true,
|
||||
createdAt = Instant.ofEpochMilli(resultRow[Actors.createdAt]).toString(),
|
||||
lastStatusAt = resultRow[lastCreated]?.let { Instant.ofEpochMilli(it).toString() },
|
||||
statusesCount = resultRow[postsCount].toInt(),
|
||||
followersCount = resultRow[followersCount].toInt(),
|
||||
followingCount = resultRow[followingCount].toInt(),
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package dev.usbharu.hideout.mastodon.query
|
||||
|
||||
import dev.usbharu.hideout.domain.mastodon.model.generated.Account
|
||||
|
||||
interface AccountQueryService {
|
||||
suspend fun findById(accountId: Long): Account
|
||||
suspend fun findByIds(accountIds: List<Long>): List<Account>
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
package dev.usbharu.hideout.mastodon.service.account
|
||||
|
||||
import dev.usbharu.hideout.application.config.ApplicationConfig
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor
|
||||
import dev.usbharu.hideout.core.query.ActorQueryService
|
||||
import dev.usbharu.hideout.domain.mastodon.model.generated.Account
|
||||
import dev.usbharu.hideout.mastodon.query.AccountQueryService
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
|
@ -14,41 +12,13 @@ interface AccountService {
|
|||
|
||||
@Service
|
||||
class AccountServiceImpl(
|
||||
private val actorQueryService: ActorQueryService,
|
||||
private val applicationConfig: ApplicationConfig
|
||||
private val accountQueryService: AccountQueryService
|
||||
) : AccountService {
|
||||
override suspend fun findById(id: Long): Account {
|
||||
val findById = actorQueryService.findById(id)
|
||||
return toAccount(findById)
|
||||
return accountQueryService.findById(id)
|
||||
}
|
||||
|
||||
private fun toAccount(findById: Actor): Account {
|
||||
val userUrl = applicationConfig.url.toString() + "/users/" + findById.id.toString()
|
||||
|
||||
return Account(
|
||||
id = findById.id.toString(),
|
||||
username = findById.name,
|
||||
acct = "${findById.name}@${findById.domain}",
|
||||
url = findById.url,
|
||||
displayName = findById.screenName,
|
||||
note = findById.description,
|
||||
avatar = "$userUrl/icon.jpg",
|
||||
avatarStatic = "$userUrl/icon.jpg",
|
||||
header = "$userUrl/header.jpg",
|
||||
headerStatic = "$userUrl/header.jpg",
|
||||
locked = findById.locked,
|
||||
fields = emptyList(),
|
||||
emojis = emptyList(),
|
||||
bot = false,
|
||||
group = false,
|
||||
discoverable = false,
|
||||
createdAt = findById.createdAt.toString(),
|
||||
lastStatusAt = findById.createdAt.toString(),
|
||||
statusesCount = 0,
|
||||
followersCount = 0,
|
||||
)
|
||||
override suspend fun findByIds(ids: List<Long>): List<Account> {
|
||||
return accountQueryService.findByIds(ids)
|
||||
}
|
||||
|
||||
override suspend fun findByIds(ids: List<Long>): List<Account> =
|
||||
actorQueryService.findByIds(ids).map { toAccount(it) }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue