diff --git a/.gitignore b/.gitignore index b1dff0d..108d567 100644 --- a/.gitignore +++ b/.gitignore @@ -5,10 +5,7 @@ build/ !**/src/test/**/build/ ### IntelliJ IDEA ### -.idea/modules.xml -.idea/jarRepositories.xml -.idea/compiler.xml -.idea/libraries/ +.idea/ *.iws *.iml *.ipr diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index bbc40ac..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Environment-dependent path to Maven home directory -/mavenHomeManager.xml -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml -/inspectionProfiles/Project_Default.xml -copilot* diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml deleted file mode 100644 index 4a53bee..0000000 --- a/.idea/AndroidProjectSystem.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/copilot.data.migration.agent.xml b/.idea/copilot.data.migration.agent.xml deleted file mode 100644 index 4ea72a9..0000000 --- a/.idea/copilot.data.migration.agent.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/copilot.data.migration.edit.xml b/.idea/copilot.data.migration.edit.xml deleted file mode 100644 index 8648f94..0000000 --- a/.idea/copilot.data.migration.edit.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml deleted file mode 100644 index a3395a8..0000000 --- a/.idea/dataSources.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - postgresql - true - org.postgresql.Driver - jdbc:postgresql://localhost:5432/postgres - - - - - - $ProjectFileDir$ - - - \ No newline at end of file diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml deleted file mode 100644 index c8fc930..0000000 --- a/.idea/dictionaries/project.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - Krescent - averix - checkpointed - chrono - helightdev - krescent - kurrent - overblock - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 7388394..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml deleted file mode 100644 index ebd2e7b..0000000 --- a/.idea/kotlinc.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 0b3edfb..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml deleted file mode 100644 index 97b2417..0000000 --- a/.idea/sqldialects.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 25264bd..3651160 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,14 +1,14 @@ [versions] -kotlin = "2.1.20" +kotlin = "2.3.0" kotlinxDatetime = "0.6.1" kotlinxSerialization = "1.7.3" kotlinxCoroutines = "1.10.2" kurrentClient = "1.0.1" orgReactiveStream = "1.0.4" mongoDriver = "5.5.0" -testContainers = "1.21.4" -exposed = "0.59.0" -postgresql = "42.7.3" +testContainers = "1.21.0" +exposed = "1.3.0" +postgresql = "42.7.11" slf4j = "2.0.9" redisson = "3.52.0" diff --git a/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedCheckpointStorage.kt b/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedCheckpointStorage.kt index 307ea12..62b1ed3 100644 --- a/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedCheckpointStorage.kt +++ b/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedCheckpointStorage.kt @@ -3,8 +3,11 @@ package dev.helight.krescent.exposed import dev.helight.krescent.checkpoint.CheckpointBucket import dev.helight.krescent.checkpoint.CheckpointStorage import dev.helight.krescent.checkpoint.StoredCheckpoint -import org.jetbrains.exposed.sql.* -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import kotlinx.datetime.toDeprecatedInstant +import kotlinx.datetime.toStdlibInstant +import org.jetbrains.exposed.v1.core.eq +import org.jetbrains.exposed.v1.jdbc.* +import kotlin.time.ExperimentalTime class ExposedCheckpointStorage( val database: Database, @@ -15,23 +18,25 @@ class ExposedCheckpointStorage( table.create(database) } + @OptIn(ExperimentalTime::class) override suspend fun storeCheckpoint(checkpoint: StoredCheckpoint): Unit = jdbcSuspendTransaction(database) { table.upsert(keys = arrayOf(table.namespace)) { it[namespace] = checkpoint.namespace it[position] = checkpoint.position - it[timestamp] = checkpoint.timestamp + it[timestamp] = checkpoint.timestamp.toStdlibInstant() it[version] = checkpoint.version it[data] = checkpoint.data.encodeToByteArray() } } + @OptIn(ExperimentalTime::class) override suspend fun getLatestCheckpoint(namespace: String): StoredCheckpoint? = jdbcSuspendTransaction(database) { table.selectAll().where { table.namespace eq namespace }.firstOrNull()?.let { StoredCheckpoint( namespace = it[table.namespace], position = it[table.position], version = it[table.version], - timestamp = it[table.timestamp], + timestamp = it[table.timestamp].toDeprecatedInstant(), data = CheckpointBucket.fromByteArray(it[table.data]) ) } diff --git a/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedEventPublisher.kt b/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedEventPublisher.kt index 071810d..35dd328 100644 --- a/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedEventPublisher.kt +++ b/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedEventPublisher.kt @@ -2,24 +2,26 @@ package dev.helight.krescent.exposed import dev.helight.krescent.event.EventMessage import dev.helight.krescent.source.EventPublisher -import org.jetbrains.exposed.sql.Database -import org.jetbrains.exposed.sql.insert -import java.util.* +import kotlinx.datetime.toStdlibInstant +import org.jetbrains.exposed.v1.jdbc.Database +import org.jetbrains.exposed.v1.jdbc.insert import kotlin.time.ExperimentalTime +import kotlin.uuid.ExperimentalUuidApi +import kotlin.uuid.Uuid class ExposedEventPublisher( val database: Database, val streamId: String, val table: KrescentEventLogTable = KrescentEventLogTable(), ) : EventPublisher { - @OptIn(ExperimentalTime::class) + @OptIn(ExperimentalTime::class, ExperimentalUuidApi::class) override suspend fun publish(event: EventMessage) { jdbcSuspendTransaction(database) { table.insert { - it[uid] = UUID.fromString(event.id) + it[uid] = Uuid.parse(event.id) it[streamId] = this@ExposedEventPublisher.streamId it[type] = event.type - it[timestamp] = event.timestamp + it[timestamp] = event.timestamp.toStdlibInstant() it[data] = event.payload } } diff --git a/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedEventSource.kt b/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedEventSource.kt index 48dba78..2c14e94 100644 --- a/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedEventSource.kt +++ b/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedEventSource.kt @@ -5,13 +5,21 @@ import dev.helight.krescent.source.StoredEventSource import dev.helight.krescent.source.StreamingToken import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.channelFlow -import org.jetbrains.exposed.sql.* -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -import org.jetbrains.exposed.sql.SqlExpressionBuilder.like -import org.jetbrains.exposed.sql.SqlExpressionBuilder.regexp -import org.jetbrains.exposed.sql.json.contains +import kotlinx.datetime.toDeprecatedInstant +import org.jetbrains.exposed.v1.core.ResultRow +import org.jetbrains.exposed.v1.core.SortOrder +import org.jetbrains.exposed.v1.core.eq +import org.jetbrains.exposed.v1.core.inList +import org.jetbrains.exposed.v1.core.like +import org.jetbrains.exposed.v1.core.regexp +import org.jetbrains.exposed.v1.jdbc.Database +import org.jetbrains.exposed.v1.jdbc.Query +import org.jetbrains.exposed.v1.jdbc.andWhere +import org.jetbrains.exposed.v1.jdbc.select +import org.jetbrains.exposed.v1.json.contains import kotlin.math.min import kotlin.time.ExperimentalTime +import kotlin.uuid.ExperimentalUuidApi @OptIn(ExperimentalTime::class) class ExposedEventSource( @@ -67,12 +75,13 @@ class ExposedEventSource( } } + @OptIn(ExperimentalUuidApi::class) private fun mapRowToPair(row: ResultRow): Pair { val event = EventMessage( id = row[table.uid].toString(), type = row[table.type], - timestamp = row[table.timestamp], - payload = row[table.data], + timestamp = row[table.timestamp].toDeprecatedInstant(), + payload = row[table.data] , ) val token = ExposedStreamingToken.PositionToken(row[table.id].value) return event to token diff --git a/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedStreamingToken.kt b/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedStreamingToken.kt index 9aafb41..cd6c8c9 100644 --- a/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedStreamingToken.kt +++ b/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedStreamingToken.kt @@ -1,9 +1,10 @@ package dev.helight.krescent.exposed import dev.helight.krescent.source.StreamingToken -import org.jetbrains.exposed.sql.Query -import org.jetbrains.exposed.sql.andWhere -import org.jetbrains.exposed.sql.selectAll +import org.jetbrains.exposed.v1.core.greater +import org.jetbrains.exposed.v1.jdbc.Query +import org.jetbrains.exposed.v1.jdbc.andWhere +import org.jetbrains.exposed.v1.jdbc.selectAll sealed class ExposedStreamingToken : StreamingToken { diff --git a/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedTableProjector.kt b/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedTableProjector.kt index a57f2fd..32fe93a 100644 --- a/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedTableProjector.kt +++ b/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/ExposedTableProjector.kt @@ -13,7 +13,11 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromJsonElement import kotlinx.serialization.json.encodeToJsonElement -import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.v1.core.Table +import org.jetbrains.exposed.v1.core.Transaction +import org.jetbrains.exposed.v1.jdbc.Database +import org.jetbrains.exposed.v1.jdbc.SchemaUtils +import org.jetbrains.exposed.v1.jdbc.exists import java.util.logging.Logger class ExposedTableProjector( diff --git a/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/KrescentEventLogTable.kt b/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/KrescentEventLogTable.kt index 3421ac0..e6e0c22 100644 --- a/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/KrescentEventLogTable.kt +++ b/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/KrescentEventLogTable.kt @@ -4,22 +4,27 @@ package dev.helight.krescent.exposed import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement -import org.jetbrains.exposed.dao.id.LongIdTable -import org.jetbrains.exposed.sql.Database -import org.jetbrains.exposed.sql.SchemaUtils -import org.jetbrains.exposed.sql.Table -import org.jetbrains.exposed.sql.json.json -import org.jetbrains.exposed.sql.json.jsonb -import org.jetbrains.exposed.sql.kotlin.datetime.KotlinInstantColumnType -import org.jetbrains.exposed.sql.upsert +import org.jetbrains.exposed.v1.core.Table +import org.jetbrains.exposed.v1.core.dao.id.LongIdTable +import org.jetbrains.exposed.v1.core.eq +import org.jetbrains.exposed.v1.datetime.KotlinInstantColumnType +import org.jetbrains.exposed.v1.datetime.timestamp +import org.jetbrains.exposed.v1.jdbc.Database +import org.jetbrains.exposed.v1.jdbc.SchemaUtils +import org.jetbrains.exposed.v1.jdbc.select +import org.jetbrains.exposed.v1.jdbc.upsert +import org.jetbrains.exposed.v1.json.json +import org.jetbrains.exposed.v1.json.jsonb import kotlin.time.ExperimentalTime +import kotlin.uuid.ExperimentalUuidApi @OptIn(ExperimentalTime::class) class KrescentEventLogTable(tableName: String = "krescent") : LongIdTable(tableName) { + @OptIn(ExperimentalUuidApi::class) val uid = uuid("uuid").uniqueIndex() val streamId = text("streamId").index() val type = text("type").index() - val timestamp = registerColumn("timestamp", KotlinInstantColumnType()).index() + val timestamp = timestamp("timestamp").index() val data = jsonb("data", { Json.encodeToString(it) diff --git a/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/Utils.kt b/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/Utils.kt index 353788a..71ce6ef 100644 --- a/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/Utils.kt +++ b/krescent-exposed/src/main/kotlin/dev/helight/krescent/exposed/Utils.kt @@ -1,10 +1,10 @@ package dev.helight.krescent.exposed import kotlinx.coroutines.coroutineScope -import org.jetbrains.exposed.sql.Database -import org.jetbrains.exposed.sql.Transaction -import org.jetbrains.exposed.sql.transactions.TransactionManager -import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction +import org.jetbrains.exposed.v1.core.Transaction +import org.jetbrains.exposed.v1.jdbc.Database +import org.jetbrains.exposed.v1.jdbc.transactions.TransactionManager +import org.jetbrains.exposed.v1.jdbc.transactions.suspendTransaction internal suspend fun jdbcSuspendTransaction( database: Database, @@ -16,7 +16,7 @@ internal suspend fun jdbcSuspendTransaction( ?.takeIf { it.db == database } ?.let { return@coroutineScope statement.invoke(it) } - return@coroutineScope newSuspendedTransaction(db = database) { - statement.invoke(this@newSuspendedTransaction) + return@coroutineScope suspendTransaction(db = database) { + statement.invoke(this@suspendTransaction) } } \ No newline at end of file diff --git a/krescent-exposed/src/test/kotlin/dev/helight/krescent/exposed/ExposedTableProjectorTest.kt b/krescent-exposed/src/test/kotlin/dev/helight/krescent/exposed/ExposedTableProjectorTest.kt index 8c2a14d..a88351c 100644 --- a/krescent-exposed/src/test/kotlin/dev/helight/krescent/exposed/ExposedTableProjectorTest.kt +++ b/krescent-exposed/src/test/kotlin/dev/helight/krescent/exposed/ExposedTableProjectorTest.kt @@ -16,9 +16,16 @@ import kotlinx.coroutines.runBlocking import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.serialization.Serializable -import org.jetbrains.exposed.sql.* -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -import org.jetbrains.exposed.sql.transactions.transaction +import org.jetbrains.exposed.v1.core.Table +import org.jetbrains.exposed.v1.core.eq +import org.jetbrains.exposed.v1.jdbc.Database +import org.jetbrains.exposed.v1.jdbc.SchemaUtils +import org.jetbrains.exposed.v1.jdbc.deleteWhere +import org.jetbrains.exposed.v1.jdbc.select +import org.jetbrains.exposed.v1.jdbc.selectAll +import org.jetbrains.exposed.v1.jdbc.transactions.transaction +import org.jetbrains.exposed.v1.jdbc.update +import org.jetbrains.exposed.v1.jdbc.upsert import org.junit.jupiter.api.assertThrows import org.testcontainers.containers.GenericContainer import org.testcontainers.junit.jupiter.Container @@ -27,6 +34,7 @@ import java.time.Duration import java.util.* import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.time.Duration.Companion.milliseconds @Testcontainers class ExposedTableProjectorTest { @@ -59,7 +67,7 @@ class ExposedTableProjectorTest { table.create(db) try { this.block(db, table) - delay(300) + delay(300.milliseconds) } finally { runCatching { table.drop(db) } dropProjection() diff --git a/krescent-exposed/src/test/kotlin/dev/helight/krescent/exposed/PostgresCheckpointStorage.kt b/krescent-exposed/src/test/kotlin/dev/helight/krescent/exposed/PostgresCheckpointStorage.kt index 427b4e1..589a28f 100644 --- a/krescent-exposed/src/test/kotlin/dev/helight/krescent/exposed/PostgresCheckpointStorage.kt +++ b/krescent-exposed/src/test/kotlin/dev/helight/krescent/exposed/PostgresCheckpointStorage.kt @@ -5,12 +5,13 @@ import dev.helight.krescent.test.CheckpointStoreContract import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking -import org.jetbrains.exposed.sql.Database +import org.jetbrains.exposed.v1.jdbc.Database import org.testcontainers.containers.GenericContainer import org.testcontainers.junit.jupiter.Container import org.testcontainers.junit.jupiter.Testcontainers import java.time.Duration import java.util.* +import kotlin.time.Duration.Companion.milliseconds @Testcontainers class PostgresCheckpointStorage : CheckpointStoreContract { @@ -32,6 +33,7 @@ class PostgresCheckpointStorage : CheckpointStoreContract { user = "root", password = "example" ) + } override fun withCheckpointStorage(block: suspend CoroutineScope.(CheckpointStorage) -> Unit) = runBlocking { @@ -42,7 +44,7 @@ class PostgresCheckpointStorage : CheckpointStoreContract { try { val storage = ExposedCheckpointStorage(db, table) this.block(storage) - delay(300) + delay(300.milliseconds) } finally { runCatching { table.drop(db) } } diff --git a/krescent-exposed/src/test/kotlin/dev/helight/krescent/exposed/PostgresStreamingSource.kt b/krescent-exposed/src/test/kotlin/dev/helight/krescent/exposed/PostgresStreamingSource.kt index fc78943..2c6aac3 100644 --- a/krescent-exposed/src/test/kotlin/dev/helight/krescent/exposed/PostgresStreamingSource.kt +++ b/krescent-exposed/src/test/kotlin/dev/helight/krescent/exposed/PostgresStreamingSource.kt @@ -14,7 +14,7 @@ import kotlinx.coroutines.runBlocking import kotlinx.serialization.Serializable import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.put -import org.jetbrains.exposed.sql.Database +import org.jetbrains.exposed.v1.jdbc.Database import org.testcontainers.containers.GenericContainer import org.testcontainers.junit.jupiter.Container import org.testcontainers.junit.jupiter.Testcontainers @@ -22,6 +22,7 @@ import java.time.Duration import java.util.* import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.time.Duration.Companion.milliseconds @Testcontainers class PostgresStreamingSource : StreamingEventSourceContract { @@ -52,7 +53,7 @@ class PostgresStreamingSource : StreamingEventSourceContract { table.create(db) try { this.block(db, table) - delay(300) + delay(300.milliseconds) } finally { runCatching { table.drop(db) } } diff --git a/krescent-postgres/src/main/kotlin/dev/helight/krescent/postgres/PostgresLock.kt b/krescent-postgres/src/main/kotlin/dev/helight/krescent/postgres/PostgresLock.kt index 7360d26..026dcfb 100644 --- a/krescent-postgres/src/main/kotlin/dev/helight/krescent/postgres/PostgresLock.kt +++ b/krescent-postgres/src/main/kotlin/dev/helight/krescent/postgres/PostgresLock.kt @@ -5,8 +5,8 @@ import dev.helight.krescent.synchronization.KrescentLockProvider import kotlinx.coroutines.* import kotlinx.coroutines.selects.onTimeout import kotlinx.coroutines.selects.select -import org.jetbrains.exposed.sql.Database -import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction +import org.jetbrains.exposed.v1.jdbc.Database +import org.jetbrains.exposed.v1.jdbc.transactions.suspendTransaction import java.nio.ByteBuffer import java.security.MessageDigest import java.util.* @@ -60,7 +60,7 @@ private fun launchPostgresLockJob( ): Deferred { val started = CompletableDeferred() CoroutineScope(Dispatchers.IO).launch { - newSuspendedTransaction(db = database) { + suspendTransaction(db = database) { try { val setLockTimeout = when (timeout) { Duration.INFINITE -> "SET LOCAL lock_timeout = 0" @@ -75,7 +75,7 @@ private fun launchPostgresLockJob( started.complete(Unit) } catch (e: Exception) { started.completeExceptionally(e) - return@newSuspendedTransaction + return@suspendTransaction } select { releaser.onAwait {} diff --git a/krescent-postgres/src/test/kotlin/dev/helight/krescent/postgres/PostgresLock.kt b/krescent-postgres/src/test/kotlin/dev/helight/krescent/postgres/PostgresLock.kt index 9435ade..1c60198 100644 --- a/krescent-postgres/src/test/kotlin/dev/helight/krescent/postgres/PostgresLock.kt +++ b/krescent-postgres/src/test/kotlin/dev/helight/krescent/postgres/PostgresLock.kt @@ -2,7 +2,7 @@ package dev.helight.krescent.postgres import dev.helight.krescent.synchronization.KrescentLockProvider import dev.helight.krescent.test.KrescentLockProviderContract -import org.jetbrains.exposed.sql.Database +import org.jetbrains.exposed.v1.jdbc.Database import org.testcontainers.containers.GenericContainer import org.testcontainers.junit.jupiter.Container import org.testcontainers.junit.jupiter.Testcontainers