From 5d052b9ad88f9283a50fffb8d5eb85cc7c12016c Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 4 May 2023 23:47:24 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20repository=E3=81=ABtransaction=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/IJwtRefreshTokenRepository.kt | 2 + .../hideout/repository/IMetaRepository.kt | 2 + .../hideout/repository/IPostRepository.kt | 2 + .../hideout/repository/IUserRepository.kt | 2 + .../JwtRefreshTokenRepositoryImpl.kt | 66 ++--- .../hideout/repository/MetaRepositoryImpl.kt | 46 ++-- .../hideout/repository/PostRepositoryImpl.kt | 62 ++--- .../hideout/repository/UserRepository.kt | 244 ++++++++---------- .../service/ServerInitialiseServiceImpl.kt | 25 +- .../hideout/repository/UserRepositoryTest.kt | 189 +++++++------- .../ServerInitialiseServiceImplTest.kt | 24 +- 11 files changed, 320 insertions(+), 344 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/IJwtRefreshTokenRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/IJwtRefreshTokenRepository.kt index 9e6a3c96..ae7f8140 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/IJwtRefreshTokenRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/IJwtRefreshTokenRepository.kt @@ -3,6 +3,8 @@ package dev.usbharu.hideout.repository import dev.usbharu.hideout.domain.model.hideout.entity.JwtRefreshToken interface IJwtRefreshTokenRepository { + suspend fun transaction(block: suspend () -> T):T + suspend fun generateId(): Long suspend fun save(token: JwtRefreshToken) diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/IMetaRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/IMetaRepository.kt index b90be212..04af6c93 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/IMetaRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/IMetaRepository.kt @@ -4,6 +4,8 @@ import dev.usbharu.hideout.domain.model.hideout.entity.Meta interface IMetaRepository { + suspend fun transaction(block: suspend () -> T):T + suspend fun save(meta: Meta) suspend fun get(): Meta? diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/IPostRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/IPostRepository.kt index 9fee2d02..f620161d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/IPostRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/IPostRepository.kt @@ -7,4 +7,6 @@ interface IPostRepository { suspend fun insert(post: Post): PostEntity suspend fun findOneById(id: Long): PostEntity suspend fun delete(id: Long) + @Suppress("InjectDispatcher") + suspend fun transaction(block: suspend () -> T): T } diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt index c35382dd..4cf821d2 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt @@ -36,4 +36,6 @@ interface IUserRepository { suspend fun findFollowersById(id: Long): List suspend fun nextId(): Long + @Suppress("InjectDispatcher") + suspend fun transaction(block: suspend () -> T): T } diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/JwtRefreshTokenRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/JwtRefreshTokenRepositoryImpl.kt index fccc8c38..0e5f494f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/JwtRefreshTokenRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/JwtRefreshTokenRepositoryImpl.kt @@ -1,6 +1,8 @@ package dev.usbharu.hideout.repository import dev.usbharu.hideout.domain.model.hideout.entity.JwtRefreshToken +import dev.usbharu.hideout.repository.JwtRefreshTokens.id +import dev.usbharu.hideout.repository.JwtRefreshTokens.refreshToken import dev.usbharu.hideout.service.IdGenerateService import kotlinx.coroutines.Dispatchers import org.jetbrains.exposed.sql.* @@ -25,78 +27,60 @@ class JwtRefreshTokenRepositoryImpl( } @Suppress("InjectDispatcher") - suspend fun query(block: suspend () -> T): T = + override suspend fun transaction(block: suspend () -> T): T = newSuspendedTransaction(Dispatchers.IO) { block() } override suspend fun generateId(): Long = idGenerateService.generateId() override suspend fun save(token: JwtRefreshToken) { - query { - if (JwtRefreshTokens.select { JwtRefreshTokens.id.eq(token.id) }.empty()) { - JwtRefreshTokens.insert { - it[id] = token.id - it[userId] = token.userId - it[refreshToken] = token.refreshToken - it[createdAt] = token.createdAt.toEpochMilli() - it[expiresAt] = token.expiresAt.toEpochMilli() - } - } else { - JwtRefreshTokens.update({ JwtRefreshTokens.id eq token.id }) { - it[userId] = token.userId - it[refreshToken] = token.refreshToken - it[createdAt] = token.createdAt.toEpochMilli() - it[expiresAt] = token.expiresAt.toEpochMilli() - } + if (JwtRefreshTokens.select { id.eq(token.id) }.empty()) { + JwtRefreshTokens.insert { + it[id] = token.id + it[userId] = token.userId + it[refreshToken] = token.refreshToken + it[createdAt] = token.createdAt.toEpochMilli() + it[expiresAt] = token.expiresAt.toEpochMilli() + } + } else { + JwtRefreshTokens.update({ id eq token.id }) { + it[userId] = token.userId + it[refreshToken] = token.refreshToken + it[createdAt] = token.createdAt.toEpochMilli() + it[expiresAt] = token.expiresAt.toEpochMilli() } } } override suspend fun findById(id: Long): JwtRefreshToken? { - return query { - JwtRefreshTokens.select { JwtRefreshTokens.id.eq(id) }.singleOrNull()?.toJwtRefreshToken() - } + return JwtRefreshTokens.select { JwtRefreshTokens.id.eq(id) }.singleOrNull()?.toJwtRefreshToken() } override suspend fun findByToken(token: String): JwtRefreshToken? { - return query { - JwtRefreshTokens.select { JwtRefreshTokens.refreshToken.eq(token) }.singleOrNull()?.toJwtRefreshToken() - } + return JwtRefreshTokens.select { refreshToken.eq(token) }.singleOrNull()?.toJwtRefreshToken() } override suspend fun findByUserId(userId: Long): JwtRefreshToken? { - return query { - JwtRefreshTokens.select { JwtRefreshTokens.userId.eq(userId) }.singleOrNull()?.toJwtRefreshToken() - } + return JwtRefreshTokens.select { JwtRefreshTokens.userId.eq(userId) }.singleOrNull()?.toJwtRefreshToken() } override suspend fun delete(token: JwtRefreshToken) { - return query { - JwtRefreshTokens.deleteWhere { JwtRefreshTokens.id eq token.id } - } + JwtRefreshTokens.deleteWhere { id eq token.id } } override suspend fun deleteById(id: Long) { - return query { - JwtRefreshTokens.deleteWhere { JwtRefreshTokens.id eq id } - } + JwtRefreshTokens.deleteWhere { JwtRefreshTokens.id eq id } } override suspend fun deleteByToken(token: String) { - return query { - JwtRefreshTokens.deleteWhere { JwtRefreshTokens.refreshToken eq token } - } + JwtRefreshTokens.deleteWhere { refreshToken eq token } } override suspend fun deleteByUserId(userId: Long) { - return query { - JwtRefreshTokens.deleteWhere { JwtRefreshTokens.userId eq userId } - } + JwtRefreshTokens.deleteWhere { JwtRefreshTokens.userId eq userId } } override suspend fun deleteAll() { - return query { - JwtRefreshTokens.deleteAll() - } + JwtRefreshTokens.deleteAll() } } diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/MetaRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/MetaRepositoryImpl.kt index a479512d..a4f999ef 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/MetaRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/MetaRepositoryImpl.kt @@ -1,6 +1,8 @@ package dev.usbharu.hideout.repository import dev.usbharu.hideout.domain.model.hideout.entity.Jwt +import dev.usbharu.hideout.repository.Meta.id +import dev.usbharu.hideout.repository.Meta.kid import kotlinx.coroutines.Dispatchers import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction @@ -19,38 +21,34 @@ class MetaRepositoryImpl(private val database: Database) : IMetaRepository { } @Suppress("InjectDispatcher") - suspend fun query(block: suspend () -> T): T = + override suspend fun transaction(block: suspend () -> T): T = newSuspendedTransaction(Dispatchers.IO) { block() } override suspend fun save(meta: dev.usbharu.hideout.domain.model.hideout.entity.Meta) { - return query { - if (Meta.select { Meta.id eq 1 }.empty()) { - Meta.insert { - it[id] = 1 - it[this.version] = meta.version - it[kid] = UUID.randomUUID().toString() - it[this.jwtPrivateKey] = meta.jwt.privateKey - it[this.jwtPublicKey] = meta.jwt.publicKey - } - } else { - Meta.update({ Meta.id eq 1 }) { - it[this.version] = meta.version - it[kid] = UUID.randomUUID().toString() - it[this.jwtPrivateKey] = meta.jwt.privateKey - it[this.jwtPublicKey] = meta.jwt.publicKey - } + if (Meta.select { 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({ 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.domain.model.hideout.entity.Meta? { - return query { - Meta.select { Meta.id eq 1 }.singleOrNull()?.let { - dev.usbharu.hideout.domain.model.hideout.entity.Meta( - it[Meta.version], - Jwt(UUID.fromString(it[Meta.kid]), it[Meta.jwtPrivateKey], it[Meta.jwtPublicKey]) - ) - } + return Meta.select { id eq 1 }.singleOrNull()?.let { + dev.usbharu.hideout.domain.model.hideout.entity.Meta( + it[Meta.version], + Jwt(UUID.fromString(it[kid]), it[Meta.jwtPrivateKey], it[Meta.jwtPublicKey]) + ) } } } diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt index 9a57f4e7..707bf82e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt @@ -23,48 +23,40 @@ class PostRepositoryImpl(database: Database, private val idGenerateService: IdGe } @Suppress("InjectDispatcher") - suspend fun query(block: suspend () -> T): T = + override suspend fun transaction(block: suspend () -> T): T = newSuspendedTransaction(Dispatchers.IO) { block() } override suspend fun insert(post: Post): PostEntity { - return query { - val generateId = idGenerateService.generateId() - val name = Users.select { Users.id eq post.userId }.single().toUser().name - val postUrl = Config.configData.url + "/users/$name/posts/$generateId" - Posts.insert { - it[id] = generateId - it[userId] = post.userId - it[overview] = post.overview - it[text] = post.text - it[createdAt] = post.createdAt - it[visibility] = post.visibility - it[url] = postUrl - it[repostId] = post.repostId - it[replyId] = post.replyId - } - return@query PostEntity( - id = generateId, - userId = post.userId, - overview = post.overview, - text = post.text, - createdAt = post.createdAt, - visibility = post.visibility, - url = postUrl, - repostId = post.repostId, - replyId = post.replyId - ) + val generateId = idGenerateService.generateId() + val name = Users.select { Users.id eq post.userId }.single().toUser().name + val postUrl = Config.configData.url + "/users/$name/posts/$generateId" + Posts.insert { + it[id] = generateId + it[userId] = post.userId + it[overview] = post.overview + it[text] = post.text + it[createdAt] = post.createdAt + it[visibility] = post.visibility + it[url] = postUrl + it[repostId] = post.repostId + it[replyId] = post.replyId } + return PostEntity( + id = generateId, + userId = post.userId, + overview = post.overview, + text = post.text, + createdAt = post.createdAt, + visibility = post.visibility, + url = postUrl, + repostId = post.repostId, + replyId = post.replyId + ) } - override suspend fun findOneById(id: Long): PostEntity { - return query { - Posts.select { Posts.id eq id }.single().toPost() - } - } + override suspend fun findOneById(id: Long): PostEntity = Posts.select { Posts.id eq id }.single().toPost() override suspend fun delete(id: Long) { - return query { - Posts.deleteWhere { Posts.id eq id } - } + Posts.deleteWhere { Posts.id eq id } } } diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt index 763f71eb..74a056d5 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt @@ -1,6 +1,19 @@ package dev.usbharu.hideout.repository import dev.usbharu.hideout.domain.model.hideout.entity.User +import dev.usbharu.hideout.repository.Users.createdAt +import dev.usbharu.hideout.repository.Users.description +import dev.usbharu.hideout.repository.Users.domain +import dev.usbharu.hideout.repository.Users.id +import dev.usbharu.hideout.repository.Users.inbox +import dev.usbharu.hideout.repository.Users.name +import dev.usbharu.hideout.repository.Users.outbox +import dev.usbharu.hideout.repository.Users.password +import dev.usbharu.hideout.repository.Users.privateKey +import dev.usbharu.hideout.repository.Users.publicKey +import dev.usbharu.hideout.repository.Users.screenName +import dev.usbharu.hideout.repository.Users.url +import dev.usbharu.hideout.repository.UsersFollowers.followerId import dev.usbharu.hideout.service.IdGenerateService import kotlinx.coroutines.Dispatchers import org.jetbrains.exposed.dao.id.LongIdTable @@ -24,185 +37,148 @@ class UserRepository(private val database: Database, private val idGenerateServi } @Suppress("InjectDispatcher") - suspend fun query(block: suspend () -> T): T = + override suspend fun transaction(block: suspend () -> T): T = newSuspendedTransaction(Dispatchers.IO) { block() } override suspend fun save(user: User): User { - return query { - val singleOrNull = Users.select { Users.id eq user.id }.singleOrNull() - if (singleOrNull == null) { - Users.insert { - it[id] = user.id - it[name] = user.name - it[domain] = user.domain - it[screenName] = user.screenName - it[description] = user.description - it[password] = user.password - it[inbox] = user.inbox - it[outbox] = user.outbox - it[url] = user.url - it[createdAt] = user.createdAt.toEpochMilli() - it[publicKey] = user.publicKey - it[privateKey] = user.privateKey - } - } else { - Users.update({ Users.id eq user.id }) { - it[name] = user.name - it[domain] = user.domain - it[screenName] = user.screenName - it[description] = user.description - it[password] = user.password - it[inbox] = user.inbox - it[outbox] = user.outbox - it[url] = user.url - it[createdAt] = user.createdAt.toEpochMilli() - it[publicKey] = user.publicKey - it[privateKey] = user.privateKey - } + val singleOrNull = Users.select { id eq user.id }.singleOrNull() + if (singleOrNull == null) { + Users.insert { + it[id] = user.id + it[name] = user.name + it[domain] = user.domain + it[screenName] = user.screenName + it[description] = user.description + it[password] = user.password + it[inbox] = user.inbox + it[outbox] = user.outbox + it[url] = user.url + it[createdAt] = user.createdAt.toEpochMilli() + it[publicKey] = user.publicKey + it[privateKey] = user.privateKey + } + } else { + Users.update({ id eq user.id }) { + it[name] = user.name + it[domain] = user.domain + it[screenName] = user.screenName + it[description] = user.description + it[password] = user.password + it[inbox] = user.inbox + it[outbox] = user.outbox + it[url] = user.url + it[createdAt] = user.createdAt.toEpochMilli() + it[publicKey] = user.publicKey + it[privateKey] = user.privateKey } - return@query user } + return user } override suspend fun createFollower(id: Long, follower: Long) { - return query { - UsersFollowers.insert { - it[userId] = id - it[followerId] = follower - } + UsersFollowers.insert { + it[userId] = id + it[followerId] = follower } } override suspend fun findById(id: Long): User? { - return query { - Users.select { Users.id eq id }.map { - it.toUser() - }.singleOrNull() - } + return Users.select { Users.id eq id }.map { + it.toUser() + }.singleOrNull() } override suspend fun findByIds(ids: List): List { - return query { - Users.select { Users.id inList ids }.map { - it.toUser() - } + return Users.select { id inList ids }.map { + it.toUser() } } override suspend fun findByName(name: String): List { - return query { - Users.select { Users.name eq name }.map { - it.toUser() - } + return Users.select { Users.name eq name }.map { + it.toUser() } } - override suspend fun findByNameAndDomain(name: String, domain: String): User? { - return query { - Users.select { Users.name eq name and (Users.domain eq domain) }.singleOrNull()?.toUser() - } - } + override suspend fun findByNameAndDomain(name: String, domain: String): User? = + Users.select { Users.name eq name and (Users.domain eq domain) }.singleOrNull()?.toUser() override suspend fun findByDomain(domain: String): List { - return query { - Users.select { Users.domain eq domain }.map { - it.toUser() - } + return Users.select { Users.domain eq domain }.map { + it.toUser() } } override suspend fun findByNameAndDomains(names: List>): List { - return query { - val selectAll = Users.selectAll() - names.forEach { (name, domain) -> - selectAll.orWhere { Users.name eq name and (Users.domain eq domain) } - } - selectAll.map { it.toUser() } + val selectAll = Users.selectAll() + names.forEach { (name, domain) -> + selectAll.orWhere { Users.name eq name and (Users.domain eq domain) } } + return selectAll.map { it.toUser() } } - override suspend fun findByUrl(url: String): User? { - return query { - Users.select { Users.url eq url }.singleOrNull()?.toUser() - } - } + override suspend fun findByUrl(url: String): User? = Users.select { Users.url eq url }.singleOrNull()?.toUser() - override suspend fun findByUrls(urls: List): List { - return query { - Users.select { Users.url inList urls }.map { it.toUser() } - } - } + override suspend fun findByUrls(urls: List): List = + Users.select { url inList urls }.map { it.toUser() } override suspend fun findFollowersById(id: Long): List { - return query { - val followers = Users.alias("FOLLOWERS") - Users.innerJoin( - otherTable = UsersFollowers, - onColumn = { Users.id }, - otherColumn = { userId } + val followers = Users.alias("FOLLOWERS") + return Users.innerJoin( + otherTable = UsersFollowers, + onColumn = { Users.id }, + otherColumn = { userId } + ) + .innerJoin( + otherTable = followers, + onColumn = { followerId }, + otherColumn = { followers[Users.id] } ) - .innerJoin( - otherTable = followers, - onColumn = { UsersFollowers.followerId }, - otherColumn = { followers[Users.id] } + .slice( + followers.get(Users.id), + followers.get(name), + followers.get(domain), + followers.get(screenName), + followers.get(description), + followers.get(password), + followers.get(inbox), + followers.get(outbox), + followers.get(url), + followers.get(publicKey), + followers.get(privateKey), + followers.get(createdAt) + ) + .select { Users.id eq id } + .map { + User( + id = it[followers[Users.id]], + name = it[followers[name]], + domain = it[followers[domain]], + screenName = it[followers[screenName]], + description = it[followers[description]], + password = it[followers[password]], + inbox = it[followers[inbox]], + outbox = it[followers[outbox]], + url = it[followers[url]], + publicKey = it[followers[publicKey]], + privateKey = it[followers[privateKey]], + createdAt = Instant.ofEpochMilli(it[followers[createdAt]]) ) - .slice( - followers.get(Users.id), - followers.get(Users.name), - followers.get(Users.domain), - followers.get(Users.screenName), - followers.get(Users.description), - followers.get(Users.password), - followers.get(Users.inbox), - followers.get(Users.outbox), - followers.get(Users.url), - followers.get(Users.publicKey), - followers.get(Users.privateKey), - followers.get(Users.createdAt) - ) - .select { Users.id eq id } - .map { - User( - id = it[followers[Users.id]], - name = it[followers[Users.name]], - domain = it[followers[Users.domain]], - screenName = it[followers[Users.screenName]], - description = it[followers[Users.description]], - password = it[followers[Users.password]], - inbox = it[followers[Users.inbox]], - outbox = it[followers[Users.outbox]], - url = it[followers[Users.url]], - publicKey = it[followers[Users.publicKey]], - privateKey = it[followers[Users.privateKey]], - createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]) - ) - } - } + } } override suspend fun delete(id: Long) { - query { - Users.deleteWhere { Users.id.eq(id) } - } + Users.deleteWhere { Users.id.eq(id) } } override suspend fun deleteFollower(id: Long, follower: Long) { - query { - UsersFollowers.deleteWhere { (userId eq id).and(followerId eq follower) } - } + UsersFollowers.deleteWhere { (userId eq id).and(followerId eq follower) } } - override suspend fun findAll(): List { - return query { - Users.selectAll().map { it.toUser() } - } - } + override suspend fun findAll(): List = Users.selectAll().map { it.toUser() } - override suspend fun findAllByLimitAndByOffset(limit: Int, offset: Long): List { - return query { - Users.selectAll().limit(limit, offset).map { it.toUser() } - } - } + override suspend fun findAllByLimitAndByOffset(limit: Int, offset: Long): List = + Users.selectAll().limit(limit, offset).map { it.toUser() } override suspend fun nextId(): Long = idGenerateService.generateId() } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ServerInitialiseServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/ServerInitialiseServiceImpl.kt index 78bc0192..d89d0a75 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ServerInitialiseServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ServerInitialiseServiceImpl.kt @@ -16,19 +16,22 @@ class ServerInitialiseServiceImpl(private val metaRepository: IMetaRepository) : val logger: Logger = LoggerFactory.getLogger(ServerInitialiseServiceImpl::class.java) override suspend fun init() { - val savedMeta = metaRepository.get() - val implementationVersion = ServerUtil.getImplementationVersion() - if (wasInitialised(savedMeta).not()) { - logger.info("Start Initialise") - initialise(implementationVersion) - logger.info("Finish Initialise") - return + metaRepository.transaction { + + val savedMeta = metaRepository.get() + val implementationVersion = ServerUtil.getImplementationVersion() + if (wasInitialised(savedMeta).not()) { + logger.info("Start Initialise") + initialise(implementationVersion) + logger.info("Finish Initialise") + return@transaction + } + if (isVersionChanged(savedMeta!!)) { + logger.info("Version changed!! (${savedMeta.version} -> $implementationVersion)") + updateVersion(savedMeta, implementationVersion) + } } - if (isVersionChanged(savedMeta!!)) { - logger.info("Version changed!! (${savedMeta.version} -> $implementationVersion)") - updateVersion(savedMeta, implementationVersion) - } } private fun wasInitialised(meta: Meta?): Boolean { diff --git a/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt b/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt index aab82880..793e85df 100644 --- a/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt @@ -9,6 +9,7 @@ import kotlinx.coroutines.test.runTest import org.jetbrains.exposed.sql.Database import org.jetbrains.exposed.sql.SchemaUtils import org.jetbrains.exposed.sql.select +import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction import org.jetbrains.exposed.sql.transactions.transaction import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Assertions.assertIterableEquals @@ -41,111 +42,115 @@ class UserRepositoryTest { @Test fun `findFollowersById フォロワー一覧を取得`() = runTest { - val userRepository = UserRepository( - db, - object : IdGenerateService { - override suspend fun generateId(): Long { - TODO("Not yet implemented") + newSuspendedTransaction { + val userRepository = UserRepository( + db, + object : IdGenerateService { + override suspend fun generateId(): Long { + TODO("Not yet implemented") + } } + ) + val user = userRepository.save( + User( + id = 0L, + name = "test", + domain = "example.com", + screenName = "testUser", + description = "This user is test user.", + password = "https://example.com/inbox", + inbox = "", + outbox = "https://example.com/outbox", + url = "https://example.com", + publicKey = "", + createdAt = Instant.now(Clock.tickMillis(ZoneId.systemDefault())) + ) + ) + val follower = userRepository.save( + User( + id = 1L, + name = "follower", + domain = "follower.example.com", + screenName = "followerUser", + description = "This user is follower user.", + password = "", + inbox = "https://follower.example.com/inbox", + outbox = "https://follower.example.com/outbox", + url = "https://follower.example.com", + publicKey = "", + createdAt = Instant.now(Clock.tickMillis(ZoneId.systemDefault())) + ) + ) + val follower2 = userRepository.save( + User( + id = 3L, + name = "follower2", + domain = "follower2.example.com", + screenName = "followerUser2", + description = "This user is follower user 2.", + password = "", + inbox = "https://follower2.example.com/inbox", + outbox = "https://follower2.example.com/outbox", + url = "https://follower2.example.com", + publicKey = "", + createdAt = Instant.now(Clock.tickMillis(ZoneId.systemDefault())) + ) + ) + userRepository.createFollower(user.id, follower.id) + userRepository.createFollower(user.id, follower2.id) + userRepository.findFollowersById(user.id).let { + assertIterableEquals(listOf(follower, follower2), it) } - ) - val user = userRepository.save( - User( - id = 0L, - name = "test", - domain = "example.com", - screenName = "testUser", - description = "This user is test user.", - password = "https://example.com/inbox", - inbox = "", - outbox = "https://example.com/outbox", - url = "https://example.com", - publicKey = "", - createdAt = Instant.now(Clock.tickMillis(ZoneId.systemDefault())) - ) - ) - val follower = userRepository.save( - User( - id = 1L, - name = "follower", - domain = "follower.example.com", - screenName = "followerUser", - description = "This user is follower user.", - password = "", - inbox = "https://follower.example.com/inbox", - outbox = "https://follower.example.com/outbox", - url = "https://follower.example.com", - publicKey = "", - createdAt = Instant.now(Clock.tickMillis(ZoneId.systemDefault())) - ) - ) - val follower2 = userRepository.save( - User( - id = 3L, - name = "follower2", - domain = "follower2.example.com", - screenName = "followerUser2", - description = "This user is follower user 2.", - password = "", - inbox = "https://follower2.example.com/inbox", - outbox = "https://follower2.example.com/outbox", - url = "https://follower2.example.com", - publicKey = "", - createdAt = Instant.now(Clock.tickMillis(ZoneId.systemDefault())) - ) - ) - userRepository.createFollower(user.id, follower.id) - userRepository.createFollower(user.id, follower2.id) - userRepository.findFollowersById(user.id).let { - assertIterableEquals(listOf(follower, follower2), it) } } @Test fun `createFollower フォロワー追加`() = runTest { - val userRepository = UserRepository( - db, - object : IdGenerateService { - override suspend fun generateId(): Long { - TODO("Not yet implemented") + newSuspendedTransaction { + val userRepository = UserRepository( + db, + object : IdGenerateService { + override suspend fun generateId(): Long { + TODO("Not yet implemented") + } } - } - ) - val user = userRepository.save( - User( - 0L, - "test", - "example.com", - "testUser", - "This user is test user.", - "https://example.com/inbox", - "", - "https://example.com/outbox", - "https://example.com", - publicKey = "", - createdAt = Instant.now() ) - ) - val follower = userRepository.save( - User( - 1L, - "follower", - "follower.example.com", - "followerUser", - "This user is follower user.", - "", - "https://follower.example.com/inbox", - "https://follower.example.com/outbox", - "https://follower.example.com", - publicKey = "", - createdAt = Instant.now() + val user = userRepository.save( + User( + 0L, + "test", + "example.com", + "testUser", + "This user is test user.", + "https://example.com/inbox", + "", + "https://example.com/outbox", + "https://example.com", + publicKey = "", + createdAt = Instant.now() + ) ) - ) - userRepository.createFollower(user.id, follower.id) - transaction { + val follower = userRepository.save( + User( + 1L, + "follower", + "follower.example.com", + "followerUser", + "This user is follower user.", + "", + "https://follower.example.com/inbox", + "https://follower.example.com/outbox", + "https://follower.example.com", + publicKey = "", + createdAt = Instant.now() + ) + ) + userRepository.createFollower(user.id, follower.id) + val followerIds = UsersFollowers.select { UsersFollowers.userId eq user.id }.map { it[UsersFollowers.followerId] } assertIterableEquals(listOf(follower.id), followerIds) + } } } diff --git a/src/test/kotlin/dev/usbharu/hideout/service/ServerInitialiseServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/ServerInitialiseServiceImplTest.kt index 791e349a..269f2f07 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/ServerInitialiseServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/ServerInitialiseServiceImplTest.kt @@ -19,38 +19,48 @@ class ServerInitialiseServiceImplTest { val metaRepository = mock { onBlocking { get() } doReturn null onBlocking { save(any()) } doReturn Unit + onBlocking { + transaction(any Unit>()) + } doSuspendableAnswer { + (it.arguments[0] as suspend () -> Unit).invoke() + } } val serverInitialiseServiceImpl = ServerInitialiseServiceImpl(metaRepository) serverInitialiseServiceImpl.init() - verify(metaRepository,times(1)).save(any()) + verify(metaRepository, times(1)).save(any()) } @Test fun `init メタデータが存在して同じバージョンのときは何もしない`() = runTest { - val meta = Meta(ServerUtil.getImplementationVersion(), Jwt(UUID.randomUUID(),"aaafafd","afafasdf")) + val meta = Meta(ServerUtil.getImplementationVersion(), Jwt(UUID.randomUUID(), "aaafafd", "afafasdf")) val metaRepository = mock { onBlocking { get() } doReturn meta } val serverInitialiseServiceImpl = ServerInitialiseServiceImpl(metaRepository) serverInitialiseServiceImpl.init() - verify(metaRepository,times(0)).save(any()) + verify(metaRepository, times(0)).save(any()) } @Test fun `init メタデータが存在して違うバージョンのときはバージョンを変更する`() = runTest { - val meta = Meta("1.0.0", Jwt(UUID.randomUUID(),"aaafafd","afafasdf")) + val meta = Meta("1.0.0", Jwt(UUID.randomUUID(), "aaafafd", "afafasdf")) val metaRepository = mock { onBlocking { get() } doReturn meta onBlocking { save(any()) } doReturn Unit + onBlocking { + transaction(any Unit>()) + } doSuspendableAnswer { + (it.arguments[0] as suspend () -> Unit).invoke() + } } val serverInitialiseServiceImpl = ServerInitialiseServiceImpl(metaRepository) serverInitialiseServiceImpl.init() - verify(metaRepository,times(1)).save(any()) + verify(metaRepository, times(1)).save(any()) argumentCaptor { - verify(metaRepository,times(1)).save(capture()) - assertEquals(ServerUtil.getImplementationVersion(),firstValue.version) + verify(metaRepository, times(1)).save(capture()) + assertEquals(ServerUtil.getImplementationVersion(), firstValue.version) } } }