Skip to content

Commit

Permalink
Migrated JDBC components
Browse files Browse the repository at this point in the history
  • Loading branch information
deusaquilus committed Jul 7, 2024
1 parent a90d21e commit b5be729
Show file tree
Hide file tree
Showing 69 changed files with 100 additions and 38 deletions.
10 changes: 5 additions & 5 deletions scripts/setup_db_scripts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
# is the directory from where the docker-compose is called and everything under that directory
# is included in the image. So for example if docker compose in a directory 'foo' then
# everything under 'foo/*' is included inside including the DB setup scripts. We write these paths based on that.
export SQLITE_SCRIPT=terpal-sql-core/src/test/resources/db/sqlite-schema.sql
export MYSQL_SCRIPT=terpal-sql-core/src/test/resources/db/mysql-schema.sql
export SQL_SERVER_SCRIPT=terpal-sql-core/src/test/resources/db/sqlserver-schema.sql
export ORACLE_SCRIPT=terpal-sql-core/src/test/resources/db/oracle-schema.sql
export SQLITE_SCRIPT=terpal-sql-jdbc/src/test/resources/db/sqlite-schema.sql
export MYSQL_SCRIPT=terpal-sql-jdbc/src/test/resources/db/mysql-schema.sql
export SQL_SERVER_SCRIPT=terpal-sql-jdbc/src/test/resources/db/sqlserver-schema.sql
export ORACLE_SCRIPT=terpal-sql-jdbc/src/test/resources/db/oracle-schema.sql

