Merge pull request #65 from CommanderTvis/commandertvis/table
Exposed based Table implementation
This commit is contained in:
commit
d769b0d389
15
dataforge-exposed/build.gradle.kts
Normal file
15
dataforge-exposed/build.gradle.kts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
plugins {
|
||||||
|
id("ru.mipt.npm.gradle.jvm")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api("org.jetbrains.exposed:exposed-core:0.31.1")
|
||||||
|
testImplementation("org.jetbrains.exposed:exposed-jdbc:0.31.1")
|
||||||
|
testImplementation("com.h2database:h2:1.4.200")
|
||||||
|
testImplementation("org.slf4j:slf4j-simple:1.7.30")
|
||||||
|
api(project(":dataforge-tables"))
|
||||||
|
}
|
||||||
|
|
||||||
|
readme {
|
||||||
|
maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
package space.kscience.dataforge.exposed
|
||||||
|
|
||||||
|
import org.jetbrains.exposed.dao.id.EntityID
|
||||||
|
import org.jetbrains.exposed.dao.id.IntIdTable
|
||||||
|
import org.jetbrains.exposed.sql.*
|
||||||
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
import space.kscience.dataforge.meta.Meta
|
||||||
|
import space.kscience.dataforge.tables.Column
|
||||||
|
import space.kscience.dataforge.tables.Row
|
||||||
|
import space.kscience.dataforge.tables.Table
|
||||||
|
import kotlin.reflect.KType
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import org.jetbrains.exposed.sql.Column as SqlColumn
|
||||||
|
|
||||||
|
public class ExposedColumn<T : Any>(
|
||||||
|
public val db: Database,
|
||||||
|
public val sqlTable: IntIdTable,
|
||||||
|
public val sqlColumn: SqlColumn<T>,
|
||||||
|
public override val type: KType,
|
||||||
|
) : Column<T> {
|
||||||
|
public override val name: String
|
||||||
|
get() = sqlColumn.name
|
||||||
|
|
||||||
|
public override val meta: Meta
|
||||||
|
get() = Meta.EMPTY
|
||||||
|
|
||||||
|
public override val size: Int
|
||||||
|
get() = transaction(db) { sqlColumn.table.selectAll().count().toInt() }
|
||||||
|
|
||||||
|
public override fun get(index: Int): T? = transaction(db) {
|
||||||
|
sqlTable.select { sqlTable.id eq index + 1 }.firstOrNull()?.getOrNull(sqlColumn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
public class ExposedRow<T : Any>(
|
||||||
|
public val db: Database,
|
||||||
|
public val sqlTable: IntIdTable,
|
||||||
|
public val sqlRow: ResultRow,
|
||||||
|
) :
|
||||||
|
Row<T> {
|
||||||
|
public override fun get(column: String): T? = transaction(db) {
|
||||||
|
val theColumn = sqlTable.columns.find { it.name == column } as SqlColumn<T>? ?: return@transaction null
|
||||||
|
sqlRow.getOrNull(theColumn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
public class ExposedTable<T : Any>(public val db: Database, public val sqlTable: IntIdTable, public val type: KType) :
|
||||||
|
Table<T> {
|
||||||
|
public override val columns: List<Column<T>> =
|
||||||
|
sqlTable.columns.filterNot { it.name == "id" }.map { ExposedColumn(db, sqlTable, it as SqlColumn<T>, type) }
|
||||||
|
|
||||||
|
public override val rows: List<Row<T>>
|
||||||
|
get() = transaction(db) {
|
||||||
|
sqlTable.selectAll().map { ExposedRow(db, sqlTable, it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override operator fun get(row: Int, column: String): T? = transaction(db) {
|
||||||
|
val sqlColumn: SqlColumn<T> = sqlTable.columns.find { it.name == column } as SqlColumn<T>?
|
||||||
|
?: return@transaction null
|
||||||
|
|
||||||
|
sqlTable.select { sqlTable.id eq row + 1 }.firstOrNull()?.getOrNull(sqlColumn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public inline fun <reified T : Any> ExposedTable(db: Database, table: IntIdTable): ExposedTable<T> =
|
||||||
|
ExposedTable(db, table, typeOf<T>())
|
||||||
|
|
||||||
|
public inline fun <reified T : Any> ExposedTable(
|
||||||
|
db: Database,
|
||||||
|
tableName: String,
|
||||||
|
columns: List<String>,
|
||||||
|
sqlColumnType: IColumnType,
|
||||||
|
): ExposedTable<T> {
|
||||||
|
val table = object : IntIdTable(tableName) {
|
||||||
|
init {
|
||||||
|
columns.forEach { registerColumn<T>(it, sqlColumnType) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction(db) { SchemaUtils.createMissingTablesAndColumns(table) }
|
||||||
|
return ExposedTable(db, table)
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package space.kscience.dataforge.exposed
|
||||||
|
|
||||||
|
import org.jetbrains.exposed.sql.Column
|
||||||
|
import org.jetbrains.exposed.sql.Database
|
||||||
|
import org.jetbrains.exposed.sql.IntegerColumnType
|
||||||
|
import org.jetbrains.exposed.sql.insert
|
||||||
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
internal class ExposedTableTest {
|
||||||
|
@Test
|
||||||
|
fun exposedTable() {
|
||||||
|
val db = Database.connect("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", driver = "org.h2.Driver")
|
||||||
|
|
||||||
|
val table = ExposedTable<Int>(
|
||||||
|
db,
|
||||||
|
"test",
|
||||||
|
listOf("a", "b", "c"),
|
||||||
|
IntegerColumnType(),
|
||||||
|
)
|
||||||
|
|
||||||
|
transaction(db) {
|
||||||
|
table.sqlTable.insert {
|
||||||
|
it[table.sqlTable.columns.find { t -> t.name == "a" } as Column<Int>] = 42
|
||||||
|
it[table.sqlTable.columns.find { t -> t.name == "b" } as Column<Int>] = 3
|
||||||
|
it[table.sqlTable.columns.find { t -> t.name == "c" } as Column<Int>] = 7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals(42, table[0, "a"])
|
||||||
|
assertEquals(3, table[0, "b"])
|
||||||
|
assertEquals(7, table[0, "c"])
|
||||||
|
assertEquals(3, table.columns.size)
|
||||||
|
table.columns.forEach { assertEquals(1, it.size) }
|
||||||
|
assertEquals(1, table.rows.size)
|
||||||
|
}
|
||||||
|
}
|
@ -27,5 +27,6 @@ include(
|
|||||||
// ":dataforge-output",
|
// ":dataforge-output",
|
||||||
":dataforge-tables",
|
":dataforge-tables",
|
||||||
":dataforge-workspace",
|
":dataforge-workspace",
|
||||||
|
":dataforge-exposed",
|
||||||
":dataforge-scripting"
|
":dataforge-scripting"
|
||||||
)
|
)
|
Loading…
Reference in New Issue
Block a user