mirror of https://github.com/usbharu/Hideout.git
wip
This commit is contained in:
parent
922bdb4991
commit
ccd089fa8e
|
@ -17,22 +17,21 @@
|
|||
package dev.usbharu.hideout.core.application.actor
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor2Repository
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class DeleteLocalActorApplicationService(
|
||||
private val transaction: Transaction,
|
||||
private val actor2Repository: Actor2Repository,
|
||||
private val actorRepository: ActorRepository,
|
||||
) {
|
||||
suspend fun delete(actorId: Long, executor: ActorId) {
|
||||
transaction.transaction {
|
||||
val id = ActorId(actorId)
|
||||
val findById = actor2Repository.findById(id)!!
|
||||
val findById = actorRepository.findById(id)!!
|
||||
findById.delete()
|
||||
actor2Repository.delete(findById)
|
||||
actorRepository.delete(findById)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
package dev.usbharu.hideout.core.application.actor
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor2Repository
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||
import dev.usbharu.hideout.core.domain.service.actor.local.AccountMigrationCheck.*
|
||||
import dev.usbharu.hideout.core.domain.service.actor.local.LocalActorMigrationCheckDomainService
|
||||
import org.springframework.stereotype.Service
|
||||
|
@ -26,24 +26,23 @@ import org.springframework.stereotype.Service
|
|||
@Service
|
||||
class MigrationLocalActorApplicationService(
|
||||
private val transaction: Transaction,
|
||||
private val actor2Repository: Actor2Repository,
|
||||
private val actorRepository: ActorRepository,
|
||||
private val localActorMigrationCheckDomainService: LocalActorMigrationCheckDomainService,
|
||||
) {
|
||||
suspend fun migration(from: Long, to: Long, executor: ActorId) {
|
||||
transaction.transaction<Unit> {
|
||||
|
||||
val fromActorId = ActorId(from)
|
||||
val toActorId = ActorId(to)
|
||||
|
||||
val fromActor = actor2Repository.findById(fromActorId)!!
|
||||
val toActor = actor2Repository.findById(toActorId)!!
|
||||
val fromActor = actorRepository.findById(fromActorId)!!
|
||||
val toActor = actorRepository.findById(toActorId)!!
|
||||
|
||||
val canAccountMigration = localActorMigrationCheckDomainService.canAccountMigration(fromActor, toActor)
|
||||
when (canAccountMigration) {
|
||||
is AlreadyMoved -> TODO()
|
||||
is CanAccountMigration -> {
|
||||
fromActor.moveTo = toActorId
|
||||
actor2Repository.save(fromActor)
|
||||
actorRepository.save(fromActor)
|
||||
}
|
||||
|
||||
is CircularReferences -> TODO()
|
||||
|
@ -51,6 +50,5 @@ class MigrationLocalActorApplicationService(
|
|||
is AlsoKnownAsNotFound -> TODO()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,22 +19,22 @@ package dev.usbharu.hideout.core.application.actor
|
|||
import dev.usbharu.hideout.application.config.ApplicationConfig
|
||||
import dev.usbharu.hideout.application.service.id.IdGenerateService
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor2Repository
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||
import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
|
||||
import dev.usbharu.hideout.core.domain.service.actor.local.LocalActorDomainService
|
||||
import dev.usbharu.hideout.core.domain.service.userdetail.UserDetailDomainService
|
||||
import dev.usbharu.hideout.core.infrastructure.factory.Actor2FactoryImpl
|
||||
import dev.usbharu.hideout.core.infrastructure.factory.ActorFactoryImpl
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class RegisterLocalActorApplicationService(
|
||||
private val transaction: Transaction,
|
||||
private val actorDomainService: LocalActorDomainService,
|
||||
private val actor2Repository: Actor2Repository,
|
||||
private val actor2FactoryImpl: Actor2FactoryImpl,
|
||||
private val actorRepository: ActorRepository,
|
||||
private val actorFactoryImpl: ActorFactoryImpl,
|
||||
private val instanceRepository: InstanceRepository,
|
||||
private val applicationConfig: ApplicationConfig,
|
||||
private val userDetailDomainService: UserDetailDomainService,
|
||||
|
@ -44,26 +44,23 @@ class RegisterLocalActorApplicationService(
|
|||
suspend fun register(registerLocalActor: RegisterLocalActor) {
|
||||
transaction.transaction {
|
||||
if (actorDomainService.usernameAlreadyUse(registerLocalActor.name)) {
|
||||
//todo 適切な例外を考える
|
||||
// todo 適切な例外を考える
|
||||
throw Exception("Username already exists")
|
||||
}
|
||||
val instance = instanceRepository.findByUrl(applicationConfig.url.toURI())!!
|
||||
|
||||
|
||||
val actor = actor2FactoryImpl.createLocal(
|
||||
val actor = actorFactoryImpl.createLocal(
|
||||
registerLocalActor.name,
|
||||
actorDomainService.generateKeyPair(),
|
||||
instance.id
|
||||
)
|
||||
actor2Repository.save(actor)
|
||||
actorRepository.save(actor)
|
||||
val userDetail = UserDetail.create(
|
||||
id = UserDetailId(idGenerateService.generateId()),
|
||||
actorId = actor.id,
|
||||
password = userDetailDomainService.hashPassword(registerLocalActor.password),
|
||||
)
|
||||
userDetailRepository.save(userDetail)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,4 +5,4 @@ import org.springframework.stereotype.Service
|
|||
@Service
|
||||
interface SetAlsoKnownAsLocalActorApplicationService {
|
||||
suspend fun setAlsoKnownAs(actorId: Long, alsoKnownAs: List<Long>)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,24 +17,21 @@
|
|||
package dev.usbharu.hideout.core.application.actor
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor2Repository
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class SuspendLocalActorApplicationService(
|
||||
private val transaction: Transaction,
|
||||
private val actor2Repository: Actor2Repository,
|
||||
private val actorRepository: ActorRepository,
|
||||
) {
|
||||
suspend fun suspend(actorId: Long, executor: ActorId) {
|
||||
transaction.transaction {
|
||||
|
||||
val id = ActorId(actorId)
|
||||
|
||||
val findById = actor2Repository.findById(id)!!
|
||||
val findById = actorRepository.findById(id)!!
|
||||
findById.suspend = true
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,21 +17,20 @@
|
|||
package dev.usbharu.hideout.core.application.actor
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor2Repository
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class UnsuspendLocalActorApplicationService(
|
||||
private val transaction: Transaction,
|
||||
private val actor2Repository: Actor2Repository,
|
||||
private val actorRepository: ActorRepository,
|
||||
) {
|
||||
suspend fun unsuspend(actorId: Long, executor: Long) {
|
||||
transaction.transaction {
|
||||
val findById = actor2Repository.findById(ActorId(actorId))!!
|
||||
val findById = actorRepository.findById(ActorId(actorId))!!
|
||||
|
||||
findById.suspend = false
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,15 +16,15 @@
|
|||
|
||||
package dev.usbharu.hideout.core.application.post
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.post.Post2Repository
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostId
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostRepository
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class DeleteLocalPostApplicationService(private val postRepository: Post2Repository) {
|
||||
class DeleteLocalPostApplicationService(private val postRepository: PostRepository) {
|
||||
suspend fun delete(postId: Long) {
|
||||
val findById = postRepository.findById(PostId(postId))!!
|
||||
findById.delete()
|
||||
postRepository.save(findById)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,27 +16,26 @@
|
|||
|
||||
package dev.usbharu.hideout.core.application.post
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor2Repository
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||
import dev.usbharu.hideout.core.domain.model.media.MediaId
|
||||
import dev.usbharu.hideout.core.domain.model.post.Post2Repository
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostId
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostOverview
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostRepository
|
||||
import dev.usbharu.hideout.core.infrastructure.factory.PostFactoryImpl
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class RegisterLocalPostApplicationService(
|
||||
private val postFactory: PostFactoryImpl,
|
||||
private val actor2Repository: Actor2Repository,
|
||||
private val postRepository: Post2Repository,
|
||||
private val actorRepository: ActorRepository,
|
||||
private val postRepository: PostRepository,
|
||||
) {
|
||||
suspend fun register(registerLocalPost: RegisterLocalPost) {
|
||||
|
||||
val actorId = ActorId(registerLocalPost.actorId)
|
||||
val post = postFactory.createLocal(
|
||||
actorId,
|
||||
actor2Repository.findById(actorId)!!.name,
|
||||
actorRepository.findById(actorId)!!.name,
|
||||
PostOverview(registerLocalPost.overview),
|
||||
registerLocalPost.content,
|
||||
registerLocalPost.visibility,
|
||||
|
@ -48,4 +47,4 @@ class RegisterLocalPostApplicationService(
|
|||
|
||||
postRepository.save(post)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,16 +18,16 @@ package dev.usbharu.hideout.core.application.post
|
|||
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.domain.model.media.MediaId
|
||||
import dev.usbharu.hideout.core.domain.model.post.Post2Repository
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostId
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostOverview
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostRepository
|
||||
import dev.usbharu.hideout.core.infrastructure.factory.PostContentFactoryImpl
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class UpdateLocalNoteApplicationService(
|
||||
private val transaction: Transaction,
|
||||
private val postRepository: Post2Repository,
|
||||
private val postRepository: PostRepository,
|
||||
private val postContentFactoryImpl: PostContentFactoryImpl,
|
||||
) {
|
||||
suspend fun update(updateLocalNote: UpdateLocalNote) {
|
||||
|
@ -42,4 +42,4 @@ class UpdateLocalNoteApplicationService(
|
|||
postRepository.save(post)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
|
||||
package dev.usbharu.hideout.core.domain.event.actor
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor2
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody
|
||||
|
||||
class ActorDomainEventFactory(private val actor: Actor2) {
|
||||
class ActorDomainEventFactory(private val actor: Actor) {
|
||||
fun createEvent(actorEvent: ActorEvent): DomainEvent {
|
||||
return DomainEvent.create(
|
||||
actorEvent.eventName,
|
||||
|
@ -30,7 +30,7 @@ class ActorDomainEventFactory(private val actor: Actor2) {
|
|||
}
|
||||
}
|
||||
|
||||
class ActorEventBody(actor: Actor2) : DomainEventBody(
|
||||
class ActorEventBody(actor: Actor) : DomainEventBody(
|
||||
mapOf(
|
||||
"actor" to actor
|
||||
)
|
||||
|
@ -43,4 +43,4 @@ enum class ActorEvent(val eventName: String, val collectable: Boolean = true) {
|
|||
move("ActorMove"),
|
||||
actorSuspend("ActorSuspend"),
|
||||
actorUnsuspend("ActorUnsuspend"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,4 +44,4 @@ enum class ActorInstanceRelationshipEvent(val eventName: String) {
|
|||
block("ActorInstanceBlock"),
|
||||
mute("ActorInstanceMute"),
|
||||
unmute("ActorInstanceUnmute"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,4 +33,4 @@ class InstanceEventBody(instance: Instance) : DomainEventBody(mapOf("instance" t
|
|||
|
||||
enum class InstanceEvent(val eventName: String) {
|
||||
update("InstanceUpdate")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
|
||||
package dev.usbharu.hideout.core.domain.event.post
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.post.Post2
|
||||
import dev.usbharu.hideout.core.domain.model.post.Post
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody
|
||||
|
||||
class PostDomainEventFactory(private val post: Post2) {
|
||||
class PostDomainEventFactory(private val post: Post) {
|
||||
fun createEvent(postEvent: PostEvent): DomainEvent {
|
||||
return DomainEvent.create(
|
||||
postEvent.eventName,
|
||||
|
@ -29,11 +29,11 @@ class PostDomainEventFactory(private val post: Post2) {
|
|||
}
|
||||
}
|
||||
|
||||
class PostEventBody(post: Post2) : DomainEventBody(mapOf("post" to post))
|
||||
class PostEventBody(post: Post) : DomainEventBody(mapOf("post" to post))
|
||||
|
||||
enum class PostEvent(val eventName: String) {
|
||||
delete("PostDelete"),
|
||||
update("PostUpdate"),
|
||||
create("PostCreate"),
|
||||
checkUpdate("PostCheckUpdate"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,17 +16,17 @@
|
|||
|
||||
package dev.usbharu.hideout.core.domain.event.relationship
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.relationship.Relationship2
|
||||
import dev.usbharu.hideout.core.domain.model.relationship.Relationship
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody
|
||||
|
||||
class RelationshipEventFactory(private val relationship2: Relationship2) {
|
||||
class RelationshipEventFactory(private val relationship: Relationship) {
|
||||
fun createEvent(relationshipEvent: RelationshipEvent): DomainEvent {
|
||||
return DomainEvent.create(relationshipEvent.eventName, RelationshipEventBody(relationship2))
|
||||
return DomainEvent.create(relationshipEvent.eventName, RelationshipEventBody(relationship))
|
||||
}
|
||||
}
|
||||
|
||||
class RelationshipEventBody(relationship: Relationship2) : DomainEventBody(mapOf("relationship" to relationship))
|
||||
class RelationshipEventBody(relationship: Relationship) : DomainEventBody(mapOf("relationship" to relationship))
|
||||
|
||||
enum class RelationshipEvent(val eventName: String) {
|
||||
follow("RelationshipFollow"),
|
||||
|
@ -37,4 +37,4 @@ enum class RelationshipEvent(val eventName: String) {
|
|||
unmute("RelationshipUnmute"),
|
||||
followRequest("RelationshipFollowRequest"),
|
||||
unfollowRequest("RelationshipUnfollowRequest"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,13 +18,14 @@ package dev.usbharu.hideout.core.domain.model.actor
|
|||
|
||||
import dev.usbharu.hideout.core.domain.event.actor.ActorDomainEventFactory
|
||||
import dev.usbharu.hideout.core.domain.event.actor.ActorEvent.*
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.EmojiId
|
||||
import dev.usbharu.hideout.core.domain.model.instance.InstanceId
|
||||
import dev.usbharu.hideout.core.domain.model.shared.Domain
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventStorable
|
||||
import java.net.URI
|
||||
import java.time.Instant
|
||||
|
||||
class Actor2 private constructor(
|
||||
class Actor(
|
||||
val id: ActorId,
|
||||
val name: ActorName,
|
||||
val domain: Domain,
|
||||
|
@ -49,6 +50,8 @@ class Actor2 private constructor(
|
|||
var lastUpdateAt: Instant = createdAt,
|
||||
alsoKnownAs: Set<ActorId> = emptySet(),
|
||||
moveTo: ActorId? = null,
|
||||
emojiIds: Set<EmojiId>,
|
||||
deleted: Boolean,
|
||||
) : DomainEventStorable() {
|
||||
|
||||
var suspend = suspend
|
||||
|
@ -74,9 +77,8 @@ class Actor2 private constructor(
|
|||
field = value
|
||||
}
|
||||
|
||||
|
||||
val emojis
|
||||
get() = screenName.emojis + description.emojis
|
||||
var emojis = emojiIds
|
||||
private set
|
||||
|
||||
var description = description
|
||||
set(value) {
|
||||
|
@ -89,62 +91,28 @@ class Actor2 private constructor(
|
|||
field = value
|
||||
}
|
||||
|
||||
var deleted = deleted
|
||||
private set
|
||||
|
||||
fun delete() {
|
||||
addDomainEvent(ActorDomainEventFactory(this).createEvent(delete))
|
||||
if (deleted.not()) {
|
||||
addDomainEvent(ActorDomainEventFactory(this).createEvent(delete))
|
||||
screenName = ActorScreenName.empty
|
||||
description = ActorDescription.empty
|
||||
emojis = emptySet()
|
||||
lastPostAt = null
|
||||
postsCount = ActorPostsCount.ZERO
|
||||
followersCount = null
|
||||
followingCount = null
|
||||
}
|
||||
}
|
||||
|
||||
fun restore() {
|
||||
deleted = false
|
||||
checkUpdate()
|
||||
}
|
||||
|
||||
fun checkUpdate() {
|
||||
addDomainEvent(ActorDomainEventFactory(this).createEvent(checkUpdate))
|
||||
}
|
||||
|
||||
abstract class Actor2Factory {
|
||||
protected suspend fun internalCreate(
|
||||
id: ActorId,
|
||||
name: ActorName,
|
||||
domain: Domain,
|
||||
screenName: ActorScreenName,
|
||||
description: ActorDescription,
|
||||
inbox: URI,
|
||||
outbox: URI,
|
||||
url: URI,
|
||||
publicKey: ActorPublicKey,
|
||||
privateKey: ActorPrivateKey? = null,
|
||||
createdAt: Instant,
|
||||
keyId: ActorKeyId,
|
||||
followersEndpoint: URI,
|
||||
followingEndpoint: URI,
|
||||
instance: InstanceId,
|
||||
locked: Boolean,
|
||||
followersCount: ActorRelationshipCount,
|
||||
followingCount: ActorRelationshipCount,
|
||||
postsCount: ActorPostsCount,
|
||||
lastPostDate: Instant? = null,
|
||||
suspend: Boolean,
|
||||
): Actor2 {
|
||||
return Actor2(
|
||||
id = id,
|
||||
name = name,
|
||||
domain = domain,
|
||||
screenName = screenName,
|
||||
description = description,
|
||||
inbox = inbox,
|
||||
outbox = outbox,
|
||||
url = url,
|
||||
publicKey = publicKey,
|
||||
privateKey = privateKey,
|
||||
createdAt = createdAt,
|
||||
keyId = keyId,
|
||||
followersEndpoint = followersEndpoint,
|
||||
followingEndpoint = followingEndpoint,
|
||||
instance = instance,
|
||||
locked = locked,
|
||||
followersCount = followersCount,
|
||||
followingCount = followingCount,
|
||||
postsCount = postsCount,
|
||||
lastPostAt = lastPostDate,
|
||||
suspend = suspend
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,15 +16,10 @@
|
|||
|
||||
package dev.usbharu.hideout.core.domain.model.actor
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.EmojiId
|
||||
|
||||
|
||||
class ActorDescription private constructor(val description: String, val emojis: List<EmojiId>) {
|
||||
@JvmInline
|
||||
value class ActorDescription(val description: String) {
|
||||
companion object {
|
||||
val length = 10000
|
||||
val empty = ActorDescription("")
|
||||
}
|
||||
abstract class ActorDescriptionFactory {
|
||||
protected suspend fun create(description: String, emojis: List<EmojiId>): ActorDescription =
|
||||
ActorDescription(description, emojis)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,4 +24,4 @@ value class ActorId(val id: Long) {
|
|||
companion object {
|
||||
val ghost = ActorId(0L)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,4 +17,4 @@
|
|||
package dev.usbharu.hideout.core.domain.model.actor
|
||||
|
||||
@JvmInline
|
||||
value class ActorKeyId(val keyId: String)
|
||||
value class ActorKeyId(val keyId: String)
|
||||
|
|
|
@ -18,11 +18,8 @@ package dev.usbharu.hideout.core.domain.model.actor
|
|||
|
||||
@JvmInline
|
||||
value class ActorName(val name: String) {
|
||||
init {
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
val length = 300
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,4 +24,8 @@ value class ActorPostsCount(val postsCount: Int) {
|
|||
|
||||
operator fun inc() = ActorPostsCount(postsCount + 1)
|
||||
operator fun dec() = ActorPostsCount(postsCount - 1)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ZERO = ActorPostsCount(0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,4 +17,4 @@
|
|||
package dev.usbharu.hideout.core.domain.model.actor
|
||||
|
||||
@JvmInline
|
||||
value class ActorPrivateKey(val privateKey: String)
|
||||
value class ActorPrivateKey(val privateKey: String)
|
||||
|
|
|
@ -17,4 +17,4 @@
|
|||
package dev.usbharu.hideout.core.domain.model.actor
|
||||
|
||||
@JvmInline
|
||||
value class ActorPublicKey(val publicKey: String)
|
||||
value class ActorPublicKey(val publicKey: String)
|
||||
|
|
|
@ -24,4 +24,4 @@ value class ActorRelationshipCount(val relationshipCount: Int) {
|
|||
|
||||
operator fun inc(): ActorRelationshipCount = ActorRelationshipCount(relationshipCount + 1)
|
||||
operator fun dec(): ActorRelationshipCount = ActorRelationshipCount(relationshipCount - 1)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
package dev.usbharu.hideout.core.domain.model.actor
|
||||
|
||||
interface Actor2Repository {
|
||||
suspend fun save(actor: Actor2): Actor2
|
||||
suspend fun delete(actor: Actor2)
|
||||
suspend fun findById(id: ActorId): Actor2?
|
||||
}
|
||||
interface ActorRepository {
|
||||
suspend fun save(actor: Actor): Actor
|
||||
suspend fun delete(actor: Actor)
|
||||
suspend fun findById(id: ActorId): Actor?
|
||||
}
|
|
@ -16,16 +16,10 @@
|
|||
|
||||
package dev.usbharu.hideout.core.domain.model.actor
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.EmojiId
|
||||
|
||||
|
||||
class ActorScreenName private constructor(val screenName: String, val emojis: List<EmojiId>) {
|
||||
@JvmInline
|
||||
value class ActorScreenName(val screenName: String) {
|
||||
companion object {
|
||||
val length = 300
|
||||
}
|
||||
|
||||
abstract class ActorScreenNameFactory {
|
||||
protected suspend fun create(screenName: String, emojis: List<EmojiId>): ActorScreenName =
|
||||
ActorScreenName(screenName, emojis)
|
||||
val empty = ActorScreenName("")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,4 +85,4 @@ data class ActorInstanceRelationship(
|
|||
result = 31 * result + instanceId.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,4 +19,4 @@ package dev.usbharu.hideout.core.domain.model.actorinstancerelationship
|
|||
interface ActorInstanceRelationshipRepository {
|
||||
suspend fun save(actorInstanceRelationship: ActorInstanceRelationship): ActorInstanceRelationship
|
||||
suspend fun delete(actorInstanceRelationship: ActorInstanceRelationship)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.domain.model.deletedActor
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorName
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorPublicKey
|
||||
import dev.usbharu.hideout.core.domain.model.shared.Domain
|
||||
import java.net.URI
|
||||
import java.time.Instant
|
||||
|
||||
data class DeletedActor(
|
||||
val id: DeletedActorId,
|
||||
val name: ActorName,
|
||||
val domain: Domain,
|
||||
val apId: URI,
|
||||
val publicKey: ActorPublicKey,
|
||||
val deletedAt: Instant,
|
||||
)
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.domain.model.deletedActor
|
||||
|
||||
@JvmInline
|
||||
value class DeletedActorId(val id: Long)
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.domain.model.deletedActor
|
||||
|
||||
interface DeletedActorRepository {
|
||||
suspend fun save(deletedActor: DeletedActor): DeletedActor
|
||||
suspend fun delete(deletedActor: DeletedActor)
|
||||
suspend fun findById(id: DeletedActorId): DeletedActor?
|
||||
suspend fun findByNameAndDomain(name: String, domain: String): DeletedActor?
|
||||
}
|
|
@ -17,10 +17,8 @@
|
|||
package dev.usbharu.hideout.core.domain.model.emoji
|
||||
|
||||
interface CustomEmojiRepository {
|
||||
suspend fun generateId(): Long
|
||||
suspend fun save(customEmoji: CustomEmoji): CustomEmoji
|
||||
suspend fun findById(id: Long): CustomEmoji?
|
||||
suspend fun delete(customEmoji: CustomEmoji)
|
||||
suspend fun findByNameAndDomain(name: String, domain: String): CustomEmoji?
|
||||
suspend fun findByNamesAndDomain(names: List<String>, domain: String): List<CustomEmoji>
|
||||
}
|
||||
|
|
|
@ -17,4 +17,4 @@
|
|||
package dev.usbharu.hideout.core.domain.model.emoji
|
||||
|
||||
@JvmInline
|
||||
value class EmojiId(val emojiId: Long)
|
||||
value class EmojiId(val emojiId: Long)
|
||||
|
|
|
@ -37,7 +37,6 @@ class Instance(
|
|||
val createdAt: Instant,
|
||||
) : DomainEventStorable() {
|
||||
|
||||
|
||||
var iconUrl = iconUrl
|
||||
set(value) {
|
||||
addDomainEvent(InstanceEventFactory(this).createEvent(InstanceEvent.update))
|
||||
|
@ -56,6 +55,4 @@ class Instance(
|
|||
override fun hashCode(): Int {
|
||||
return id.hashCode()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -17,4 +17,4 @@
|
|||
package dev.usbharu.hideout.core.domain.model.instance
|
||||
|
||||
@JvmInline
|
||||
value class InstanceId(val instanceId: Long)
|
||||
value class InstanceId(val instanceId: Long)
|
||||
|
|
|
@ -19,7 +19,6 @@ package dev.usbharu.hideout.core.domain.model.instance
|
|||
import java.net.URI
|
||||
|
||||
interface InstanceRepository {
|
||||
suspend fun generateId(): InstanceId
|
||||
suspend fun save(instance: Instance): Instance
|
||||
suspend fun findById(id: InstanceId): Instance?
|
||||
suspend fun delete(instance: Instance)
|
||||
|
|
|
@ -29,4 +29,3 @@ data class Media(
|
|||
val blurHash: MediaBlurHash?,
|
||||
val description: MediaDescription? = null,
|
||||
)
|
||||
|
||||
|
|
|
@ -17,4 +17,4 @@
|
|||
package dev.usbharu.hideout.core.domain.model.media
|
||||
|
||||
@JvmInline
|
||||
value class MediaBlurHash(val hash: String)
|
||||
value class MediaBlurHash(val hash: String)
|
||||
|
|
|
@ -17,9 +17,7 @@
|
|||
package dev.usbharu.hideout.core.domain.model.media
|
||||
|
||||
interface MediaRepository {
|
||||
suspend fun generateId(): Long
|
||||
suspend fun save(media: Media): Media
|
||||
suspend fun findById(id: Long): Media?
|
||||
suspend fun delete(id: Long)
|
||||
suspend fun findByRemoteUrl(remoteUrl: String): Media?
|
||||
suspend fun findById(id: MediaId): Media?
|
||||
suspend fun delete(media: Media)
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventStorable
|
|||
import java.net.URI
|
||||
import java.time.Instant
|
||||
|
||||
class Post2 private constructor(
|
||||
class Post private constructor(
|
||||
val id: PostId,
|
||||
actorId: ActorId,
|
||||
overview: PostOverview? = null,
|
||||
|
@ -143,7 +143,6 @@ class Post2 private constructor(
|
|||
content = PostContent.empty
|
||||
overview = null
|
||||
mediaIds = emptyList()
|
||||
|
||||
}
|
||||
deleted = true
|
||||
}
|
||||
|
@ -157,6 +156,7 @@ class Post2 private constructor(
|
|||
this.content = content
|
||||
this.overview = overview
|
||||
this.mediaIds = mediaIds
|
||||
checkUpdate()
|
||||
}
|
||||
|
||||
var hide = hide
|
||||
|
@ -182,7 +182,7 @@ class Post2 private constructor(
|
|||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as Post2
|
||||
other as Post
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
|
@ -207,8 +207,8 @@ class Post2 private constructor(
|
|||
deleted: Boolean,
|
||||
mediaIds: List<MediaId>,
|
||||
hide: Boolean,
|
||||
): Post2 {
|
||||
return Post2(
|
||||
): Post {
|
||||
return Post(
|
||||
id = id,
|
||||
actorId = actorId,
|
||||
overview = overview,
|
||||
|
@ -226,4 +226,4 @@ class Post2 private constructor(
|
|||
).apply { addDomainEvent(PostDomainEventFactory(this).createEvent(PostEvent.create)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,7 +29,9 @@ class PostContent private constructor(val text: String, val content: String, val
|
|||
abstract class PostContentFactory {
|
||||
protected suspend fun create(text: String, content: String, emojiIds: List<EmojiId>): PostContent {
|
||||
return PostContent(
|
||||
text, content, emojiIds
|
||||
text,
|
||||
content,
|
||||
emojiIds
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,10 @@ package dev.usbharu.hideout.core.domain.model.post
|
|||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
|
||||
interface Post2Repository {
|
||||
suspend fun save(post: Post2): Post2
|
||||
suspend fun saveAll(posts: List<Post2>): List<Post2>
|
||||
suspend fun findById(id: PostId): Post2?
|
||||
suspend fun findByActorId(id: ActorId): List<Post2>
|
||||
suspend fun delete(post: Post2)
|
||||
}
|
||||
interface PostRepository {
|
||||
suspend fun save(post: Post): Post
|
||||
suspend fun saveAll(posts: List<Post>): List<Post>
|
||||
suspend fun findById(id: PostId): Post?
|
||||
suspend fun findByActorId(id: ActorId): List<Post>
|
||||
suspend fun delete(post: Post)
|
||||
}
|
|
@ -21,7 +21,7 @@ import dev.usbharu.hideout.core.domain.event.relationship.RelationshipEventFacto
|
|||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventStorable
|
||||
|
||||
class Relationship2(
|
||||
class Relationship(
|
||||
val actorId: ActorId,
|
||||
val targetActorId: ActorId,
|
||||
following: Boolean,
|
||||
|
@ -43,7 +43,6 @@ class Relationship2(
|
|||
var mutingFollowRequest: Boolean = mutingFollowRequest
|
||||
private set
|
||||
|
||||
|
||||
fun follow() {
|
||||
require(blocking.not())
|
||||
following = true
|
||||
|
@ -103,4 +102,4 @@ class Relationship2(
|
|||
fun rejectFollowRequest() {
|
||||
followRequesting = false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
package dev.usbharu.hideout.core.domain.model.relationship
|
||||
|
||||
interface Relationship2Repository {
|
||||
suspend fun save(relationship2: Relationship2): Relationship2
|
||||
suspend fun delete(relationship2: Relationship2)
|
||||
}
|
||||
interface RelationshipRepository {
|
||||
suspend fun save(relationship: Relationship): Relationship
|
||||
suspend fun delete(relationship: Relationship)
|
||||
}
|
|
@ -21,4 +21,4 @@ value class Domain(val domain: String) {
|
|||
companion object {
|
||||
val length = 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,14 +17,14 @@
|
|||
package dev.usbharu.hideout.core.domain.service.actor
|
||||
|
||||
import dev.usbharu.hideout.application.config.ApplicationConfig
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor2
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
interface IRemoteActorCheckDomainService {
|
||||
fun isRemoteActor(actor: Actor2): Boolean
|
||||
fun isRemoteActor(actor: Actor): Boolean
|
||||
}
|
||||
|
||||
@Service
|
||||
class RemoteActorCheckDomainService(private val applicationConfig: ApplicationConfig) : IRemoteActorCheckDomainService {
|
||||
override fun isRemoteActor(actor: Actor2): Boolean = actor.domain.domain == applicationConfig.url.host
|
||||
override fun isRemoteActor(actor: Actor): Boolean = actor.domain.domain == applicationConfig.url.host
|
||||
}
|
||||
|
|
|
@ -22,4 +22,4 @@ import dev.usbharu.hideout.core.domain.model.actor.ActorPublicKey
|
|||
interface LocalActorDomainService {
|
||||
suspend fun usernameAlreadyUse(name: String): Boolean
|
||||
suspend fun generateKeyPair(): Pair<ActorPublicKey, ActorPrivateKey>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
|
||||
package dev.usbharu.hideout.core.domain.service.actor.local
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor2
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor
|
||||
|
||||
interface LocalActorMigrationCheckDomainService {
|
||||
suspend fun canAccountMigration(from: Actor2, to: Actor2): AccountMigrationCheck
|
||||
suspend fun canAccountMigration(from: Actor, to: Actor): AccountMigrationCheck
|
||||
}
|
||||
|
||||
sealed class AccountMigrationCheck(
|
||||
|
@ -34,4 +34,4 @@ sealed class AccountMigrationCheck(
|
|||
class AlreadyMoved(val message: String) : AccountMigrationCheck(false)
|
||||
|
||||
class AlsoKnownAsNotFound(val message: String) : AccountMigrationCheck(false)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,4 +18,4 @@ package dev.usbharu.hideout.core.domain.service.actorinstancerelationship
|
|||
|
||||
interface ActorInstanceRelationshipDomainService {
|
||||
suspend fun block()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,4 +18,4 @@ package dev.usbharu.hideout.core.domain.service.userdetail
|
|||
|
||||
interface PasswordEncoder {
|
||||
suspend fun encode(input: String): String
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,4 +22,4 @@ import org.springframework.stereotype.Service
|
|||
@Service
|
||||
class UserDetailDomainService(private val passwordEncoder: PasswordEncoder) {
|
||||
suspend fun hashPassword(password: String) = UserDetailHashedPassword(passwordEncoder.encode(password))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,4 +50,4 @@ data class DomainEvent(
|
|||
return DomainEvent(id, name, occurredOn, body, collectable)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,4 +20,4 @@ abstract class DomainEventBody(val map: Map<String, Any>) {
|
|||
fun toMap(): Map<String, Any> {
|
||||
return map
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,4 +2,4 @@ package dev.usbharu.hideout.core.domain.shared.domainevent
|
|||
|
||||
interface DomainEventPublisher {
|
||||
suspend fun publishEvent(domainEvent: DomainEvent)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,4 +26,4 @@ abstract class DomainEventStorable {
|
|||
fun clearDomainEvents() = domainEvents.clear()
|
||||
|
||||
fun getDomainEvents(): List<DomainEvent> = domainEvents.toList()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,4 +4,4 @@ interface DomainEventSubscriber {
|
|||
fun subscribe(eventName: String, domainEventConsumer: DomainEventConsumer)
|
||||
}
|
||||
|
||||
typealias DomainEventConsumer = (DomainEvent) -> Unit
|
||||
typealias DomainEventConsumer = (DomainEvent) -> Unit
|
||||
|
|
|
@ -19,4 +19,4 @@ interface DomainEventPublishableRepository<T : DomainEventStorable> {
|
|||
}
|
||||
entity.clearDomainEvents()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.infrastructure.exposed
|
||||
|
||||
import dev.usbharu.hideout.application.infrastructure.exposed.QueryMapper
|
||||
import dev.usbharu.hideout.application.infrastructure.exposed.ResultRowMapper
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Actors
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.ActorsAlsoKnownAs
|
||||
import org.jetbrains.exposed.sql.Query
|
||||
import org.jetbrains.exposed.sql.ResultRow
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class ActorQueryMapper(private val actorResultRowMapper: ResultRowMapper<Actor>) : QueryMapper<Actor> {
|
||||
override fun map(query: Query): List<Actor> {
|
||||
return query
|
||||
.groupBy { it[Actors.id] }
|
||||
.map { it.value }
|
||||
.map {
|
||||
it
|
||||
.first()
|
||||
.let(actorResultRowMapper::map)
|
||||
.apply {
|
||||
alsoKnownAs = it.mapNotNull { resultRow: ResultRow ->
|
||||
resultRow.getOrNull(
|
||||
ActorsAlsoKnownAs.alsoKnownAs
|
||||
)?.let { actorId ->
|
||||
ActorId(
|
||||
actorId
|
||||
)
|
||||
}
|
||||
}.toSet()
|
||||
clearDomainEvents()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.infrastructure.exposed
|
||||
|
||||
import dev.usbharu.hideout.application.infrastructure.exposed.ResultRowMapper
|
||||
import dev.usbharu.hideout.core.domain.model.actor.*
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.EmojiId
|
||||
import dev.usbharu.hideout.core.domain.model.instance.InstanceId
|
||||
import dev.usbharu.hideout.core.domain.model.shared.Domain
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Actors
|
||||
import org.jetbrains.exposed.sql.ResultRow
|
||||
import org.springframework.stereotype.Component
|
||||
import java.net.URI
|
||||
|
||||
@Component
|
||||
class ActorResultRowMapper : ResultRowMapper<Actor> {
|
||||
override fun map(resultRow: ResultRow): Actor {
|
||||
return Actor(
|
||||
id = ActorId(resultRow[Actors.id]),
|
||||
name = ActorName(resultRow[Actors.name]),
|
||||
domain = Domain(resultRow[Actors.domain]),
|
||||
screenName = ActorScreenName(resultRow[Actors.screenName]),
|
||||
description = ActorDescription(resultRow[Actors.description]),
|
||||
inbox = URI.create(resultRow[Actors.inbox]),
|
||||
outbox = URI.create(resultRow[Actors.outbox]),
|
||||
url = URI.create(resultRow[Actors.url]),
|
||||
publicKey = ActorPublicKey(resultRow[Actors.publicKey]),
|
||||
privateKey = resultRow[Actors.privateKey]?.let { ActorPrivateKey(it) },
|
||||
createdAt = resultRow[Actors.createdAt],
|
||||
keyId = ActorKeyId(resultRow[Actors.keyId]),
|
||||
followersEndpoint = resultRow[Actors.followers]?.let { URI.create(it) },
|
||||
followingEndpoint = resultRow[Actors.following]?.let { URI.create(it) },
|
||||
instance = InstanceId(resultRow[Actors.instance]),
|
||||
locked = resultRow[Actors.locked],
|
||||
followersCount = resultRow[Actors.followersCount]?.let { ActorRelationshipCount(it) },
|
||||
followingCount = resultRow[Actors.followingCount]?.let { ActorRelationshipCount(it) },
|
||||
postsCount = ActorPostsCount(resultRow[Actors.postsCount]),
|
||||
lastPostAt = resultRow[Actors.lastPostAt],
|
||||
suspend = resultRow[Actors.suspend],
|
||||
lastUpdateAt = resultRow[Actors.lastUpdateAt],
|
||||
alsoKnownAs = emptySet(),
|
||||
moveTo = resultRow[Actors.moveTo]?.let { ActorId(it) },
|
||||
emojiIds = resultRow[Actors.emojis]
|
||||
.split(",")
|
||||
.filter { it.isNotEmpty() }
|
||||
.map { EmojiId(it.toLong()) }
|
||||
.toSet(),
|
||||
deleted = resultRow[Actors.deleted]
|
||||
)
|
||||
}
|
||||
}
|
|
@ -16,9 +16,11 @@
|
|||
|
||||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import dev.usbharu.hideout.application.service.id.IdGenerateService
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.CustomEmoji
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiRepository
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.EmojiId
|
||||
import dev.usbharu.hideout.core.domain.model.instance.InstanceId
|
||||
import dev.usbharu.hideout.core.domain.model.shared.Domain
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.jetbrains.exposed.sql.javatime.CurrentTimestamp
|
||||
|
@ -26,34 +28,33 @@ import org.jetbrains.exposed.sql.javatime.timestamp
|
|||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Repository
|
||||
import java.net.URI
|
||||
|
||||
@Repository
|
||||
class CustomEmojiRepositoryImpl(private val idGenerateService: IdGenerateService) : CustomEmojiRepository,
|
||||
class CustomEmojiRepositoryImpl : CustomEmojiRepository,
|
||||
AbstractRepository() {
|
||||
override val logger: Logger
|
||||
get() = Companion.logger
|
||||
|
||||
override suspend fun generateId(): Long = idGenerateService.generateId()
|
||||
|
||||
override suspend fun save(customEmoji: CustomEmoji): CustomEmoji = query {
|
||||
val singleOrNull =
|
||||
CustomEmojis.selectAll().where { CustomEmojis.id eq customEmoji.id }.forUpdate().singleOrNull()
|
||||
CustomEmojis.selectAll().where { CustomEmojis.id eq customEmoji.id.emojiId }.forUpdate().singleOrNull()
|
||||
if (singleOrNull == null) {
|
||||
CustomEmojis.insert {
|
||||
it[id] = customEmoji.id
|
||||
it[id] = customEmoji.id.emojiId
|
||||
it[name] = customEmoji.name
|
||||
it[domain] = customEmoji.domain
|
||||
it[instanceId] = customEmoji.instanceId
|
||||
it[url] = customEmoji.url
|
||||
it[domain] = customEmoji.domain.domain
|
||||
it[instanceId] = customEmoji.instanceId.instanceId
|
||||
it[url] = customEmoji.url.toString()
|
||||
it[category] = customEmoji.category
|
||||
it[createdAt] = customEmoji.createdAt
|
||||
}
|
||||
} else {
|
||||
CustomEmojis.update({ CustomEmojis.id eq customEmoji.id }) {
|
||||
CustomEmojis.update({ CustomEmojis.id eq customEmoji.id.emojiId }) {
|
||||
it[name] = customEmoji.name
|
||||
it[domain] = customEmoji.domain
|
||||
it[instanceId] = customEmoji.instanceId
|
||||
it[url] = customEmoji.url
|
||||
it[domain] = customEmoji.domain.domain
|
||||
it[instanceId] = customEmoji.instanceId.instanceId
|
||||
it[url] = customEmoji.url.toString()
|
||||
it[category] = customEmoji.category
|
||||
it[createdAt] = customEmoji.createdAt
|
||||
}
|
||||
|
@ -66,14 +67,16 @@ class CustomEmojiRepositoryImpl(private val idGenerateService: IdGenerateService
|
|||
}
|
||||
|
||||
override suspend fun delete(customEmoji: CustomEmoji): Unit = query {
|
||||
CustomEmojis.deleteWhere { id eq customEmoji.id }
|
||||
CustomEmojis.deleteWhere { id eq customEmoji.id.emojiId }
|
||||
}
|
||||
|
||||
override suspend fun findByNameAndDomain(name: String, domain: String): CustomEmoji? = query {
|
||||
return@query CustomEmojis
|
||||
.selectAll().where { CustomEmojis.name eq name and (CustomEmojis.domain eq domain) }
|
||||
.singleOrNull()
|
||||
?.toCustomEmoji()
|
||||
override suspend fun findByNamesAndDomain(names: List<String>, domain: String): List<CustomEmoji> {
|
||||
return CustomEmojis
|
||||
.selectAll()
|
||||
.where {
|
||||
CustomEmojis.name inList names and (CustomEmojis.domain eq domain)
|
||||
}
|
||||
.map { it.toCustomEmoji() }
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -82,22 +85,22 @@ class CustomEmojiRepositoryImpl(private val idGenerateService: IdGenerateService
|
|||
}
|
||||
|
||||
fun ResultRow.toCustomEmoji(): CustomEmoji = CustomEmoji(
|
||||
id = this[CustomEmojis.id],
|
||||
id = EmojiId(this[CustomEmojis.id]),
|
||||
name = this[CustomEmojis.name],
|
||||
domain = this[CustomEmojis.domain],
|
||||
instanceId = this[CustomEmojis.instanceId],
|
||||
url = this[CustomEmojis.url],
|
||||
domain = Domain(this[CustomEmojis.domain]),
|
||||
instanceId = InstanceId(this[CustomEmojis.instanceId]),
|
||||
url = URI.create(this[CustomEmojis.url]),
|
||||
category = this[CustomEmojis.category],
|
||||
createdAt = this[CustomEmojis.createdAt]
|
||||
)
|
||||
|
||||
fun ResultRow.toCustomEmojiOrNull(): CustomEmoji? {
|
||||
return CustomEmoji(
|
||||
id = this.getOrNull(CustomEmojis.id) ?: return null,
|
||||
id = EmojiId(this.getOrNull(CustomEmojis.id) ?: return null),
|
||||
name = this.getOrNull(CustomEmojis.name) ?: return null,
|
||||
domain = this.getOrNull(CustomEmojis.domain) ?: return null,
|
||||
instanceId = this[CustomEmojis.instanceId],
|
||||
url = this.getOrNull(CustomEmojis.url) ?: return null,
|
||||
domain = Domain(this.getOrNull(CustomEmojis.domain) ?: return null),
|
||||
instanceId = InstanceId(this.getOrNull(CustomEmojis.instanceId) ?: return null),
|
||||
url = URI.create(this.getOrNull(CustomEmojis.url) ?: return null),
|
||||
category = this[CustomEmojis.category],
|
||||
createdAt = this.getOrNull(CustomEmojis.createdAt) ?: return null
|
||||
)
|
||||
|
@ -107,7 +110,7 @@ object CustomEmojis : Table("emojis") {
|
|||
val id = long("id")
|
||||
val name = varchar("name", 1000)
|
||||
val domain = varchar("domain", 1000)
|
||||
val instanceId = long("instance_id").references(Instance.id).nullable()
|
||||
val instanceId = long("instance_id").references(Instance.id)
|
||||
val url = varchar("url", 255).uniqueIndex()
|
||||
val category = varchar("category", 255).nullable()
|
||||
val createdAt = timestamp("created_at").defaultExpression(CurrentTimestamp)
|
||||
|
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.deletedActor.DeletedActor
|
||||
import dev.usbharu.hideout.core.domain.model.deletedActor.DeletedActorRepository
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.jetbrains.exposed.sql.javatime.timestamp
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
class DeletedActorRepositoryImpl : DeletedActorRepository, AbstractRepository() {
|
||||
override val logger: Logger
|
||||
get() = Companion.logger
|
||||
|
||||
override suspend fun save(deletedActor: DeletedActor): DeletedActor = query {
|
||||
val singleOrNull =
|
||||
DeletedActors.selectAll().where { DeletedActors.id eq deletedActor.id }.forUpdate().singleOrNull()
|
||||
|
||||
if (singleOrNull == null) {
|
||||
DeletedActors.insert {
|
||||
it[id] = deletedActor.id
|
||||
it[name] = deletedActor.name
|
||||
it[domain] = deletedActor.domain
|
||||
it[apId] = deletedActor.apId
|
||||
it[publicKey] = deletedActor.publicKey
|
||||
it[deletedAt] = deletedActor.deletedAt
|
||||
}
|
||||
} else {
|
||||
DeletedActors.update({ DeletedActors.id eq deletedActor.id }) {
|
||||
it[name] = deletedActor.name
|
||||
it[domain] = deletedActor.domain
|
||||
it[apId] = deletedActor.apId
|
||||
it[publicKey] = deletedActor.publicKey
|
||||
it[deletedAt] = deletedActor.deletedAt
|
||||
}
|
||||
}
|
||||
return@query deletedActor
|
||||
}
|
||||
|
||||
override suspend fun delete(deletedActor: DeletedActor): Unit = query {
|
||||
DeletedActors.deleteWhere { id eq deletedActor.id }
|
||||
}
|
||||
|
||||
override suspend fun findById(id: Long): DeletedActor? = query {
|
||||
return@query DeletedActors
|
||||
.selectAll().where { DeletedActors.id eq id }
|
||||
.singleOrNull()
|
||||
?.toDeletedActor()
|
||||
}
|
||||
|
||||
override suspend fun findByNameAndDomain(name: String, domain: String): DeletedActor? = query {
|
||||
return@query DeletedActors
|
||||
.selectAll().where { DeletedActors.name eq name and (DeletedActors.domain eq domain) }
|
||||
.singleOrNull()
|
||||
?.toDeletedActor()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(DeletedActorRepositoryImpl::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
fun ResultRow.toDeletedActor(): DeletedActor = deletedActor(this)
|
||||
|
||||
private fun deletedActor(singleOr: ResultRow): DeletedActor {
|
||||
return DeletedActor(
|
||||
id = singleOr[DeletedActors.id],
|
||||
name = singleOr[DeletedActors.name],
|
||||
domain = singleOr[DeletedActors.domain],
|
||||
apId = singleOr[DeletedActors.publicKey],
|
||||
publicKey = singleOr[DeletedActors.apId],
|
||||
deletedAt = singleOr[DeletedActors.deletedAt]
|
||||
)
|
||||
}
|
||||
|
||||
object DeletedActors : Table("deleted_actors") {
|
||||
val id = long("id")
|
||||
val name = varchar("name", 300)
|
||||
val domain = varchar("domain", 255)
|
||||
val apId = varchar("ap_id", 255).uniqueIndex()
|
||||
val publicKey = varchar("public_key", 10000).uniqueIndex()
|
||||
val deletedAt = timestamp("deleted_at")
|
||||
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||
|
||||
init {
|
||||
uniqueIndex(name, domain)
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import dev.usbharu.hideout.application.infrastructure.exposed.QueryMapper
|
||||
import dev.usbharu.hideout.core.domain.model.actor.*
|
||||
import dev.usbharu.hideout.core.domain.model.shared.Domain
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher
|
||||
|
@ -12,18 +13,22 @@ import org.slf4j.LoggerFactory
|
|||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
class ExposedActor2Repository(override val domainEventPublisher: DomainEventPublisher) : AbstractRepository(),
|
||||
DomainEventPublishableRepository<Actor2>, Actor2Repository {
|
||||
class ExposedActorRepository(
|
||||
private val actorQueryMapper: QueryMapper<Actor>,
|
||||
override val domainEventPublisher: DomainEventPublisher,
|
||||
) : AbstractRepository(),
|
||||
DomainEventPublishableRepository<Actor>,
|
||||
ActorRepository {
|
||||
override val logger: Logger
|
||||
get() = Companion.logger
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(ExposedActor2Repository::class.java)
|
||||
private val logger = LoggerFactory.getLogger(ExposedActorRepository::class.java)
|
||||
}
|
||||
|
||||
override suspend fun save(actor: Actor2): Actor2 {
|
||||
override suspend fun save(actor: Actor): Actor {
|
||||
query {
|
||||
Actors2.upsert {
|
||||
Actors.upsert {
|
||||
it[id] = actor.id.id
|
||||
it[name] = actor.name.name
|
||||
it[domain] = actor.domain.domain
|
||||
|
@ -49,32 +54,41 @@ class ExposedActor2Repository(override val domainEventPublisher: DomainEventPubl
|
|||
it[moveTo] = actor.moveTo?.id
|
||||
it[emojis] = actor.emojis.joinToString(",")
|
||||
}
|
||||
Actors2AlsoKnownAs.deleteWhere {
|
||||
ActorsAlsoKnownAs.deleteWhere {
|
||||
actorId eq actor.id.id
|
||||
}
|
||||
Actors2AlsoKnownAs.batchInsert(actor.alsoKnownAs) {
|
||||
this[Actors2AlsoKnownAs.actorId] = actor.id.id
|
||||
this[Actors2AlsoKnownAs.alsoKnownAs] = it.id
|
||||
ActorsAlsoKnownAs.batchInsert(actor.alsoKnownAs) {
|
||||
this[ActorsAlsoKnownAs.actorId] = actor.id.id
|
||||
this[ActorsAlsoKnownAs.alsoKnownAs] = it.id
|
||||
}
|
||||
}
|
||||
update(actor)
|
||||
return actor
|
||||
}
|
||||
|
||||
override suspend fun delete(actor: Actor2) {
|
||||
override suspend fun delete(actor: Actor) {
|
||||
query {
|
||||
Actors2.deleteWhere { id eq actor.id.id }
|
||||
Actors2AlsoKnownAs.deleteWhere { actorId eq actor.id.id }
|
||||
Actors.deleteWhere { id eq actor.id.id }
|
||||
ActorsAlsoKnownAs.deleteWhere { actorId eq actor.id.id }
|
||||
}
|
||||
update(actor)
|
||||
}
|
||||
|
||||
override suspend fun findById(id: ActorId): Actor2? {
|
||||
TODO()
|
||||
override suspend fun findById(id: ActorId): Actor? {
|
||||
return query {
|
||||
Actors
|
||||
.leftJoin(ActorsAlsoKnownAs, onColumn = { Actors.id }, otherColumn = { actorId })
|
||||
.selectAll()
|
||||
.where {
|
||||
Actors.id eq id.id
|
||||
}
|
||||
.let(actorQueryMapper::map)
|
||||
.first()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object Actors2 : Table("actors") {
|
||||
object Actors : Table("actors") {
|
||||
val id = long("id")
|
||||
val name = varchar("name", ActorName.length)
|
||||
val domain = varchar("domain", Domain.length)
|
||||
|
@ -99,6 +113,7 @@ object Actors2 : Table("actors") {
|
|||
val suspend = bool("suspend")
|
||||
val moveTo = long("move_to").references(id).nullable()
|
||||
val emojis = varchar("emojis", 3000)
|
||||
val deleted = bool("deleted")
|
||||
|
||||
override val primaryKey = PrimaryKey(id)
|
||||
|
||||
|
@ -107,10 +122,10 @@ object Actors2 : Table("actors") {
|
|||
}
|
||||
}
|
||||
|
||||
object Actors2AlsoKnownAs : Table("actor_alsoknwonas") {
|
||||
object ActorsAlsoKnownAs : Table("actor_alsoknwonas") {
|
||||
val actorId =
|
||||
long("actor_id").references(Actors2.id, onDelete = ReferenceOption.CASCADE, onUpdate = ReferenceOption.CASCADE)
|
||||
val alsoKnownAs = long("alsoKnownAs").references(Actors2.id, ReferenceOption.CASCADE, ReferenceOption.CASCADE)
|
||||
long("actor_id").references(Actors.id, onDelete = ReferenceOption.CASCADE, onUpdate = ReferenceOption.CASCADE)
|
||||
val alsoKnownAs = long("alsoKnownAs").references(Actors.id, ReferenceOption.CASCADE, ReferenceOption.CASCADE)
|
||||
|
||||
override val primaryKey: PrimaryKey = PrimaryKey(actorId, alsoKnownAs)
|
||||
}
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import dev.usbharu.hideout.application.service.id.IdGenerateService
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterMode
|
||||
import dev.usbharu.hideout.core.domain.model.filterkeyword.FilterKeyword
|
||||
import dev.usbharu.hideout.core.domain.model.filterkeyword.FilterKeywordRepository
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
class ExposedFilterKeywordRepository(private val idGenerateService: IdGenerateService) : FilterKeywordRepository,
|
||||
AbstractRepository() {
|
||||
override val logger: Logger
|
||||
get() = Companion.logger
|
||||
|
||||
override suspend fun generateId(): Long = idGenerateService.generateId()
|
||||
|
||||
override suspend fun save(filterKeyword: FilterKeyword): FilterKeyword = query {
|
||||
val empty = FilterKeywords.selectAll().where { FilterKeywords.id eq filterKeyword.id }.empty()
|
||||
if (empty) {
|
||||
FilterKeywords.insert {
|
||||
it[id] = filterKeyword.id
|
||||
it[filterId] = filterKeyword.filterId
|
||||
it[keyword] = filterKeyword.keyword
|
||||
it[mode] = filterKeyword.mode.name
|
||||
}
|
||||
} else {
|
||||
FilterKeywords.update({ FilterKeywords.id eq filterKeyword.id }) {
|
||||
it[filterId] = filterKeyword.filterId
|
||||
it[keyword] = filterKeyword.keyword
|
||||
it[mode] = filterKeyword.mode.name
|
||||
}
|
||||
}
|
||||
filterKeyword
|
||||
}
|
||||
|
||||
override suspend fun saveAll(filterKeywordList: List<FilterKeyword>): Unit = query {
|
||||
FilterKeywords.batchInsert(filterKeywordList, ignore = true) {
|
||||
this[FilterKeywords.id] = it.id
|
||||
this[FilterKeywords.filterId] = it.filterId
|
||||
this[FilterKeywords.keyword] = it.keyword
|
||||
this[FilterKeywords.mode] = it.mode.name
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun findById(id: Long): FilterKeyword? = query {
|
||||
return@query FilterKeywords.selectAll().where { FilterKeywords.id eq id }.singleOrNull()?.toFilterKeyword()
|
||||
}
|
||||
|
||||
override suspend fun deleteById(id: Long): Unit = query {
|
||||
FilterKeywords.deleteWhere { FilterKeywords.id eq id }
|
||||
}
|
||||
|
||||
override suspend fun deleteByFilterId(filterId: Long): Unit = query {
|
||||
FilterKeywords.deleteWhere { FilterKeywords.filterId eq filterId }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(ExposedFilterKeywordRepository::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
fun ResultRow.toFilterKeyword(): FilterKeyword {
|
||||
return FilterKeyword(
|
||||
this[FilterKeywords.id],
|
||||
this[FilterKeywords.filterId],
|
||||
this[FilterKeywords.keyword],
|
||||
this[FilterKeywords.mode].let { FilterMode.valueOf(it) }
|
||||
)
|
||||
}
|
||||
|
||||
object FilterKeywords : Table("filter_keywords") {
|
||||
val id = long("id")
|
||||
val filterId = long("filter_id").references(Filters.id)
|
||||
val keyword = varchar("keyword", 1000)
|
||||
val mode = varchar("mode", 100)
|
||||
|
||||
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import dev.usbharu.hideout.application.service.id.IdGenerateService
|
||||
import dev.usbharu.hideout.core.domain.model.filter.Filter
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterAction
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterRepository
|
||||
import dev.usbharu.hideout.core.domain.model.filter.FilterType
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
class ExposedFilterRepository(private val idGenerateService: IdGenerateService) : FilterRepository,
|
||||
AbstractRepository() {
|
||||
override val logger: Logger
|
||||
get() = Companion.logger
|
||||
|
||||
override suspend fun generateId(): Long = idGenerateService.generateId()
|
||||
|
||||
override suspend fun save(filter: Filter): Filter = query {
|
||||
val empty = Filters.selectAll().where {
|
||||
Filters.id eq filter.id
|
||||
}.forUpdate().empty()
|
||||
if (empty) {
|
||||
Filters.insert {
|
||||
it[id] = filter.id
|
||||
it[userId] = filter.userId
|
||||
it[name] = filter.name
|
||||
it[context] = filter.context.joinToString(",") { filterType -> filterType.name }
|
||||
it[filterAction] = filter.filterAction.name
|
||||
}
|
||||
} else {
|
||||
Filters.update({ Filters.id eq filter.id }) {
|
||||
it[userId] = filter.userId
|
||||
it[name] = filter.name
|
||||
it[context] = filter.context.joinToString(",") { filterType -> filterType.name }
|
||||
it[filterAction] = filter.filterAction.name
|
||||
}
|
||||
}
|
||||
filter
|
||||
}
|
||||
|
||||
override suspend fun findById(id: Long): Filter? = query {
|
||||
return@query Filters.selectAll().where { Filters.id eq id }.singleOrNull()?.toFilter()
|
||||
}
|
||||
|
||||
override suspend fun findByUserIdAndId(userId: Long, id: Long): Filter? = query {
|
||||
return@query Filters.selectAll().where { Filters.userId eq userId and (Filters.id eq id) }.singleOrNull()
|
||||
?.toFilter()
|
||||
}
|
||||
|
||||
override suspend fun findByUserIdAndType(userId: Long, types: List<FilterType>): List<Filter> = query {
|
||||
return@query Filters.selectAll().where { Filters.userId eq userId }.map { it.toFilter() }
|
||||
.filter { it.context.containsAll(types) }
|
||||
}
|
||||
|
||||
override suspend fun deleteById(id: Long): Unit = query {
|
||||
Filters.deleteWhere { Filters.id eq id }
|
||||
}
|
||||
|
||||
override suspend fun deleteByUserIdAndId(userId: Long, id: Long) {
|
||||
Filters.deleteWhere { Filters.userId eq userId and (Filters.id eq id) }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(ExposedFilterRepository::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
fun ResultRow.toFilter(): Filter = Filter(
|
||||
this[Filters.id],
|
||||
this[Filters.userId],
|
||||
this[Filters.name],
|
||||
this[Filters.context].split(",").filterNot(String::isEmpty).map { FilterType.valueOf(it) },
|
||||
this[Filters.filterAction].let { FilterAction.valueOf(it) }
|
||||
)
|
||||
|
||||
object Filters : Table() {
|
||||
val id = long("id")
|
||||
val userId = long("user_id").references(Actors.id)
|
||||
val name = varchar("name", 255)
|
||||
val context = varchar("context", 500)
|
||||
val filterAction = varchar("action", 255)
|
||||
|
||||
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||
}
|
|
@ -20,34 +20,37 @@ import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
|||
import dev.usbharu.hideout.core.domain.model.post.*
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher
|
||||
import dev.usbharu.hideout.core.domain.shared.repository.DomainEventPublishableRepository
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts2.actorId
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts2.apId
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts2.content
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts2.createdAt
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts2.deleted
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts2.hide
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts2.id
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts2.moveTo
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts2.overview
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts2.replyId
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts2.repostId
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts2.sensitive
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts2.text
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts2.url
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts2.visibility
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.actorId
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.apId
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.content
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.createdAt
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.deleted
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.hide
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.id
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.moveTo
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.overview
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.replyId
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.repostId
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.sensitive
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.text
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.url
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.visibility
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.inList
|
||||
import org.jetbrains.exposed.sql.javatime.timestamp
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
class ExposedPost2Repository(override val domainEventPublisher: DomainEventPublisher) : Post2Repository,
|
||||
AbstractRepository(), DomainEventPublishableRepository<Post2> {
|
||||
override suspend fun save(post: Post2): Post2 {
|
||||
class ExposedPostRepository(override val domainEventPublisher: DomainEventPublisher) :
|
||||
PostRepository,
|
||||
AbstractRepository(),
|
||||
DomainEventPublishableRepository<Post> {
|
||||
override suspend fun save(post: Post): Post {
|
||||
query {
|
||||
Posts2.upsert {
|
||||
Posts.upsert {
|
||||
it[id] = post.id.id
|
||||
it[actorId] = post.actorId.id
|
||||
it[overview] = post.overview?.overview
|
||||
|
@ -70,6 +73,9 @@ class ExposedPost2Repository(override val domainEventPublisher: DomainEventPubli
|
|||
PostsEmojis.deleteWhere {
|
||||
postId eq post.id.id
|
||||
}
|
||||
PostsVisibleActors.deleteWhere {
|
||||
postId eq post.id.id
|
||||
}
|
||||
PostsMedia.batchInsert(post.mediaIds) {
|
||||
this[PostsMedia.postId] = post.id.id
|
||||
this[PostsMedia.mediaId] = it.id
|
||||
|
@ -78,14 +84,18 @@ class ExposedPost2Repository(override val domainEventPublisher: DomainEventPubli
|
|||
this[PostsEmojis.postId] = post.id.id
|
||||
this[PostsEmojis.emojiId] = it.emojiId
|
||||
}
|
||||
PostsVisibleActors.batchInsert(post.visibleActors) {
|
||||
this[PostsVisibleActors.postId] = post.id.id
|
||||
this[PostsVisibleActors.actorId] = it.id
|
||||
}
|
||||
}
|
||||
update(post)
|
||||
return post
|
||||
}
|
||||
|
||||
override suspend fun saveAll(posts: List<Post2>): List<Post2> {
|
||||
override suspend fun saveAll(posts: List<Post>): List<Post> {
|
||||
query {
|
||||
Posts2.batchUpsert(posts, id) {
|
||||
Posts.batchUpsert(posts, id) {
|
||||
this[id] = it.id.id
|
||||
this[actorId] = it.actorId.id
|
||||
this[overview] = it.overview?.overview
|
||||
|
@ -103,15 +113,30 @@ class ExposedPost2Repository(override val domainEventPublisher: DomainEventPubli
|
|||
this[moveTo] = it.moveTo?.id
|
||||
}
|
||||
val mediaIds = posts.flatMap { post -> post.mediaIds.map { post.id.id to it.id } }
|
||||
PostsMedia.batchUpsert(mediaIds, PostsMedia.postId) {
|
||||
val postsIds = posts.map { it.id.id }
|
||||
PostsMedia.deleteWhere {
|
||||
postId inList postsIds
|
||||
}
|
||||
PostsMedia.batchInsert(mediaIds) {
|
||||
this[PostsMedia.postId] = it.first
|
||||
this[PostsMedia.mediaId] = it.second
|
||||
}
|
||||
val emojiIds = posts.flatMap { post -> post.emojiIds.map { post.id.id to it.emojiId } }
|
||||
PostsEmojis.batchUpsert(emojiIds, PostsEmojis.postId) {
|
||||
PostsEmojis.deleteWhere {
|
||||
postId inList postsIds
|
||||
}
|
||||
PostsEmojis.batchInsert(emojiIds) {
|
||||
this[PostsEmojis.postId] = it.first
|
||||
this[PostsEmojis.emojiId] = it.second
|
||||
}
|
||||
val visibleActors = posts.flatMap { post -> post.visibleActors.map { post.id.id to it.id } }
|
||||
PostsVisibleActors.deleteWhere {
|
||||
postId inList postsIds
|
||||
}
|
||||
PostsVisibleActors.batchInsert(visibleActors) {
|
||||
this[PostsVisibleActors.postId] = it.first
|
||||
this[PostsVisibleActors.actorId] = it.second
|
||||
}
|
||||
}
|
||||
posts.forEach {
|
||||
update(it)
|
||||
|
@ -119,17 +144,17 @@ class ExposedPost2Repository(override val domainEventPublisher: DomainEventPubli
|
|||
return posts
|
||||
}
|
||||
|
||||
override suspend fun findById(id: PostId): Post2? {
|
||||
override suspend fun findById(id: PostId): Post? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override suspend fun findByActorId(id: ActorId): List<Post2> {
|
||||
override suspend fun findByActorId(id: ActorId): List<Post> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override suspend fun delete(post: Post2) {
|
||||
override suspend fun delete(post: Post) {
|
||||
query {
|
||||
Posts2.deleteWhere {
|
||||
Posts.deleteWhere {
|
||||
id eq post.id.id
|
||||
}
|
||||
}
|
||||
|
@ -139,13 +164,13 @@ class ExposedPost2Repository(override val domainEventPublisher: DomainEventPubli
|
|||
override val logger: Logger = Companion.logger
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(ExposedPost2Repository::class.java)
|
||||
private val logger = LoggerFactory.getLogger(ExposedPostRepository::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
object Posts2 : Table("posts") {
|
||||
object Posts : Table("posts") {
|
||||
val id = long("id")
|
||||
val actorId = long("actor_id").references(Actors2.id)
|
||||
val actorId = long("actor_id").references(Actors.id)
|
||||
val overview = varchar("overview", PostOverview.length).nullable()
|
||||
val content = varchar("content", PostContent.contentLength)
|
||||
val text = varchar("text", PostContent.textLength)
|
||||
|
@ -159,7 +184,6 @@ object Posts2 : Table("posts") {
|
|||
val deleted = bool("deleted")
|
||||
val hide = bool("hide")
|
||||
val moveTo = long("move_to").references(id).nullable()
|
||||
|
||||
}
|
||||
|
||||
object PostsMedia : Table("posts_media") {
|
||||
|
@ -172,4 +196,9 @@ object PostsEmojis : Table("posts_emojis") {
|
|||
val postId = long("post_id").references(id)
|
||||
val emojiId = long("emoji_id").references(CustomEmojis.id)
|
||||
override val primaryKey: PrimaryKey = PrimaryKey(postId, emojiId)
|
||||
}
|
||||
}
|
||||
|
||||
object PostsVisibleActors : Table("posts_visible_actors") {
|
||||
val postId = long("post_id").references(id)
|
||||
val actorId = long("actor_id").references(Actors.id)
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import dev.usbharu.hideout.application.service.id.IdGenerateService
|
||||
import dev.usbharu.hideout.core.domain.model.post.Visibility
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.beans.factory.annotation.Qualifier
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
@Qualifier("jdbc")
|
||||
@ConditionalOnProperty("hideout.use-mongodb", havingValue = "false", matchIfMissing = true)
|
||||
class ExposedTimelineRepository(private val idGenerateService: IdGenerateService) : TimelineRepository,
|
||||
AbstractRepository() {
|
||||
override val logger: Logger
|
||||
get() = Companion.logger
|
||||
|
||||
override suspend fun generateId(): Long = idGenerateService.generateId()
|
||||
|
||||
override suspend fun save(timeline: Timeline): Timeline = query {
|
||||
if (Timelines.selectAll().where { Timelines.id eq timeline.id }.forUpdate().singleOrNull() == null) {
|
||||
Timelines.insert {
|
||||
it[id] = timeline.id
|
||||
it[userId] = timeline.userId
|
||||
it[timelineId] = timeline.timelineId
|
||||
it[postId] = timeline.postId
|
||||
it[postActorId] = timeline.postActorId
|
||||
it[createdAt] = timeline.createdAt
|
||||
it[replyId] = timeline.replyId
|
||||
it[repostId] = timeline.repostId
|
||||
it[visibility] = timeline.visibility.ordinal
|
||||
it[sensitive] = timeline.sensitive
|
||||
it[isLocal] = timeline.isLocal
|
||||
it[isPureRepost] = timeline.isPureRepost
|
||||
it[mediaIds] = timeline.mediaIds.joinToString(",")
|
||||
it[emojiIds] = timeline.emojiIds.joinToString(",")
|
||||
}
|
||||
} else {
|
||||
Timelines.update({ Timelines.id eq timeline.id }) {
|
||||
it[userId] = timeline.userId
|
||||
it[timelineId] = timeline.timelineId
|
||||
it[postId] = timeline.postId
|
||||
it[postActorId] = timeline.postActorId
|
||||
it[createdAt] = timeline.createdAt
|
||||
it[replyId] = timeline.replyId
|
||||
it[repostId] = timeline.repostId
|
||||
it[visibility] = timeline.visibility.ordinal
|
||||
it[sensitive] = timeline.sensitive
|
||||
it[isLocal] = timeline.isLocal
|
||||
it[isPureRepost] = timeline.isPureRepost
|
||||
it[mediaIds] = timeline.mediaIds.joinToString(",")
|
||||
it[emojiIds] = timeline.emojiIds.joinToString(",")
|
||||
}
|
||||
}
|
||||
return@query timeline
|
||||
}
|
||||
|
||||
override suspend fun saveAll(timelines: List<Timeline>): List<Timeline> = query {
|
||||
Timelines.batchInsert(timelines, true, false) {
|
||||
this[Timelines.id] = it.id
|
||||
this[Timelines.userId] = it.userId
|
||||
this[Timelines.timelineId] = it.timelineId
|
||||
this[Timelines.postId] = it.postId
|
||||
this[Timelines.postActorId] = it.postActorId
|
||||
this[Timelines.createdAt] = it.createdAt
|
||||
this[Timelines.replyId] = it.replyId
|
||||
this[Timelines.repostId] = it.repostId
|
||||
this[Timelines.visibility] = it.visibility.ordinal
|
||||
this[Timelines.sensitive] = it.sensitive
|
||||
this[Timelines.isLocal] = it.isLocal
|
||||
this[Timelines.isPureRepost] = it.isPureRepost
|
||||
this[Timelines.mediaIds] = it.mediaIds.joinToString(",")
|
||||
this[Timelines.emojiIds] = it.emojiIds.joinToString(",")
|
||||
}
|
||||
return@query timelines
|
||||
}
|
||||
|
||||
override suspend fun findByUserId(id: Long): List<Timeline> = query {
|
||||
return@query Timelines.selectAll().where { Timelines.userId eq id }.map { it.toTimeline() }
|
||||
}
|
||||
|
||||
override suspend fun findByUserIdAndTimelineId(userId: Long, timelineId: Long): List<Timeline> = query {
|
||||
return@query Timelines.selectAll().where { Timelines.userId eq userId and (Timelines.timelineId eq timelineId) }
|
||||
.map { it.toTimeline() }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(ExposedTimelineRepository::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
fun ResultRow.toTimeline(): Timeline {
|
||||
return Timeline(
|
||||
id = this[Timelines.id],
|
||||
userId = this[Timelines.userId],
|
||||
timelineId = this[Timelines.timelineId],
|
||||
postId = this[Timelines.postId],
|
||||
postActorId = this[Timelines.postActorId],
|
||||
createdAt = this[Timelines.createdAt],
|
||||
replyId = this[Timelines.replyId],
|
||||
repostId = this[Timelines.repostId],
|
||||
visibility = Visibility.values().first { it.ordinal == this[Timelines.visibility] },
|
||||
sensitive = this[Timelines.sensitive],
|
||||
isLocal = this[Timelines.isLocal],
|
||||
isPureRepost = this[Timelines.isPureRepost],
|
||||
mediaIds = this[Timelines.mediaIds].split(",").mapNotNull { it.toLongOrNull() },
|
||||
emojiIds = this[Timelines.emojiIds].split(",").mapNotNull { it.toLongOrNull() }
|
||||
)
|
||||
}
|
||||
|
||||
object Timelines : Table("timelines") {
|
||||
val id = long("id")
|
||||
val userId = long("user_id")
|
||||
val timelineId = long("timeline_id")
|
||||
val postId = long("post_id")
|
||||
val postActorId = long("post_actor_id")
|
||||
val createdAt = long("created_at")
|
||||
val replyId = long("reply_id").nullable()
|
||||
val repostId = long("repost_id").nullable()
|
||||
val visibility = integer("visibility")
|
||||
val sensitive = bool("sensitive")
|
||||
val isLocal = bool("is_local")
|
||||
val isPureRepost = bool("is_pure_repost")
|
||||
val mediaIds = varchar("media_ids", 255)
|
||||
val emojiIds = varchar("emoji_ids", 255)
|
||||
|
||||
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||
|
||||
init {
|
||||
uniqueIndex(userId, timelineId, postId)
|
||||
}
|
||||
}
|
|
@ -16,69 +16,67 @@
|
|||
|
||||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import dev.usbharu.hideout.application.service.id.IdGenerateService
|
||||
import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository
|
||||
import dev.usbharu.hideout.core.domain.model.instance.*
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.jetbrains.exposed.sql.javatime.timestamp
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Repository
|
||||
import java.net.URI
|
||||
import dev.usbharu.hideout.core.domain.model.instance.Instance as InstanceEntity
|
||||
|
||||
@Repository
|
||||
class InstanceRepositoryImpl(private val idGenerateService: IdGenerateService) : InstanceRepository,
|
||||
class InstanceRepositoryImpl : InstanceRepository,
|
||||
AbstractRepository() {
|
||||
override val logger: Logger
|
||||
get() = Companion.logger
|
||||
|
||||
override suspend fun generateId(): Long = idGenerateService.generateId()
|
||||
|
||||
override suspend fun save(instance: InstanceEntity): InstanceEntity = query {
|
||||
if (Instance.selectAll().where { Instance.id.eq(instance.id) }.forUpdate().empty()) {
|
||||
if (Instance.selectAll().where { Instance.id.eq(instance.id.instanceId) }.forUpdate().empty()) {
|
||||
Instance.insert {
|
||||
it[id] = instance.id
|
||||
it[name] = instance.name
|
||||
it[description] = instance.description
|
||||
it[url] = instance.url
|
||||
it[iconUrl] = instance.iconUrl
|
||||
it[sharedInbox] = instance.sharedInbox
|
||||
it[software] = instance.software
|
||||
it[version] = instance.version
|
||||
it[id] = instance.id.instanceId
|
||||
it[name] = instance.name.name
|
||||
it[description] = instance.description.description
|
||||
it[url] = instance.url.toString()
|
||||
it[iconUrl] = instance.iconUrl.toString()
|
||||
it[sharedInbox] = instance.sharedInbox?.toString()
|
||||
it[software] = instance.software.software
|
||||
it[version] = instance.version.version
|
||||
it[isBlocked] = instance.isBlocked
|
||||
it[isMuted] = instance.isMuted
|
||||
it[moderationNote] = instance.moderationNote
|
||||
it[moderationNote] = instance.moderationNote.note
|
||||
it[createdAt] = instance.createdAt
|
||||
}
|
||||
} else {
|
||||
Instance.update({ Instance.id eq instance.id }) {
|
||||
it[name] = instance.name
|
||||
it[description] = instance.description
|
||||
it[url] = instance.url
|
||||
it[iconUrl] = instance.iconUrl
|
||||
it[sharedInbox] = instance.sharedInbox
|
||||
it[software] = instance.software
|
||||
it[version] = instance.version
|
||||
Instance.update({ Instance.id eq instance.id.instanceId }) {
|
||||
it[name] = instance.name.name
|
||||
it[description] = instance.description.description
|
||||
it[url] = instance.url.toString()
|
||||
it[iconUrl] = instance.iconUrl.toString()
|
||||
it[sharedInbox] = instance.sharedInbox?.toString()
|
||||
it[software] = instance.software.software
|
||||
it[version] = instance.version.version
|
||||
it[isBlocked] = instance.isBlocked
|
||||
it[isMuted] = instance.isMuted
|
||||
it[moderationNote] = instance.moderationNote
|
||||
it[moderationNote] = instance.moderationNote.note
|
||||
it[createdAt] = instance.createdAt
|
||||
}
|
||||
}
|
||||
return@query instance
|
||||
}
|
||||
|
||||
override suspend fun findById(id: Long): InstanceEntity? = query {
|
||||
return@query Instance.selectAll().where { Instance.id eq id }
|
||||
override suspend fun findById(id: InstanceId): InstanceEntity? = query {
|
||||
return@query Instance.selectAll().where { Instance.id eq id.instanceId }
|
||||
.singleOrNull()?.toInstance()
|
||||
}
|
||||
|
||||
override suspend fun delete(instance: InstanceEntity): Unit = query {
|
||||
Instance.deleteWhere { id eq instance.id }
|
||||
Instance.deleteWhere { id eq instance.id.instanceId }
|
||||
}
|
||||
|
||||
override suspend fun findByUrl(url: String): dev.usbharu.hideout.core.domain.model.instance.Instance? = query {
|
||||
return@query Instance.selectAll().where { Instance.url eq url }.singleOrNull()?.toInstance()
|
||||
override suspend fun findByUrl(url: URI): dev.usbharu.hideout.core.domain.model.instance.Instance? = query {
|
||||
return@query Instance.selectAll().where { Instance.url eq url.toString() }.singleOrNull()?.toInstance()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -88,17 +86,17 @@ class InstanceRepositoryImpl(private val idGenerateService: IdGenerateService) :
|
|||
|
||||
fun ResultRow.toInstance(): InstanceEntity {
|
||||
return InstanceEntity(
|
||||
id = this[Instance.id],
|
||||
name = this[Instance.name],
|
||||
description = this[Instance.description],
|
||||
url = this[Instance.url],
|
||||
iconUrl = this[Instance.iconUrl],
|
||||
sharedInbox = this[Instance.sharedInbox],
|
||||
software = this[Instance.software],
|
||||
version = this[Instance.version],
|
||||
id = InstanceId(this[Instance.id]),
|
||||
name = InstanceName(this[Instance.name]),
|
||||
description = InstanceDescription(this[Instance.description]),
|
||||
url = URI.create(this[Instance.url]),
|
||||
iconUrl = URI.create(this[Instance.iconUrl]),
|
||||
sharedInbox = this[Instance.sharedInbox]?.let { URI.create(it) },
|
||||
software = InstanceSoftware(this[Instance.software]),
|
||||
version = InstanceVersion(this[Instance.version]),
|
||||
isBlocked = this[Instance.isBlocked],
|
||||
isMuted = this[Instance.isMuted],
|
||||
moderationNote = this[Instance.moderationNote],
|
||||
moderationNote = InstanceModerationNote(this[Instance.moderationNote]),
|
||||
createdAt = this[Instance.createdAt]
|
||||
)
|
||||
}
|
||||
|
|
|
@ -16,105 +16,82 @@
|
|||
|
||||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import dev.usbharu.hideout.application.service.id.IdGenerateService
|
||||
import dev.usbharu.hideout.core.domain.model.media.FileType
|
||||
import dev.usbharu.hideout.core.domain.model.media.MediaRepository
|
||||
import dev.usbharu.hideout.core.domain.model.media.MimeType
|
||||
import dev.usbharu.hideout.core.domain.model.media.*
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Repository
|
||||
import java.net.URI
|
||||
import dev.usbharu.hideout.core.domain.model.media.Media as EntityMedia
|
||||
|
||||
@Repository
|
||||
class MediaRepositoryImpl(private val idGenerateService: IdGenerateService) : MediaRepository, AbstractRepository() {
|
||||
class MediaRepositoryImpl : MediaRepository, AbstractRepository() {
|
||||
override suspend fun findById(id: MediaId): dev.usbharu.hideout.core.domain.model.media.Media? {
|
||||
return query {
|
||||
return@query Media
|
||||
.selectAll().where { Media.id eq id.id }
|
||||
.singleOrNull()
|
||||
?.toMedia()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun delete(media: dev.usbharu.hideout.core.domain.model.media.Media): Unit = query {
|
||||
Media.deleteWhere {
|
||||
id eq id
|
||||
}
|
||||
}
|
||||
|
||||
override val logger: Logger
|
||||
get() = Companion.logger
|
||||
|
||||
override suspend fun generateId(): Long = idGenerateService.generateId()
|
||||
|
||||
override suspend fun save(media: EntityMedia): EntityMedia = query {
|
||||
if (Media.selectAll().where { Media.id eq media.id }.forUpdate().singleOrNull() != null
|
||||
if (Media.selectAll().where { Media.id eq media.id.id }.forUpdate().singleOrNull() != null
|
||||
) {
|
||||
Media.update({ Media.id eq media.id }) {
|
||||
it[name] = media.name
|
||||
it[url] = media.url
|
||||
it[remoteUrl] = media.remoteUrl
|
||||
it[thumbnailUrl] = media.thumbnailUrl
|
||||
it[type] = media.type.ordinal
|
||||
it[blurhash] = media.blurHash
|
||||
Media.update({ Media.id eq media.id.id }) {
|
||||
it[name] = media.name.name
|
||||
it[url] = media.url.toString()
|
||||
it[remoteUrl] = media.remoteUrl?.toString()
|
||||
it[thumbnailUrl] = media.thumbnailUrl?.toString()
|
||||
it[type] = media.type.name
|
||||
it[blurhash] = media.blurHash?.hash
|
||||
it[mimeType] = media.mimeType.type + "/" + media.mimeType.subtype
|
||||
it[description] = media.description
|
||||
it[description] = media.description?.description
|
||||
}
|
||||
} else {
|
||||
Media.insert {
|
||||
it[id] = media.id
|
||||
it[name] = media.name
|
||||
it[url] = media.url
|
||||
it[remoteUrl] = media.remoteUrl
|
||||
it[thumbnailUrl] = media.thumbnailUrl
|
||||
it[type] = media.type.ordinal
|
||||
it[blurhash] = media.blurHash
|
||||
it[id] = media.id.id
|
||||
it[name] = media.name.name
|
||||
it[url] = media.url.toString()
|
||||
it[remoteUrl] = media.remoteUrl?.toString()
|
||||
it[thumbnailUrl] = media.thumbnailUrl?.toString()
|
||||
it[type] = media.type.name
|
||||
it[blurhash] = media.blurHash?.hash
|
||||
it[mimeType] = media.mimeType.type + "/" + media.mimeType.subtype
|
||||
it[description] = media.description
|
||||
it[description] = media.description?.description
|
||||
}
|
||||
}
|
||||
return@query media
|
||||
}
|
||||
|
||||
override suspend fun findById(id: Long): EntityMedia? = query {
|
||||
return@query Media
|
||||
.selectAll().where { Media.id eq id }
|
||||
.singleOrNull()
|
||||
?.toMedia()
|
||||
}
|
||||
|
||||
override suspend fun delete(id: Long): Unit = query {
|
||||
Media.deleteWhere {
|
||||
Media.id eq id
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun findByRemoteUrl(remoteUrl: String): dev.usbharu.hideout.core.domain.model.media.Media? =
|
||||
query {
|
||||
return@query Media.selectAll().where { Media.remoteUrl eq remoteUrl }.singleOrNull()?.toMedia()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(MediaRepositoryImpl::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
fun ResultRow.toMedia(): EntityMedia {
|
||||
val fileType = FileType.values().first { it.ordinal == this[Media.type] }
|
||||
val fileType = FileType.valueOf(this[Media.type])
|
||||
val mimeType = this[Media.mimeType]
|
||||
return EntityMedia(
|
||||
id = this[Media.id],
|
||||
name = this[Media.name],
|
||||
url = this[Media.url],
|
||||
remoteUrl = this[Media.remoteUrl],
|
||||
thumbnailUrl = this[Media.thumbnailUrl],
|
||||
id = MediaId(this[Media.id]),
|
||||
name = MediaName(this[Media.name]),
|
||||
url = URI.create(this[Media.url]),
|
||||
remoteUrl = this[Media.remoteUrl]?.let { URI.create(it) },
|
||||
thumbnailUrl = this[Media.thumbnailUrl]?.let { URI.create(it) },
|
||||
type = fileType,
|
||||
blurHash = this[Media.blurhash],
|
||||
blurHash = this[Media.blurhash]?.let { MediaBlurHash(it) },
|
||||
mimeType = MimeType(mimeType.substringBefore("/"), mimeType.substringAfter("/"), fileType),
|
||||
description = this[Media.description]
|
||||
)
|
||||
}
|
||||
|
||||
fun ResultRow.toMediaOrNull(): EntityMedia? {
|
||||
val fileType = FileType.values().first { it.ordinal == (this.getOrNull(Media.type) ?: return null) }
|
||||
val mimeType = this.getOrNull(Media.mimeType) ?: return null
|
||||
return EntityMedia(
|
||||
id = this.getOrNull(Media.id) ?: return null,
|
||||
name = this.getOrNull(Media.name) ?: return null,
|
||||
url = this.getOrNull(Media.url) ?: return null,
|
||||
remoteUrl = this[Media.remoteUrl],
|
||||
thumbnailUrl = this[Media.thumbnailUrl],
|
||||
type = FileType.values().first { it.ordinal == this.getOrNull(Media.type) },
|
||||
blurHash = this[Media.blurhash],
|
||||
mimeType = MimeType(mimeType.substringBefore("/"), mimeType.substringAfter("/"), fileType),
|
||||
description = this[Media.description]
|
||||
description = this[Media.description]?.let { MediaDescription(it) }
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -124,7 +101,7 @@ object Media : Table("media") {
|
|||
val url = varchar("url", 255).uniqueIndex()
|
||||
val remoteUrl = varchar("remote_url", 255).uniqueIndex().nullable()
|
||||
val thumbnailUrl = varchar("thumbnail_url", 255).uniqueIndex().nullable()
|
||||
val type = integer("type")
|
||||
val type = varchar("type", 100)
|
||||
val blurhash = varchar("blurhash", 255).nullable()
|
||||
val mimeType = varchar("mime_type", 255)
|
||||
val description = varchar("description", 4000).nullable()
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.springframework.stereotype.Repository
|
||||
import java.util.*
|
||||
|
||||
@Repository
|
||||
class MetaRepositoryImpl : MetaRepository {
|
||||
|
||||
override suspend fun save(meta: dev.usbharu.hideout.core.domain.model.meta.Meta) {
|
||||
if (Meta.selectAll().where { Meta.id eq 1 }.empty()) {
|
||||
Meta.insert {
|
||||
it[id] = 1
|
||||
it[version] = meta.version
|
||||
it[kid] = UUID.randomUUID().toString()
|
||||
it[jwtPrivateKey] = meta.jwt.privateKey
|
||||
it[jwtPublicKey] = meta.jwt.publicKey
|
||||
}
|
||||
} else {
|
||||
Meta.update({ Meta.id eq 1 }) {
|
||||
it[version] = meta.version
|
||||
it[kid] = UUID.randomUUID().toString()
|
||||
it[jwtPrivateKey] = meta.jwt.privateKey
|
||||
it[jwtPublicKey] = meta.jwt.publicKey
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun get(): dev.usbharu.hideout.core.domain.model.meta.Meta? {
|
||||
return Meta.selectAll().where { Meta.id eq 1 }.singleOrNull()?.let {
|
||||
dev.usbharu.hideout.core.domain.model.meta.Meta(
|
||||
it[Meta.version],
|
||||
Jwt(UUID.fromString(it[Meta.kid]), it[Meta.jwtPrivateKey], it[Meta.jwtPublicKey])
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object Meta : Table("meta_info") {
|
||||
val id: Column<Long> = long("id")
|
||||
val version: Column<String> = varchar("version", 1000)
|
||||
val kid: Column<String> = varchar("kid", 1000)
|
||||
val jwtPrivateKey: Column<String> = varchar("jwt_private_key", 100000)
|
||||
val jwtPublicKey: Column<String> = varchar("jwt_public_key", 100000)
|
||||
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||
}
|
|
@ -16,14 +16,14 @@
|
|||
|
||||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailHashedPassword
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
|
||||
import org.jetbrains.exposed.dao.id.LongIdTable
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.jetbrains.exposed.sql.deleteWhere
|
||||
import org.jetbrains.exposed.sql.insert
|
||||
import org.jetbrains.exposed.sql.selectAll
|
||||
import org.jetbrains.exposed.sql.update
|
||||
import org.jetbrains.exposed.sql.javatime.timestamp
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Repository
|
||||
|
@ -35,24 +35,28 @@ class UserDetailRepositoryImpl : UserDetailRepository, AbstractRepository() {
|
|||
|
||||
override suspend fun save(userDetail: UserDetail): UserDetail = query {
|
||||
val singleOrNull =
|
||||
UserDetails.selectAll().where { UserDetails.actorId eq userDetail.actorId }.forUpdate().singleOrNull()
|
||||
UserDetails.selectAll().where { UserDetails.id eq userDetail.id.id }.forUpdate().singleOrNull()
|
||||
if (singleOrNull == null) {
|
||||
UserDetails.insert {
|
||||
it[actorId] = userDetail.actorId
|
||||
it[password] = userDetail.password
|
||||
it[id] = userDetail.id.id
|
||||
it[actorId] = userDetail.actorId.id
|
||||
it[password] = userDetail.password.password
|
||||
it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest
|
||||
it[lastMigration] = userDetail.lastMigration
|
||||
}
|
||||
} else {
|
||||
UserDetails.update({ UserDetails.actorId eq userDetail.actorId }) {
|
||||
it[password] = userDetail.password
|
||||
UserDetails.update({ UserDetails.id eq userDetail.id.id }) {
|
||||
it[actorId] = userDetail.actorId.id
|
||||
it[password] = userDetail.password.password
|
||||
it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest
|
||||
it[lastMigration] = userDetail.lastMigration
|
||||
}
|
||||
}
|
||||
return@query userDetail
|
||||
}
|
||||
|
||||
override suspend fun delete(userDetail: UserDetail): Unit = query {
|
||||
UserDetails.deleteWhere { actorId eq userDetail.actorId }
|
||||
UserDetails.deleteWhere { id eq userDetail.id.id }
|
||||
}
|
||||
|
||||
override suspend fun findByActorId(actorId: Long): UserDetail? = query {
|
||||
|
@ -60,10 +64,12 @@ class UserDetailRepositoryImpl : UserDetailRepository, AbstractRepository() {
|
|||
.selectAll().where { UserDetails.actorId eq actorId }
|
||||
.singleOrNull()
|
||||
?.let {
|
||||
UserDetail(
|
||||
it[UserDetails.actorId],
|
||||
it[UserDetails.password],
|
||||
it[UserDetails.autoAcceptFolloweeFollowRequest]
|
||||
UserDetail.create(
|
||||
UserDetailId(it[UserDetails.id]),
|
||||
ActorId(it[UserDetails.actorId]),
|
||||
UserDetailHashedPassword(it[UserDetails.password]),
|
||||
it[UserDetails.autoAcceptFolloweeFollowRequest],
|
||||
it[UserDetails.lastMigration]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -73,8 +79,11 @@ class UserDetailRepositoryImpl : UserDetailRepository, AbstractRepository() {
|
|||
}
|
||||
}
|
||||
|
||||
object UserDetails : LongIdTable("user_details") {
|
||||
object UserDetails : Table("user_details") {
|
||||
val id = long("id")
|
||||
val actorId = long("actor_id").references(Actors.id)
|
||||
val password = varchar("password", 255)
|
||||
val autoAcceptFolloweeFollowRequest = bool("auto_accept_followee_follow_request")
|
||||
val lastMigration = timestamp("last_migration").nullable()
|
||||
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||
}
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.infrastructure.factory
|
||||
|
||||
import dev.usbharu.hideout.application.config.ApplicationConfig
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorDescription
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiRepository
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.EmojiId
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class ActorDescriptionFactoryImpl(
|
||||
private val applicationConfig: ApplicationConfig,
|
||||
private val emojiRepository: CustomEmojiRepository,
|
||||
) : ActorDescription.ActorDescriptionFactory() {
|
||||
val regex = Regex(":(w+):")
|
||||
suspend fun create(description: String): ActorDescription {
|
||||
val findAll = regex.findAll(description)
|
||||
|
||||
val emojis =
|
||||
emojiRepository.findByNamesAndDomain(
|
||||
findAll.map { it.groupValues[1] }.toList(),
|
||||
applicationConfig.url.host
|
||||
)
|
||||
return create(description, emojis.map { EmojiId(it.id) })
|
||||
}
|
||||
}
|
|
@ -26,25 +26,23 @@ import java.net.URI
|
|||
import java.time.Instant
|
||||
|
||||
@Component
|
||||
class Actor2FactoryImpl(
|
||||
class ActorFactoryImpl(
|
||||
private val idGenerateService: IdGenerateService,
|
||||
private val actorScreenNameFactory: ActorScreenNameFactoryImpl,
|
||||
private val actorDescriptionFactory: ActorDescriptionFactoryImpl,
|
||||
private val applicationConfig: ApplicationConfig,
|
||||
) : Actor2.Actor2Factory() {
|
||||
) {
|
||||
suspend fun createLocal(
|
||||
name: String,
|
||||
keyPair: Pair<ActorPublicKey, ActorPrivateKey>,
|
||||
instanceId: InstanceId,
|
||||
): Actor2 {
|
||||
): Actor {
|
||||
val actorName = ActorName(name)
|
||||
val userUrl = "${applicationConfig.url}/users/${actorName.name}"
|
||||
return super.internalCreate(
|
||||
return Actor(
|
||||
id = ActorId(idGenerateService.generateId()),
|
||||
name = actorName,
|
||||
domain = Domain(applicationConfig.url.host),
|
||||
screenName = actorScreenNameFactory.create(name),
|
||||
description = actorDescriptionFactory.create(""),
|
||||
screenName = ActorScreenName(name),
|
||||
description = ActorDescription(""),
|
||||
inbox = URI.create("$userUrl/inbox"),
|
||||
outbox = URI.create("$userUrl/outbox"),
|
||||
url = applicationConfig.url.toURI(),
|
||||
|
@ -59,8 +57,11 @@ class Actor2FactoryImpl(
|
|||
followersCount = ActorRelationshipCount(0),
|
||||
followingCount = ActorRelationshipCount(0),
|
||||
postsCount = ActorPostsCount(0),
|
||||
lastPostDate = null,
|
||||
suspend = false
|
||||
lastPostAt = null,
|
||||
suspend = false,
|
||||
emojiIds = emptySet()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// todo なんか色々おかしいので直す
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.infrastructure.factory
|
||||
|
||||
import dev.usbharu.hideout.application.config.ApplicationConfig
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorScreenName
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiRepository
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.EmojiId
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class ActorScreenNameFactoryImpl(
|
||||
private val applicationConfig: ApplicationConfig,
|
||||
private val emojiRepository: CustomEmojiRepository,
|
||||
) : ActorScreenName.ActorScreenNameFactory() {
|
||||
val regex = Regex(":(w+):")
|
||||
|
||||
suspend fun create(content: String): ActorScreenName {
|
||||
|
||||
val findAll = regex.findAll(content)
|
||||
|
||||
val emojis =
|
||||
emojiRepository.findByNamesAndDomain(
|
||||
findAll.map { it.groupValues[1] }.toList(),
|
||||
applicationConfig.url.host
|
||||
)
|
||||
return create(content, emojis.map { EmojiId(it.id) })
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -32,4 +32,4 @@ class PostContentFactoryImpl(
|
|||
emptyList()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import dev.usbharu.hideout.application.service.id.IdGenerateService
|
|||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorName
|
||||
import dev.usbharu.hideout.core.domain.model.media.MediaId
|
||||
import dev.usbharu.hideout.core.domain.model.post.Post2
|
||||
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.PostOverview
|
||||
import dev.usbharu.hideout.core.domain.model.post.Visibility
|
||||
|
@ -34,7 +34,7 @@ class PostFactoryImpl(
|
|||
private val idGenerateService: IdGenerateService,
|
||||
private val postContentFactoryImpl: PostContentFactoryImpl,
|
||||
private val applicationConfig: ApplicationConfig,
|
||||
) : Post2.PostFactory() {
|
||||
) : Post.PostFactory() {
|
||||
suspend fun createLocal(
|
||||
actorId: ActorId,
|
||||
actorName: ActorName,
|
||||
|
@ -45,7 +45,7 @@ class PostFactoryImpl(
|
|||
replyId: PostId?,
|
||||
sensitive: Boolean,
|
||||
mediaIds: List<MediaId>,
|
||||
): Post2 {
|
||||
): Post {
|
||||
val id = idGenerateService.generateId()
|
||||
val url = URI.create(applicationConfig.url.toString() + "/users/" + actorName + "/posts/" + id)
|
||||
return super.create(
|
||||
|
@ -64,4 +64,4 @@ class PostFactoryImpl(
|
|||
mediaIds
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,4 +27,4 @@ class SpringFrameworkDomainEventPublisher(private val applicationEventPublisher:
|
|||
override suspend fun publishEvent(domainEvent: DomainEvent) {
|
||||
applicationEventPublisher.publishEvent(domainEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,32 +16,16 @@
|
|||
|
||||
package dev.usbharu.hideout.core.interfaces.api.auth
|
||||
|
||||
import dev.usbharu.hideout.application.config.ApplicationConfig
|
||||
import dev.usbharu.hideout.application.config.CaptchaConfig
|
||||
import org.springframework.stereotype.Controller
|
||||
import org.springframework.ui.Model
|
||||
import org.springframework.validation.annotation.Validated
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.ModelAttribute
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
|
||||
@Controller
|
||||
class AuthController(
|
||||
private val authApiService: AuthApiService,
|
||||
private val captchaConfig: CaptchaConfig,
|
||||
private val applicationConfig: ApplicationConfig
|
||||
) {
|
||||
interface AuthController {
|
||||
@GetMapping("/auth/sign_up")
|
||||
fun signUp(model: Model): String {
|
||||
model.addAttribute("siteKey", captchaConfig.reCaptchaSiteKey)
|
||||
model.addAttribute("applicationConfig", applicationConfig)
|
||||
return "sign_up"
|
||||
}
|
||||
fun signUp(model: Model): String
|
||||
|
||||
@PostMapping("/auth/sign_up")
|
||||
suspend fun signUp(@Validated @ModelAttribute signUpForm: SignUpForm): String {
|
||||
|
||||
|
||||
return "redirect:" + registerAccount.url
|
||||
}
|
||||
suspend fun signUp(@Validated @ModelAttribute signUpForm: SignUpForm): String
|
||||
}
|
||||
|
|
|
@ -16,43 +16,21 @@
|
|||
|
||||
package dev.usbharu.hideout.core.interfaces.api.media
|
||||
|
||||
import dev.usbharu.hideout.application.config.LocalStorageConfig
|
||||
import dev.usbharu.hideout.core.service.media.FileTypeDeterminationService
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
|
||||
import org.springframework.core.io.ClassPathResource
|
||||
import org.springframework.core.io.PathResource
|
||||
import org.springframework.core.io.Resource
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.stereotype.Controller
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.name
|
||||
|
||||
@Controller
|
||||
@ConditionalOnProperty("hideout.storage.type", havingValue = "local", matchIfMissing = true)
|
||||
class LocalFileController(
|
||||
localStorageConfig: LocalStorageConfig,
|
||||
private val fileTypeDeterminationService: FileTypeDeterminationService
|
||||
) {
|
||||
|
||||
private val savePath = Path.of(localStorageConfig.path).toAbsolutePath()
|
||||
interface LocalFileController {
|
||||
|
||||
@GetMapping("/files/{id}")
|
||||
fun files(@PathVariable("id") id: String): ResponseEntity<Resource> {
|
||||
val name = Path.of(id).name
|
||||
val path = savePath.resolve(name)
|
||||
|
||||
val mimeType = fileTypeDeterminationService.fileType(path, name)
|
||||
val pathResource = PathResource(path)
|
||||
|
||||
return ResponseEntity
|
||||
.ok()
|
||||
.contentType(MediaType(mimeType.type, mimeType.subtype))
|
||||
.contentLength(pathResource.contentLength())
|
||||
.body(pathResource)
|
||||
}
|
||||
fun files(@PathVariable("id") id: String): ResponseEntity<Resource>
|
||||
|
||||
@GetMapping("/users/{user}/icon.jpg", "/users/{user}/header.jpg")
|
||||
fun icons(): ResponseEntity<Resource> {
|
||||
|
|
|
@ -44,5 +44,4 @@ object RsaUtil {
|
|||
}
|
||||
|
||||
fun decodeRsaPrivateKey(encoded: String): RSAPrivateKey = decodeRsaPrivateKey(Base64Util.decode(encoded))
|
||||
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package dev.usbharu.hideout.core.domain.model.actor
|
|||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
|
||||
class Actors2Test {
|
||||
class ActorsTest {
|
||||
@Test
|
||||
fun alsoKnownAsに自分自身が含まれてはいけない() {
|
||||
val actor = TestActor2Factory.create(publicKey = ActorPublicKey(""))
|
|
@ -7,7 +7,7 @@ import kotlinx.coroutines.runBlocking
|
|||
import java.net.URI
|
||||
import java.time.Instant
|
||||
|
||||
object TestActor2Factory : Actor2.Actor2Factory() {
|
||||
object TestActor2Factory : Actor.Actor2Factory() {
|
||||
private val idGenerateService = TwitterSnowflakeIdGenerateService
|
||||
|
||||
fun create(
|
||||
|
@ -31,8 +31,8 @@ object TestActor2Factory : Actor2.Actor2Factory() {
|
|||
followingCount: Int = 0,
|
||||
postCount: Int = 0,
|
||||
lastPostDate: Instant? = null,
|
||||
suspend: Boolean = false
|
||||
): Actor2 {
|
||||
suspend: Boolean = false,
|
||||
): Actor {
|
||||
return runBlocking {
|
||||
super.internalCreate(
|
||||
id = ActorId(id),
|
||||
|
|
Loading…
Reference in New Issue