function get_host() {
if [ -z "$1" ]; then
Expand All @@ -21,7 +21,7 @@ function get_host() {
function setup_sqlite() {
# DB File in terpal-sql
echo "Creating sqlite DB File"
DB_FILE=terpal-sql-core/terpal_test.db
DB_FILE=terpal-sql-jdbc/terpal_test.db
echo "Removing Previous sqlite DB File (if any)"
rm -f $DB_FILE
echo "Creating sqlite DB File"
Expand Down
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
includeBuild("terpal-sql-core")
includeBuild("terpal-sql-jdbc")

rootProject.name = "terpal-sql"

Expand Down
2 changes: 1 addition & 1 deletion terpal-sql-core/src/main/kotlin/io/exoquery/sql/Context.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ abstract class Context<Session, Database> {

abstract fun closeSession(session: Session): Unit
abstract fun isClosedSession(session: Session): Boolean
abstract internal suspend fun <T> runTransactionally(block: suspend CoroutineScope.() -> T): T
abstract suspend fun <T> runTransactionally(block: suspend CoroutineScope.() -> T): T

abstract val sessionKey: CoroutineContext.Key<CoroutineSession<Session>>

Expand Down
30 changes: 0 additions & 30 deletions terpal-sql-core/src/main/kotlin/io/exoquery/sql/RowDecoder.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.exoquery.sql

import io.exoquery.sql.jdbc.JdbcDecodingContext
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.descriptors.*
Expand Down Expand Up @@ -38,35 +37,6 @@ fun SerialDescriptor.verifyColumns(columns: List<ColumnInfo>): Unit {
}
}

class JdbcRowDecoder(
ctx: JdbcDecodingContext,
initialRowIndex: Int,
api: ApiDecoders<Connection, ResultSet>,
decoders: Set<SqlDecoder<Connection, ResultSet, out Any>>,
columnInfos: List<ColumnInfo>,
type: RowDecoderType,
endCallback: (Int) -> Unit
): RowDecoder<Connection, ResultSet>(ctx, initialRowIndex, api, decoders, columnInfos, type, endCallback) {

companion object {
operator fun invoke(
ctx: JdbcDecodingContext,
api: ApiDecoders<Connection, ResultSet>,
decoders: Set<SqlDecoder<Connection, ResultSet, out Any>>,
descriptor: SerialDescriptor
): JdbcRowDecoder {
fun metaColumnData(meta: ResultSetMetaData) =
(1..meta.columnCount).map { ColumnInfo(meta.getColumnName(it), meta.getColumnTypeName(it)) }
val metaColumns = metaColumnData(ctx.row.metaData)
descriptor.verifyColumns(metaColumns)
return JdbcRowDecoder(ctx, 1, api, decoders, metaColumns, RowDecoderType.Regular, {})
}
}

override fun cloneSelf(ctx: JdbcDecodingContext, initialRowIndex: Int, type: RowDecoderType, endCallback: (Int) -> Unit): RowDecoder<Connection, ResultSet> =
JdbcRowDecoder(ctx, initialRowIndex, api, decoders, columnInfos, type, endCallback)
}

sealed interface RowDecoderType {
data class Inline(val descriptor: SerialDescriptor): RowDecoderType
object Regular: RowDecoderType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package io.exoquery.sql.jdbc
import kotlin.coroutines.AbstractCoroutineContextElement
import kotlin.coroutines.CoroutineContext

internal class CoroutineTransaction(private var completed: Boolean = false) : AbstractCoroutineContextElement(CoroutineTransaction) {
class CoroutineTransaction(private var completed: Boolean = false) : AbstractCoroutineContextElement(CoroutineTransaction) {
companion object Key : CoroutineContext.Key<CoroutineTransaction>
val incomplete: Boolean
get() = !completed
Expand Down
46 changes: 46 additions & 0 deletions terpal-sql-jdbc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.jetbrains.kotlin.gradle.dsl.JvmTarget

plugins {
id("conventions")
id("publish")
id("io.exoquery.terpal-plugin") version "2.0.0-0.2.0"
kotlin("jvm") version "2.0.0"
kotlin("plugin.serialization") version "2.0.0"
}

val thisVersion = version

dependencies {
// Looks like it knows to do a project-dependency even if there is a version attached (i.e. I guess it ignores the version?)
api("io.exoquery:terpal-sql-core:${thisVersion}")

api("org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.2")
api("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")
// Optional by the user. This library provides certain utilities that enhance Hikari.
implementation("com.zaxxer:HikariCP:5.0.1")
implementation("com.typesafe:config:1.4.1")

testImplementation("io.exoquery:pprint-kotlin:2.0.2")
testImplementation("io.zonky.test:embedded-postgres:2.0.7")
testImplementation("mysql:mysql-connector-java:8.0.29")
testImplementation("com.microsoft.sqlserver:mssql-jdbc:7.4.1.jre11")
testImplementation("com.h2database:h2:2.2.224")
testImplementation("org.xerial:sqlite-jdbc:3.42.0.1")
testImplementation("com.oracle.ojdbc:ojdbc8:19.3.0.0")

testImplementation(kotlin("test"))
testImplementation("io.kotest:kotest-runner-junit5:5.9.1")
testImplementation("io.kotest.extensions:kotest-extensions-testcontainers:2.0.2")

testImplementation("org.testcontainers:mysql:1.19.8")
testImplementation("org.testcontainers:postgresql:1.19.8")
testImplementation("org.testcontainers:mssqlserver:1.19.8")
testImplementation("org.testcontainers:oracle-xe:1.19.8")

testApi(platform("io.zonky.test.postgres:embedded-postgres-binaries-bom:16.2.0"))
testImplementation("org.flywaydb:flyway-core:7.15.0") // corresponding to embedded-postgres
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1")
}
9 changes: 9 additions & 0 deletions terpal-sql-jdbc/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pluginManagement {
includeBuild("../build-logic")

repositories {
gradlePluginPortal()
mavenCentral()
mavenLocal()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ abstract class JdbcContext(override val database: DataSource): Context<Connectio
protected val JdbcCoroutineContext = object: CoroutineContext.Key<CoroutineSession<Connection>> {}
override val sessionKey: CoroutineContext.Key<CoroutineSession<Connection>> = JdbcCoroutineContext

override open internal suspend fun <T> runTransactionally(block: suspend CoroutineScope.() -> T): T {
override open suspend fun <T> runTransactionally(block: suspend CoroutineScope.() -> T): T {
val session = coroutineContext.get(sessionKey)?.session ?: error("No connection found")
session.runWithManualCommit {
val transaction = CoroutineTransaction()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.exoquery.sql.jdbc

import io.exoquery.sql.*
import kotlinx.serialization.descriptors.SerialDescriptor
import java.sql.Connection
import java.sql.ResultSet
import java.sql.ResultSetMetaData

class JdbcRowDecoder(
ctx: JdbcDecodingContext,
initialRowIndex: Int,
api: ApiDecoders<Connection, ResultSet>,
decoders: Set<SqlDecoder<Connection, ResultSet, out Any>>,
columnInfos: List<ColumnInfo>,
type: RowDecoderType,
endCallback: (Int) -> Unit
): RowDecoder<Connection, ResultSet>(ctx, initialRowIndex, api, decoders, columnInfos, type, endCallback) {

companion object {
operator fun invoke(
ctx: JdbcDecodingContext,
api: ApiDecoders<Connection, ResultSet>,
decoders: Set<SqlDecoder<Connection, ResultSet, out Any>>,
descriptor: SerialDescriptor
): JdbcRowDecoder {
fun metaColumnData(meta: ResultSetMetaData) =
(1..meta.columnCount).map { ColumnInfo(meta.getColumnName(it), meta.getColumnTypeName(it)) }
val metaColumns = metaColumnData(ctx.row.metaData)
descriptor.verifyColumns(metaColumns)
return JdbcRowDecoder(ctx, 1, api, decoders, metaColumns, RowDecoderType.Regular, {})
}
}

override fun cloneSelf(ctx: JdbcDecodingContext, initialRowIndex: Int, type: RowDecoderType, endCallback: (Int) -> Unit): RowDecoder<Connection, ResultSet> =
JdbcRowDecoder(ctx, initialRowIndex, api, decoders, columnInfos, type, endCallback)
}

0 comments on commit b5be729

Please sign in to comment.