Skip to content

Commit afd74d9

Browse files
committed
Use interfaces instead of data classes in api and fix other breaking changes
1 parent 77f90da commit afd74d9

File tree

11 files changed

+89
-114
lines changed

11 files changed

+89
-114
lines changed

api/src/main/kotlin/org/anvilpowered/catalyst/api/user/MinecraftUser.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,10 @@ import java.util.UUID
2828
*
2929
* Represents a single user of a game.
3030
*/
31-
data class MinecraftUser(
32-
override val uuid: UUID,
33-
val username: String,
34-
val ipAddress: String,
35-
val nickname: String? = null,
36-
) : DomainEntity {
31+
interface MinecraftUser : DomainEntity {
32+
val username: String
33+
val ipAddress: String
34+
val nickname: String?
3735

3836
data class CreateDto(
3937
val id: UUID,

api/src/main/kotlin/org/anvilpowered/catalyst/api/user/MinecraftUserRepository.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,5 @@ interface MinecraftUserRepository : MutableRepository<MinecraftUser, MinecraftUs
3737
}
3838

3939
suspend fun MinecraftUserRepository.getOnlineUser(player: Player): MinecraftUser.Online =
40-
getById(player.uniqueId)?.let { MinecraftUser.Online(it, player) }
40+
findById(player.uniqueId)?.let { MinecraftUser.Online(it, player) }
4141
?: throw IllegalStateException("User ${player.username} with id ${player.uniqueId} is not in the database!")

api/src/main/kotlin/org/anvilpowered/catalyst/api/user/User.kt

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,12 @@ import java.util.UUID
2929
*
3030
* Represents a single universal user across all games and platforms.
3131
*/
32-
data class User(
33-
override val uuid: UUID,
34-
val username: String,
35-
val email: String? = null,
36-
val discordUserId: Long? = null,
37-
val minecraftUserId: UUID? = null,
38-
) : DomainEntity, DomainFacet<User> {
32+
interface User : DomainEntity, DomainFacet<User> {
33+
34+
val username: String
35+
val email: String?
36+
val discordUserId: Long?
37+
val minecraftUser: MinecraftUser?
3938

4039
data class CreateDto(
4140
val username: String,
@@ -48,9 +47,6 @@ data class User(
4847
* Operations scoped within a platform context.
4948
*/
5049
interface PlatformScope {
51-
52-
val User.minecraftUser: MinecraftUser
53-
5450
val User.player: Player?
5551
}
5652

proxy/src/main/kotlin/org/anvilpowered/catalyst/proxy/CatalystVelocityPlugin.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ package org.anvilpowered.catalyst.proxy
2020

2121
import org.anvilpowered.anvil.core.config.Registry
2222
import org.anvilpowered.catalyst.api.config.CatalystKeys
23-
import org.anvilpowered.catalyst.proxy.db.user.MinecraftUserTable
24-
import org.anvilpowered.catalyst.proxy.db.user.UserTable
23+
import org.anvilpowered.catalyst.proxy.db.user.MinecraftUsers
24+
import org.anvilpowered.catalyst.proxy.db.user.Users
2525
import org.anvilpowered.catalyst.proxy.registrar.Registrar
2626
import org.apache.logging.log4j.Logger
2727
import org.jetbrains.exposed.sql.Database
@@ -65,8 +65,8 @@ class CatalystVelocityPlugin(
6565
logger.info("Creating tables...")
6666
transaction {
6767
SchemaUtils.createMissingTablesAndColumns(
68-
MinecraftUserTable,
69-
UserTable,
68+
MinecraftUsers,
69+
Users,
7070
)
7171
}
7272
logger.info("Finished creating tables.")

proxy/src/main/kotlin/org/anvilpowered/catalyst/proxy/chat/PrivateMessageService.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ class PrivateMessageService(
4444
private var replyMap = mutableMapOf<UUID, UUID>()
4545

4646
suspend fun sendMessage(source: Player, recipient: Player, content: Component) {
47-
val sourceUser = minecraftUserRepository.getById(source.uniqueId)?.let { MinecraftUser.Online(it, source) }
47+
val sourceUser = minecraftUserRepository.findById(source.uniqueId)?.let { MinecraftUser.Online(it, source) }
4848
?: throw IllegalStateException("User ${source.username} with id ${source.uniqueId} is not in the database!")
4949

50-
val recipientUser = minecraftUserRepository.getById(recipient.uniqueId)?.let { MinecraftUser.Online(it, recipient) }
50+
val recipientUser = minecraftUserRepository.findById(recipient.uniqueId)?.let { MinecraftUser.Online(it, recipient) }
5151
?: throw IllegalStateException("User ${recipient.username} with id ${recipient.uniqueId} is not in the database!")
5252

5353
val message = PrivateMessage(sourceUser, recipientUser, content)

proxy/src/main/kotlin/org/anvilpowered/catalyst/proxy/chat/builder/ChannelMessageBuilderImpl.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ internal class ChannelMessageBuilderImpl(
5555
}
5656

5757
override suspend fun userId(userId: UUID): ChannelMessage.Builder =
58-
user(requireNotNull(minecraftUserRepository.getById(userId)) { "Could not find user with id $userId" })
58+
user(requireNotNull(minecraftUserRepository.findById(userId)) { "Could not find user with id $userId" })
5959

6060
override fun channel(channel: ChatChannel): ChannelMessage.Builder {
6161
this.channel = channel

proxy/src/main/kotlin/org/anvilpowered/catalyst/proxy/command/MinecraftUserCommand.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ suspend fun CommandExecutionScope<CommandSource>.extractMinecraftUserSource(
8383
minecraftUserRepository: MinecraftUserRepository,
8484
): MinecraftUser {
8585
val player = extractPlayerSource()
86-
val user = minecraftUserRepository.getById(player.uniqueId)
86+
val user = minecraftUserRepository.findById(player.uniqueId)
8787
if (user == null) {
8888
context.source.sendMessage(
8989
Component.text()

proxy/src/main/kotlin/org/anvilpowered/catalyst/proxy/db/user/MinecraftUserRepositoryImpl.kt

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,64 +22,60 @@ import org.anvilpowered.anvil.core.db.MutableRepository
2222
import org.anvilpowered.anvil.core.db.SizedIterable
2323
import org.anvilpowered.catalyst.api.user.MinecraftUser
2424
import org.anvilpowered.catalyst.api.user.MinecraftUserRepository
25-
import org.anvilpowered.catalyst.api.user.User
2625
import org.anvilpowered.catalyst.proxy.db.wrap
2726
import org.apache.logging.log4j.Logger
2827
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
2928
import org.jetbrains.exposed.sql.deleteWhere
3029
import org.jetbrains.exposed.sql.mapLazy
3130
import org.jetbrains.exposed.sql.select
32-
import org.jetbrains.exposed.sql.selectAll
3331
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
3432
import org.jetbrains.exposed.sql.update
3533
import java.util.UUID
3634

37-
class MinecraftUserRepositoryImpl(
38-
private val logger: Logger,
39-
) : MinecraftUserRepository {
35+
class MinecraftUserRepositoryImpl(private val logger: Logger) : MinecraftUserRepository {
4036

4137
override suspend fun create(item: MinecraftUser.CreateDto): MinecraftUser = newSuspendedTransaction {
42-
val user = MinecraftUserEntity.new(item.id) {
38+
val user = DBMinecraftUser.new(item.id) {
4339
username = item.username
4440
ipAddress = item.ipAddress
45-
}.let { MinecraftUser(it.id.value, item.username, item.ipAddress) }
41+
}
4642

4743
logger.info("Created new MinecraftUser ${item.id} with data $item")
4844

4945
user
5046
}
5147

5248
override suspend fun put(item: MinecraftUser.CreateDto): MutableRepository.PutResult<MinecraftUser> = newSuspendedTransaction {
53-
val existingUser = getById(item.id)
49+
val existingUser = findById(item.id)
5450
if (existingUser == null) {
5551
// create a new MinecraftUser and accompanying User
56-
val newUser = MinecraftUserEntity.new(item.id) {
52+
val newUser = DBMinecraftUser.new(item.id) {
5753
username = item.username
5854
ipAddress = item.ipAddress
5955
}
6056

6157
// TODO: What if the user already exists?
6258

63-
val user = UserEntity.new {
59+
val user = DBUser.new {
6460
username = item.username
6561
minecraftUser = newUser
66-
}.let { User(it.id.value, item.username, minecraftUserId = item.id) }
62+
}
6763

6864
logger.info("Created new MinecraftUser ${item.id} with data $item and accompanying User ${user.uuid}")
6965

70-
MutableRepository.PutResult(MinecraftUser(newUser.id.value, item.username, item.ipAddress), created = true)
66+
MutableRepository.PutResult(newUser, created = true)
7167
} else {
7268
logger.info("Found existing MinecraftUser ${item.id} with username ${item.username}")
7369
// update the existing MinecraftUser
7470
if (existingUser.ipAddress != item.ipAddress) {
75-
MinecraftUserTable.update({ MinecraftUserTable.id eq item.id }) {
71+
MinecraftUsers.update({ MinecraftUsers.id eq item.id }) {
7672
logger.info("Updating IP address of MinecraftUser ${item.id} from ${existingUser.ipAddress} to ${item.ipAddress}")
7773
it[ipAddress] = item.ipAddress
7874
}
7975
}
8076

8177
if (existingUser.username != item.username) {
82-
MinecraftUserTable.update({ MinecraftUserTable.id eq item.id }) {
78+
MinecraftUsers.update({ MinecraftUsers.id eq item.id }) {
8379
logger.info("Updating username of MinecraftUser ${item.id} from ${existingUser.username} to ${item.username}")
8480
it[username] = item.username
8581
}
@@ -90,47 +86,43 @@ class MinecraftUserRepositoryImpl(
9086
}
9187

9288
override suspend fun getNickname(id: UUID): String? = newSuspendedTransaction {
93-
MinecraftUserTable.select { MinecraftUserTable.id eq id }
89+
MinecraftUsers.select { MinecraftUsers.id eq id }
9490
.firstOrNull()
95-
?.getOrNull(MinecraftUserTable.nickname)
91+
?.getOrNull(MinecraftUsers.nickname)
9692
}
9793

9894
override suspend fun updateNickname(id: UUID, nickname: String): Boolean = newSuspendedTransaction {
99-
MinecraftUserTable.update({ MinecraftUserTable.id eq id }) {
100-
it[MinecraftUserTable.nickname] = nickname
95+
MinecraftUsers.update({ MinecraftUsers.id eq id }) {
96+
it[MinecraftUsers.nickname] = nickname
10197
} > 0
10298
}
10399

104100
override suspend fun deleteNickname(id: UUID): Boolean = newSuspendedTransaction {
105-
MinecraftUserTable.update({ MinecraftUserTable.id eq id }) {
101+
MinecraftUsers.update({ MinecraftUsers.id eq id }) {
106102
it[nickname] = null
107103
} > 0
108104
}
109105

110106
override suspend fun getAllUsernames(startWith: String): SizedIterable<String> = newSuspendedTransaction {
111-
MinecraftUserEntity.find { MinecraftUserTable.username like "$startWith%" }.mapLazy { it.username }
107+
DBMinecraftUser.find { MinecraftUsers.username like "$startWith%" }.mapLazy { it.username }
112108
}.wrap()
113109

114110
override suspend fun getByUsername(username: String): MinecraftUser? = newSuspendedTransaction {
115-
MinecraftUserTable.selectAll().where { MinecraftUserTable.username eq username }
116-
.firstOrNull()
117-
?.toMinecraftUser()
111+
DBMinecraftUser.find { MinecraftUsers.username eq username }.firstOrNull()
118112
}
119113

120114
override suspend fun countAll(): Long = newSuspendedTransaction {
121-
MinecraftUserEntity.all().count()
115+
DBMinecraftUser.all().count()
122116
}
123117

124118
override suspend fun exists(id: UUID): Boolean =
125-
newSuspendedTransaction { MinecraftUserEntity.findById(id) != null }
119+
newSuspendedTransaction { DBMinecraftUser.findById(id) != null }
126120

127-
override suspend fun getById(id: UUID): MinecraftUser? = newSuspendedTransaction {
128-
MinecraftUserTable.select { MinecraftUserTable.id eq id }
129-
.firstOrNull()
130-
?.toMinecraftUser()
121+
override suspend fun findById(id: UUID): MinecraftUser? = newSuspendedTransaction {
122+
DBMinecraftUser.findById(id)
131123
}
132124

133125
override suspend fun deleteById(id: UUID): Boolean = newSuspendedTransaction {
134-
MinecraftUserTable.deleteWhere { MinecraftUserTable.id eq id } > 0
126+
MinecraftUsers.deleteWhere { MinecraftUsers.id eq id } > 0
135127
}
136128
}

proxy/src/main/kotlin/org/anvilpowered/catalyst/proxy/db/user/MinecraftUserTable.kt renamed to proxy/src/main/kotlin/org/anvilpowered/catalyst/proxy/db/user/MinecraftUsers.kt

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,19 @@ import org.jetbrains.exposed.dao.UUIDEntity
2323
import org.jetbrains.exposed.dao.UUIDEntityClass
2424
import org.jetbrains.exposed.dao.id.EntityID
2525
import org.jetbrains.exposed.dao.id.UUIDTable
26-
import org.jetbrains.exposed.sql.ResultRow
2726
import java.util.UUID
2827

29-
internal object MinecraftUserTable : UUIDTable("catalyst_minecraft_users") {
28+
internal object MinecraftUsers : UUIDTable("catalyst_minecraft_users") {
3029
val username = varchar("username", 255).uniqueIndex()
3130
val ipAddress = varchar("ip_address", 255)
3231
val nickname = varchar("nickname", 255).nullable()
3332
}
3433

35-
internal class MinecraftUserEntity(id: EntityID<UUID>) : UUIDEntity(id) {
36-
var username: String by MinecraftUserTable.username
37-
var ipAddress: String by MinecraftUserTable.ipAddress
38-
var nickname: String? by MinecraftUserTable.nickname
34+
internal class DBMinecraftUser(id: EntityID<UUID>) : UUIDEntity(id), MinecraftUser {
35+
override val uuid: UUID = id.value
36+
override var username: String by MinecraftUsers.username
37+
override var ipAddress: String by MinecraftUsers.ipAddress
38+
override var nickname: String? by MinecraftUsers.nickname
3939

40-
companion object : UUIDEntityClass<MinecraftUserEntity>(MinecraftUserTable)
40+
companion object : UUIDEntityClass<DBMinecraftUser>(MinecraftUsers)
4141
}
42-
43-
internal fun ResultRow.toMinecraftUser() = MinecraftUser(
44-
uuid = this[MinecraftUserTable.id].value,
45-
username = this[MinecraftUserTable.username],
46-
ipAddress = this[MinecraftUserTable.ipAddress],
47-
nickname = this[MinecraftUserTable.nickname],
48-
)

proxy/src/main/kotlin/org/anvilpowered/catalyst/proxy/db/user/UserRepositoryImpl.kt

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,33 +23,26 @@ import org.anvilpowered.anvil.core.db.Pagination
2323
import org.anvilpowered.catalyst.api.user.User
2424
import org.anvilpowered.catalyst.api.user.UserRepository
2525
import org.apache.logging.log4j.Logger
26-
import org.jetbrains.exposed.sql.Op
27-
import org.jetbrains.exposed.sql.SqlExpressionBuilder
2826
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
2927
import org.jetbrains.exposed.sql.deleteWhere
30-
import org.jetbrains.exposed.sql.insert
31-
import org.jetbrains.exposed.sql.select
3228
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
3329
import org.jetbrains.exposed.sql.update
3430
import java.util.UUID
3531

36-
class UserRepositoryImpl(
37-
private val logger: Logger,
38-
) : UserRepository {
32+
class UserRepositoryImpl(private val logger: Logger) : UserRepository {
3933
override suspend fun paginate(): Pagination<User> {
4034
TODO("Not yet implemented")
4135
}
4236

4337
override suspend fun create(item: User.CreateDto): User = newSuspendedTransaction {
44-
val result = UserTable.insert {
45-
it[username] = item.username
46-
it[email] = item.email
47-
it[discordUserId] = item.discordUserId
48-
it[minecraftUserId] = item.minecraftUserId
49-
}.resultedValues
38+
val itemMinecraftUser = item.minecraftUserId?.let { id -> DBMinecraftUser.findById(id) }
5039

51-
val user = checkNotNull(result) { "Failed to create User ${item.username}" }
52-
.single().toUser()
40+
val user = DBUser.new {
41+
username = item.username
42+
email = item.email
43+
discordUserId = item.discordUserId
44+
minecraftUser = itemMinecraftUser
45+
}
5346

5447
logger.info("Created new User ${user.uuid} with data $item")
5548

@@ -65,22 +58,22 @@ class UserRepositoryImpl(
6558
logger.info("Found existing User ${existingUser.uuid} with username ${existingUser.username}")
6659

6760
if (existingUser.email != item.email) {
68-
UserTable.update({ UserTable.id eq existingUser.uuid }) {
61+
Users.update({ Users.id eq existingUser.uuid }) {
6962
logger.info("Updating email for User ${existingUser.uuid} from ${existingUser.email} to ${item.email}")
7063
it[email] = item.email
7164
}
7265
}
7366

7467
if (existingUser.discordUserId != item.discordUserId) {
75-
UserTable.update({ UserTable.id eq existingUser.uuid }) {
68+
Users.update({ Users.id eq existingUser.uuid }) {
7669
logger.info("Updating discordUserId for User ${existingUser.uuid} from ${existingUser.discordUserId} to ${item.discordUserId}")
7770
it[discordUserId] = item.discordUserId
7871
}
7972
}
8073

81-
if (existingUser.minecraftUserId != item.minecraftUserId) {
82-
UserTable.update({ UserTable.id eq existingUser.uuid }) {
83-
logger.info("Updating minecraftUserId for User ${existingUser.uuid} from ${existingUser.minecraftUserId} to ${item.minecraftUserId}")
74+
if (existingUser.minecraftUser?.uuid != item.minecraftUserId) {
75+
Users.update({ Users.id eq existingUser.uuid }) {
76+
logger.info("Updating minecraftUserId for User ${existingUser.uuid} from ${existingUser.minecraftUser?.uuid} to ${item.minecraftUserId}")
8477
it[minecraftUserId] = item.minecraftUserId
8578
}
8679
}
@@ -89,24 +82,33 @@ class UserRepositoryImpl(
8982
}
9083
}
9184

92-
private suspend fun getOneWhere(condition: SqlExpressionBuilder.() -> Op<Boolean>): User? = newSuspendedTransaction {
93-
UserTable.select { condition() }.firstOrNull()?.toUser()
85+
override suspend fun findById(id: UUID): User? = newSuspendedTransaction {
86+
DBUser.findById(id)
87+
}
88+
89+
override suspend fun getByUsername(username: String): User? = newSuspendedTransaction {
90+
DBUser.find { Users.username eq username }.firstOrNull()
9491
}
9592

96-
override suspend fun getById(id: UUID): User? = getOneWhere { UserTable.id eq id }
97-
override suspend fun getByUsername(username: String): User? = getOneWhere { UserTable.username eq username }
98-
override suspend fun getByEmail(email: String): User? = getOneWhere { UserTable.email eq email }
99-
override suspend fun getByDiscordUserId(id: Long): User? = getOneWhere { UserTable.discordUserId eq id }
93+
override suspend fun getByEmail(email: String): User? = newSuspendedTransaction {
94+
DBUser.find { Users.email eq email }.firstOrNull()
95+
}
10096

101-
override suspend fun getByMinecraftUserId(id: UUID): User? = getOneWhere { UserTable.minecraftUserId eq id }
97+
override suspend fun getByDiscordUserId(id: Long): User? = newSuspendedTransaction {
98+
DBUser.find { Users.discordUserId eq id }.firstOrNull()
99+
}
100+
101+
override suspend fun getByMinecraftUserId(id: UUID): User? = newSuspendedTransaction {
102+
DBUser.find { Users.minecraftUserId eq id }.firstOrNull()
103+
}
102104

103-
override suspend fun countAll(): Long = newSuspendedTransaction { UserEntity.all().count() }
105+
override suspend fun countAll(): Long = newSuspendedTransaction { DBUser.all().count() }
104106

105107
override suspend fun exists(id: UUID): Boolean = newSuspendedTransaction {
106-
UserEntity.findById(id) != null
108+
DBUser.findById(id) != null
107109
}
108110

109111
override suspend fun deleteById(id: UUID): Boolean = newSuspendedTransaction {
110-
UserTable.deleteWhere { UserTable.id eq id } > 0
112+
Users.deleteWhere { Users.id eq id } > 0
111113
}
112114
}

0 commit comments

Comments
 (0)