Skip to content

Commit 24e0136

Browse files
authored
Ported the fix for JDBC integration from the 0.12.1 branch (#538)
* Ported the fix for JDBC integration from the 0.12.1 branch * Removed unused imports * Linting fix * Update README and improve documentation clarity
1 parent b6983cf commit 24e0136

File tree

18 files changed

+1083
-871
lines changed

18 files changed

+1083
-871
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ This table shows the mapping between main library component versions and minimum
192192
| 0.11.0 | 8 | 1.8.20 | 0.11.0-358 | 3.0.0 | 11.0.0 |
193193
| 0.11.1 | 8 | 1.8.20 | 0.11.0-358 | 3.0.0 | 11.0.0 |
194194
| 0.12.0 | 8 | 1.9.0 | 0.11.0-358 | 3.0.0 | 11.0.0 |
195+
| 0.12.1 | 8 | 1.9.0 | 0.11.0-358 | 3.0.0 | 11.0.0 |
195196

196197
## Usage example
197198

core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/rename.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ internal fun <T, C> RenameClause<T, C>.renameImpl(newNames: Array<out String>):
2222
internal fun <T, C> RenameClause<T, C>.renameImpl(transform: (ColumnWithPath<C>) -> String): DataFrame<T> {
2323
// get all selected columns and their paths
2424
val selectedColumnsWithPath = df.getColumnsWithPaths(columns)
25-
.associateBy { it.data }
25+
.associateBy { it.path }
2626
// gather a tree of all columns where the nodes will be renamed
2727
val tree = df.getColumnsWithPaths { all().rec() }.collectTree()
2828

2929
// perform rename in nodes
30-
tree.allChildrenNotNull().forEach { node ->
30+
tree.allChildrenNotNull().map { it to it.pathFromRoot() }.forEach { (node, originalPath) ->
3131
// Check if the current node/column is a selected column and, if so, get its ColumnWithPath
32-
val column = selectedColumnsWithPath[node.data] ?: return@forEach
32+
val column = selectedColumnsWithPath[originalPath] ?: return@forEach
3333
// Use the found selected ColumnWithPath to query for the new name
3434
val newColumnName = transform(column)
3535
node.name = newColumnName

dataframe-jdbc/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/db/DbType.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import org.jetbrains.kotlinx.dataframe.io.TableColumnMetadata
44
import org.jetbrains.kotlinx.dataframe.schema.ColumnSchema
55
import java.sql.ResultSet
66
import org.jetbrains.kotlinx.dataframe.io.TableMetadata
7+
import kotlin.reflect.KType
78

89
/**
910
* The `DbType` class represents a database type used for reading dataframe from the database.
@@ -22,19 +23,10 @@ public abstract class DbType(public val dbTypeInJdbcUrl: String) {
2223
*/
2324
public abstract val driverClassName: String
2425

25-
/**
26-
* Converts the data from the given [ResultSet] into the specified [TableColumnMetadata] type.
27-
*
28-
* @param rs The [ResultSet] containing the data to be converted.
29-
* @param tableColumnMetadata The [TableColumnMetadata] representing the target type of the conversion.
30-
* @return The converted data as an instance of [Any].
31-
*/
32-
public abstract fun convertDataFromResultSet(rs: ResultSet, tableColumnMetadata: TableColumnMetadata): Any?
33-
3426
/**
3527
* Returns a [ColumnSchema] produced from [tableColumnMetadata].
3628
*/
37-
public abstract fun toColumnSchema(tableColumnMetadata: TableColumnMetadata): ColumnSchema
29+
public abstract fun convertSqlTypeToColumnSchemaValue(tableColumnMetadata: TableColumnMetadata): ColumnSchema?
3830

3931
/**
4032
* Checks if the given table name is a system table for the specified database type.
@@ -52,4 +44,12 @@ public abstract class DbType(public val dbTypeInJdbcUrl: String) {
5244
* @return the TableMetadata object representing the table metadata.
5345
*/
5446
public abstract fun buildTableMetadata(tables: ResultSet): TableMetadata
47+
48+
/**
49+
* Converts SQL data type to a Kotlin data type.
50+
*
51+
* @param [tableColumnMetadata] The metadata of the table column.
52+
* @return The corresponding Kotlin data type, or null if no mapping is found.
53+
*/
54+
public abstract fun convertSqlTypeToKType(tableColumnMetadata: TableColumnMetadata): KType?
5555
}

dataframe-jdbc/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/db/H2.kt

Lines changed: 7 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@ import org.jetbrains.kotlinx.dataframe.io.TableColumnMetadata
44
import org.jetbrains.kotlinx.dataframe.schema.ColumnSchema
55
import java.sql.ResultSet
66
import java.util.Locale
7-
import org.jetbrains.kotlinx.dataframe.DataRow
8-
import org.jetbrains.kotlinx.dataframe.columns.ColumnGroup
97
import org.jetbrains.kotlinx.dataframe.io.TableMetadata
10-
import kotlin.reflect.typeOf
8+
import kotlin.reflect.KType
119

1210
/**
1311
* Represents the H2 database type.
@@ -21,71 +19,8 @@ public object H2 : DbType("h2") {
2119
override val driverClassName: String
2220
get() = "org.h2.Driver"
2321

24-
override fun convertDataFromResultSet(rs: ResultSet, tableColumnMetadata: TableColumnMetadata): Any? {
25-
val name = tableColumnMetadata.name
26-
return when (tableColumnMetadata.sqlTypeName) {
27-
"CHARACTER", "CHAR" -> rs.getString(name)
28-
"CHARACTER VARYING", "CHAR VARYING", "VARCHAR" -> rs.getString(name)
29-
"CHARACTER LARGE OBJECT", "CHAR LARGE OBJECT", "CLOB" -> rs.getString(name)
30-
"MEDIUMTEXT" -> rs.getString(name)
31-
"VARCHAR_IGNORECASE" -> rs.getString(name)
32-
"BINARY" -> rs.getBytes(name)
33-
"BINARY VARYING", "VARBINARY" -> rs.getBytes(name)
34-
"BINARY LARGE OBJECT", "BLOB" -> rs.getBytes(name)
35-
"BOOLEAN" -> rs.getBoolean(name)
36-
"TINYINT" -> rs.getByte(name)
37-
"SMALLINT" -> rs.getShort(name)
38-
"INTEGER", "INT" -> rs.getInt(name)
39-
"BIGINT" -> rs.getLong(name)
40-
"NUMERIC", "DECIMAL", "DEC" -> rs.getFloat(name) // not a BigDecimal
41-
"REAL", "FLOAT" -> rs.getFloat(name)
42-
"DOUBLE PRECISION" -> rs.getDouble(name)
43-
"DECFLOAT" -> rs.getDouble(name)
44-
"DATE" -> rs.getDate(name).toString()
45-
"TIME" -> rs.getTime(name).toString()
46-
"TIME WITH TIME ZONE" -> rs.getTime(name).toString()
47-
"TIMESTAMP" -> rs.getTimestamp(name).toString()
48-
"TIMESTAMP WITH TIME ZONE" -> rs.getTimestamp(name).toString()
49-
"INTERVAL" -> rs.getObject(name).toString()
50-
"JAVA_OBJECT" -> rs.getObject(name)
51-
"ENUM" -> rs.getString(name)
52-
"JSON" -> rs.getString(name) // TODO: https://github.com/Kotlin/dataframe/issues/462
53-
"UUID" -> rs.getString(name)
54-
else -> throw IllegalArgumentException("Unsupported H2 type: ${tableColumnMetadata.sqlTypeName}")
55-
}
56-
}
57-
58-
override fun toColumnSchema(tableColumnMetadata: TableColumnMetadata): ColumnSchema {
59-
return when (tableColumnMetadata.sqlTypeName) {
60-
"CHARACTER", "CHAR" -> ColumnSchema.Value(typeOf<String>())
61-
"CHARACTER VARYING", "CHAR VARYING", "VARCHAR" -> ColumnSchema.Value(typeOf<String>())
62-
"CHARACTER LARGE OBJECT", "CHAR LARGE OBJECT", "CLOB" -> ColumnSchema.Value(typeOf<String>())
63-
"MEDIUMTEXT" -> ColumnSchema.Value(typeOf<String>())
64-
"VARCHAR_IGNORECASE" -> ColumnSchema.Value(typeOf<String>())
65-
"BINARY" -> ColumnSchema.Value(typeOf<ByteArray>())
66-
"BINARY VARYING", "VARBINARY" -> ColumnSchema.Value(typeOf<ByteArray>())
67-
"BINARY LARGE OBJECT", "BLOB" -> ColumnSchema.Value(typeOf<ByteArray>())
68-
"BOOLEAN" -> ColumnSchema.Value(typeOf<Boolean>())
69-
"TINYINT" -> ColumnSchema.Value(typeOf<Byte>())
70-
"SMALLINT" -> ColumnSchema.Value(typeOf<Short>())
71-
"INTEGER", "INT" -> ColumnSchema.Value(typeOf<Int>())
72-
"BIGINT" -> ColumnSchema.Value(typeOf<Long>())
73-
"NUMERIC", "DECIMAL", "DEC" -> ColumnSchema.Value(typeOf<Float>())
74-
"REAL", "FLOAT" -> ColumnSchema.Value(typeOf<Float>())
75-
"DOUBLE PRECISION" -> ColumnSchema.Value(typeOf<Double>())
76-
"DECFLOAT" -> ColumnSchema.Value(typeOf<Double>())
77-
"DATE" -> ColumnSchema.Value(typeOf<String>())
78-
"TIME" -> ColumnSchema.Value(typeOf<String>())
79-
"TIME WITH TIME ZONE" -> ColumnSchema.Value(typeOf<String>())
80-
"TIMESTAMP" -> ColumnSchema.Value(typeOf<String>())
81-
"TIMESTAMP WITH TIME ZONE" -> ColumnSchema.Value(typeOf<String>())
82-
"INTERVAL" -> ColumnSchema.Value(typeOf<String>())
83-
"JAVA_OBJECT" -> ColumnSchema.Value(typeOf<Any>())
84-
"ENUM" -> ColumnSchema.Value(typeOf<String>())
85-
"JSON" -> ColumnSchema.Value(typeOf<String>()) // TODO: https://github.com/Kotlin/dataframe/issues/462
86-
"UUID" -> ColumnSchema.Value(typeOf<String>())
87-
else -> throw IllegalArgumentException("Unsupported H2 type: ${tableColumnMetadata.sqlTypeName} for column ${tableColumnMetadata.name}")
88-
}
22+
override fun convertSqlTypeToColumnSchemaValue(tableColumnMetadata: TableColumnMetadata): ColumnSchema? {
23+
return null
8924
}
9025

9126
override fun isSystemTable(tableMetadata: TableMetadata): Boolean {
@@ -99,4 +34,8 @@ public object H2 : DbType("h2") {
9934
tables.getString("TABLE_SCHEM"),
10035
tables.getString("TABLE_CAT"))
10136
}
37+
38+
override fun convertSqlTypeToKType(tableColumnMetadata: TableColumnMetadata): KType? {
39+
return null
40+
}
10241
}

dataframe-jdbc/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/db/MariaDb.kt

Lines changed: 7 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import org.jetbrains.kotlinx.dataframe.io.TableColumnMetadata
44
import org.jetbrains.kotlinx.dataframe.schema.ColumnSchema
55
import java.sql.ResultSet
66
import org.jetbrains.kotlinx.dataframe.io.TableMetadata
7-
import kotlin.reflect.typeOf
7+
import kotlin.reflect.KType
88

99
/**
1010
* Represents the MariaDb database type.
@@ -16,73 +16,8 @@ public object MariaDb : DbType("mariadb") {
1616
override val driverClassName: String
1717
get() = "org.mariadb.jdbc.Driver"
1818

19-
override fun convertDataFromResultSet(rs: ResultSet, tableColumnMetadata: TableColumnMetadata): Any? {
20-
val name = tableColumnMetadata.name
21-
return when (tableColumnMetadata.sqlTypeName) {
22-
"BIT" -> rs.getBytes(name)
23-
"TINYINT" -> rs.getInt(name)
24-
"SMALLINT" -> rs.getInt(name)
25-
"MEDIUMINT"-> rs.getInt(name)
26-
"MEDIUMINT UNSIGNED" -> rs.getLong(name)
27-
"INTEGER", "INT" -> rs.getInt(name)
28-
"INTEGER UNSIGNED", "INT UNSIGNED" -> rs.getLong(name)
29-
"BIGINT" -> rs.getLong(name)
30-
"FLOAT" -> rs.getFloat(name)
31-
"DOUBLE" -> rs.getDouble(name)
32-
"DECIMAL" -> rs.getBigDecimal(name)
33-
"DATE" -> rs.getDate(name).toString()
34-
"DATETIME" -> rs.getTimestamp(name).toString()
35-
"TIMESTAMP" -> rs.getTimestamp(name).toString()
36-
"TIME"-> rs.getTime(name).toString()
37-
"YEAR" -> rs.getDate(name).toString()
38-
"VARCHAR", "CHAR" -> rs.getString(name)
39-
"BINARY" -> rs.getBytes(name)
40-
"VARBINARY" -> rs.getBytes(name)
41-
"TINYBLOB"-> rs.getBytes(name)
42-
"BLOB"-> rs.getBytes(name)
43-
"MEDIUMBLOB" -> rs.getBytes(name)
44-
"LONGBLOB" -> rs.getBytes(name)
45-
"TEXT" -> rs.getString(name)
46-
"MEDIUMTEXT" -> rs.getString(name)
47-
"LONGTEXT" -> rs.getString(name)
48-
"ENUM" -> rs.getString(name)
49-
"SET" -> rs.getString(name)
50-
else -> throw IllegalArgumentException("Unsupported MariaDB type: ${tableColumnMetadata.sqlTypeName}")
51-
}
52-
}
53-
54-
override fun toColumnSchema(tableColumnMetadata: TableColumnMetadata): ColumnSchema {
55-
return when (tableColumnMetadata.sqlTypeName) {
56-
"BIT" -> ColumnSchema.Value(typeOf<ByteArray>())
57-
"TINYINT" -> ColumnSchema.Value(typeOf<Int>())
58-
"SMALLINT" -> ColumnSchema.Value(typeOf<Int>())
59-
"MEDIUMINT"-> ColumnSchema.Value(typeOf<Int>())
60-
"MEDIUMINT UNSIGNED" -> ColumnSchema.Value(typeOf<Long>())
61-
"INTEGER", "INT" -> ColumnSchema.Value(typeOf<Int>())
62-
"INTEGER UNSIGNED", "INT UNSIGNED" -> ColumnSchema.Value(typeOf<Long>())
63-
"BIGINT" -> ColumnSchema.Value(typeOf<Long>())
64-
"FLOAT" -> ColumnSchema.Value(typeOf<Float>())
65-
"DOUBLE" -> ColumnSchema.Value(typeOf<Double>())
66-
"DECIMAL" -> ColumnSchema.Value(typeOf<Double>())
67-
"DATE" -> ColumnSchema.Value(typeOf<String>())
68-
"DATETIME" -> ColumnSchema.Value(typeOf<String>())
69-
"TIMESTAMP" -> ColumnSchema.Value(typeOf<String>())
70-
"TIME"-> ColumnSchema.Value(typeOf<String>())
71-
"YEAR" -> ColumnSchema.Value(typeOf<String>())
72-
"VARCHAR", "CHAR" -> ColumnSchema.Value(typeOf<String>())
73-
"BINARY" -> ColumnSchema.Value(typeOf<ByteArray>())
74-
"VARBINARY" -> ColumnSchema.Value(typeOf<ByteArray>())
75-
"TINYBLOB"-> ColumnSchema.Value(typeOf<ByteArray>())
76-
"BLOB"-> ColumnSchema.Value(typeOf<ByteArray>())
77-
"MEDIUMBLOB" -> ColumnSchema.Value(typeOf<ByteArray>())
78-
"LONGBLOB" -> ColumnSchema.Value(typeOf<ByteArray>())
79-
"TEXT" -> ColumnSchema.Value(typeOf<String>())
80-
"MEDIUMTEXT" -> ColumnSchema.Value(typeOf<String>())
81-
"LONGTEXT" -> ColumnSchema.Value(typeOf<String>())
82-
"ENUM" -> ColumnSchema.Value(typeOf<String>())
83-
"SET" -> ColumnSchema.Value(typeOf<String>())
84-
else -> throw IllegalArgumentException("Unsupported MariaDB type: ${tableColumnMetadata.sqlTypeName} for column ${tableColumnMetadata.name}")
85-
}
19+
override fun convertSqlTypeToColumnSchemaValue(tableColumnMetadata: TableColumnMetadata): ColumnSchema? {
20+
return null
8621
}
8722

8823
override fun isSystemTable(tableMetadata: TableMetadata): Boolean {
@@ -95,4 +30,8 @@ public object MariaDb : DbType("mariadb") {
9530
tables.getString("table_schem"),
9631
tables.getString("table_cat"))
9732
}
33+
34+
override fun convertSqlTypeToKType(tableColumnMetadata: TableColumnMetadata): KType? {
35+
return null
36+
}
9837
}

dataframe-jdbc/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/db/MySql.kt

Lines changed: 7 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@ import org.jetbrains.kotlinx.dataframe.io.TableColumnMetadata
44
import org.jetbrains.kotlinx.dataframe.schema.ColumnSchema
55
import java.sql.ResultSet
66
import java.util.Locale
7-
import org.jetbrains.kotlinx.dataframe.DataRow
8-
import org.jetbrains.kotlinx.dataframe.columns.ColumnGroup
97
import org.jetbrains.kotlinx.dataframe.io.TableMetadata
10-
import kotlin.reflect.typeOf
8+
import kotlin.reflect.KType
119

1210
/**
1311
* Represents the MySql database type.
@@ -19,79 +17,8 @@ public object MySql : DbType("mysql") {
1917
override val driverClassName: String
2018
get() = "com.mysql.jdbc.Driver"
2119

22-
override fun convertDataFromResultSet(rs: ResultSet, tableColumnMetadata: TableColumnMetadata): Any? {
23-
val name = tableColumnMetadata.name
24-
return when (tableColumnMetadata.sqlTypeName) {
25-
"BIT" -> rs.getBytes(name)
26-
"TINYINT" -> rs.getInt(name)
27-
"SMALLINT" -> rs.getInt(name)
28-
"MEDIUMINT"-> rs.getInt(name)
29-
"MEDIUMINT UNSIGNED" -> rs.getLong(name)
30-
"INTEGER", "INT" -> rs.getInt(name)
31-
"INTEGER UNSIGNED", "INT UNSIGNED" -> rs.getLong(name)
32-
"BIGINT" -> rs.getLong(name)
33-
"FLOAT" -> rs.getFloat(name)
34-
"DOUBLE" -> rs.getDouble(name)
35-
"DECIMAL" -> rs.getBigDecimal(name)
36-
"DATE" -> rs.getDate(name).toString()
37-
"DATETIME" -> rs.getTimestamp(name).toString()
38-
"TIMESTAMP" -> rs.getTimestamp(name).toString()
39-
"TIME"-> rs.getTime(name).toString()
40-
"YEAR" -> rs.getDate(name).toString()
41-
"VARCHAR", "CHAR" -> rs.getString(name)
42-
"BINARY" -> rs.getBytes(name)
43-
"VARBINARY" -> rs.getBytes(name)
44-
"TINYBLOB"-> rs.getBytes(name)
45-
"BLOB"-> rs.getBytes(name)
46-
"MEDIUMBLOB" -> rs.getBytes(name)
47-
"LONGBLOB" -> rs.getBytes(name)
48-
"TEXT" -> rs.getString(name)
49-
"MEDIUMTEXT" -> rs.getString(name)
50-
"LONGTEXT" -> rs.getString(name)
51-
"ENUM" -> rs.getString(name)
52-
"SET" -> rs.getString(name)
53-
// special mysql types
54-
"JSON" -> rs.getString(name) // TODO: https://github.com/Kotlin/dataframe/issues/462
55-
"GEOMETRY" -> rs.getBytes(name)
56-
else -> throw IllegalArgumentException("Unsupported MySQL type: ${tableColumnMetadata.sqlTypeName}")
57-
}
58-
}
59-
60-
override fun toColumnSchema(tableColumnMetadata: TableColumnMetadata): ColumnSchema {
61-
return when (tableColumnMetadata.sqlTypeName) {
62-
"BIT" -> ColumnSchema.Value(typeOf<ByteArray>())
63-
"TINYINT" -> ColumnSchema.Value(typeOf<Int>())
64-
"SMALLINT" -> ColumnSchema.Value(typeOf<Int>())
65-
"MEDIUMINT"-> ColumnSchema.Value(typeOf<Int>())
66-
"MEDIUMINT UNSIGNED" -> ColumnSchema.Value(typeOf<Long>())
67-
"INTEGER", "INT" -> ColumnSchema.Value(typeOf<Int>())
68-
"INTEGER UNSIGNED", "INT UNSIGNED" -> ColumnSchema.Value(typeOf<Long>())
69-
"BIGINT" -> ColumnSchema.Value(typeOf<Long>())
70-
"FLOAT" -> ColumnSchema.Value(typeOf<Float>())
71-
"DOUBLE" -> ColumnSchema.Value(typeOf<Double>())
72-
"DECIMAL" -> ColumnSchema.Value(typeOf<Double>())
73-
"DATE" -> ColumnSchema.Value(typeOf<String>())
74-
"DATETIME" -> ColumnSchema.Value(typeOf<String>())
75-
"TIMESTAMP" -> ColumnSchema.Value(typeOf<String>())
76-
"TIME"-> ColumnSchema.Value(typeOf<String>())
77-
"YEAR" -> ColumnSchema.Value(typeOf<String>())
78-
"VARCHAR", "CHAR" -> ColumnSchema.Value(typeOf<String>())
79-
"BINARY" -> ColumnSchema.Value(typeOf<ByteArray>())
80-
"VARBINARY" -> ColumnSchema.Value(typeOf<ByteArray>())
81-
"TINYBLOB"-> ColumnSchema.Value(typeOf<ByteArray>())
82-
"BLOB"-> ColumnSchema.Value(typeOf<ByteArray>())
83-
"MEDIUMBLOB" -> ColumnSchema.Value(typeOf<ByteArray>())
84-
"LONGBLOB" -> ColumnSchema.Value(typeOf<ByteArray>())
85-
"TEXT" -> ColumnSchema.Value(typeOf<String>())
86-
"MEDIUMTEXT" -> ColumnSchema.Value(typeOf<String>())
87-
"LONGTEXT" -> ColumnSchema.Value(typeOf<String>())
88-
"ENUM" -> ColumnSchema.Value(typeOf<String>())
89-
"SET" -> ColumnSchema.Value(typeOf<String>())
90-
// special mysql types
91-
"JSON" -> ColumnSchema.Value(typeOf<ColumnGroup<DataRow<String>>>()) // TODO: https://github.com/Kotlin/dataframe/issues/462
92-
"GEOMETRY" -> ColumnSchema.Value(typeOf<ByteArray>())
93-
else -> throw IllegalArgumentException("Unsupported MySQL type: ${tableColumnMetadata.sqlTypeName} for column ${tableColumnMetadata.name}")
94-
}
20+
override fun convertSqlTypeToColumnSchemaValue(tableColumnMetadata: TableColumnMetadata): ColumnSchema? {
21+
return null
9522
}
9623

9724
override fun isSystemTable(tableMetadata: TableMetadata): Boolean {
@@ -116,4 +43,8 @@ public object MySql : DbType("mysql") {
11643
tables.getString("table_schem"),
11744
tables.getString("table_cat"))
11845
}
46+
47+
override fun convertSqlTypeToKType(tableColumnMetadata: TableColumnMetadata): KType? {
48+
return null
49+
}
11950
}

0 commit comments

Comments
 (0)