Skip to content

Commit 210af02

Browse files
committed
Refactored DbType to use DbColumnTypeInformation, generated from TableColumnMetadata in generateTypeInformation(). This contains potential pre- and post-processing logic for any type
1 parent 67a1ef8 commit 210af02

File tree

10 files changed

+489
-337
lines changed

10 files changed

+489
-337
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package org.jetbrains.kotlinx.dataframe.io.db
2+
3+
import org.jetbrains.kotlinx.dataframe.DataColumn
4+
import org.jetbrains.kotlinx.dataframe.api.cast
5+
import org.jetbrains.kotlinx.dataframe.schema.ColumnSchema
6+
7+
public typealias AnyDbColumnTypeInformation = DbColumnTypeInformation<*, *, *>
8+
9+
/**
10+
* Represents all type information that can be retrieved from an SQL column.
11+
* This can be extended for your specific [DbType2] if you need extra information.
12+
*
13+
* @property targetSchema the target schema of the column after running the optional
14+
* [valuePreprocessor] and [columnPostprocessor].
15+
* @property valuePreprocessor an optional function that converts values from [java.sql.ResultSet.getObject]
16+
* to a cell/row suitable to be put into a [org.jetbrains.kotlinx.dataframe.DataColumn].
17+
* @property columnPostprocessor an optional function that converts a [org.jetbrains.kotlinx.dataframe.DataColumn] with values of type [D]
18+
* to a [org.jetbrains.kotlinx.dataframe.DataColumn] of with values of type [P].
19+
*/
20+
public open class DbColumnTypeInformation<J, D, P>(
21+
public open val columnMetadata: TableColumnMetadata,
22+
public open val targetSchema: ColumnSchema,
23+
public open val valuePreprocessor: DbValuePreprocessor<J, D>?,
24+
public open val columnPostprocessor: DbColumnPostprocessor<D, P>?,
25+
) {
26+
public open fun preprocess(value: J): D {
27+
valuePreprocessor?.let { valuePreprocessor ->
28+
return valuePreprocessor.preprocess(value, this)
29+
}
30+
return value as D
31+
}
32+
33+
public open fun postprocess(column: DataColumn<D>): DataColumn<P> {
34+
columnPostprocessor?.let { columnPostprocessor ->
35+
return columnPostprocessor.postprocess(column, this)
36+
}
37+
return column.cast()
38+
}
39+
}
40+
41+
public fun <J, D, P> DbColumnTypeInformation<*, *, *>.cast(): DbColumnTypeInformation<J, D, P> =
42+
this as DbColumnTypeInformation<J, D, P>
43+
44+
public fun <T> dbColumnTypeInformation(
45+
columnMetadata: TableColumnMetadata,
46+
targetSchema: ColumnSchema,
47+
): DbColumnTypeInformation<T, T, T> =
48+
DbColumnTypeInformation(
49+
columnMetadata = columnMetadata,
50+
targetSchema = targetSchema,
51+
valuePreprocessor = null,
52+
columnPostprocessor = null,
53+
)
54+
55+
public fun <J, D> dbColumnTypeInformationWithPreprocessing(
56+
columnMetadata: TableColumnMetadata,
57+
targetSchema: ColumnSchema,
58+
valuePreprocessor: DbValuePreprocessor<J, D>?,
59+
): DbColumnTypeInformation<J, D, D> =
60+
DbColumnTypeInformation(
61+
columnMetadata = columnMetadata,
62+
targetSchema = targetSchema,
63+
valuePreprocessor = valuePreprocessor,
64+
columnPostprocessor = null,
65+
)
66+
67+
public fun <J, P> dbColumnTypeInformationWithPostprocessing(
68+
columnMetadata: TableColumnMetadata,
69+
targetSchema: ColumnSchema,
70+
columnPostprocessor: DbColumnPostprocessor<J, P>?,
71+
): DbColumnTypeInformation<J, J, P> =
72+
DbColumnTypeInformation(
73+
columnMetadata = columnMetadata,
74+
targetSchema = targetSchema,
75+
valuePreprocessor = null,
76+
columnPostprocessor = columnPostprocessor,
77+
)
78+
79+
public fun <J, D, P> dbColumnTypeInformation(
80+
columnMetadata: TableColumnMetadata,
81+
targetSchema: ColumnSchema,
82+
valuePreprocessor: DbValuePreprocessor<J, D>?,
83+
columnPostprocessor: DbColumnPostprocessor<D, P>?,
84+
): DbColumnTypeInformation<J, D, P> =
85+
DbColumnTypeInformation(
86+
columnMetadata = columnMetadata,
87+
targetSchema = targetSchema,
88+
valuePreprocessor = valuePreprocessor,
89+
columnPostprocessor = columnPostprocessor,
90+
)
91+
92+
/**
93+
* This preprocessor can be created for types where you want to convert the values
94+
* coming from [java.sql.ResultSet.getObject] to a different type more suitable to be put in a [DataColumn]
95+
*
96+
* @param J the type of the value coming from the JDBC driver.
97+
* @param D the type of the column values after preprocessing.
98+
*/
99+
public fun interface DbValuePreprocessor<in J, out D> {
100+
101+
/**
102+
* Converts the given [jdbcValue]: [J] to a [D].
103+
*
104+
* If you intend to create a [org.jetbrains.kotlinx.dataframe.columns.ColumnGroup],
105+
* return a [org.jetbrains.kotlinx.dataframe.DataRow] here.
106+
*
107+
* If you intend to create a [org.jetbrains.kotlinx.dataframe.columns.FrameColumn],
108+
* return a [org.jetbrains.kotlinx.dataframe.DataFrame] here.
109+
*/
110+
public fun preprocess(
111+
jdbcValue: J,
112+
dbColumnTypeInformation: DbColumnTypeInformation<@UnsafeVariance J, @UnsafeVariance D, *>,
113+
): D
114+
}
115+
116+
public fun <J, D> DbValuePreprocessor<*, *>.cast(): DbValuePreprocessor<J, D> = this as DbValuePreprocessor<J, D>
117+
118+
/**
119+
* @param D the type of the column values before postprocessing.
120+
* @param P the type of the column values after postprocessing.
121+
*/
122+
public fun interface DbColumnPostprocessor<in D, out P> {
123+
124+
/**
125+
* Converts the given [column]: [DataColumn] with values of type [D] to a [DataColumn] of with values of type [P].
126+
*/
127+
public fun postprocess(
128+
column: DataColumn<D>,
129+
dbColumnTypeInformation: DbColumnTypeInformation<*, @UnsafeVariance D, @UnsafeVariance P>,
130+
): DataColumn<P>
131+
}
132+
133+
public fun <D, P> DbColumnPostprocessor<*, *>.cast(): DbColumnPostprocessor<D, P> = this as DbColumnPostprocessor<D, P>

0 commit comments

Comments
 (0)