Toshihiro Nakamura
01/15/2023, 4:40 AMdave08
01/15/2023, 1:29 PMdave08
01/15/2023, 1:31 PM@KomapperColumn
annotation or some other annotation?... I think it could simplify the api, since I'm sure users would prefer to use String's for text or clob fields unless they have some field that can't be contained in a String...Toshihiro Nakamura
01/15/2023, 2:45 PMYou’re missing the mysql TEXT typeI tried to map MySQL text type to io.r2dbc.spi.Clob, but jasync-r2dbc-mysql does not support io.r2dbc.spi.Clob.
dave08
01/15/2023, 2:46 PMdave08
01/15/2023, 2:47 PMclass LongTextTypeR2dbc : R2dbcUserDefinedDataType<LongText> {
override val name: String = "text"
override val r2dbcType: Class<*> = String::class.javaObjectType
override val klass: KClass<LongText> = LongText::class
override fun getValue(row: Row, index: Int): LongText? {
return row.get(index, String::class.javaObjectType)?.let { LongText(it) }
}
override fun getValue(row: Row, columnLabel: String): LongText? {
return row.get(columnLabel, String::class.javaObjectType)?.let { LongText(it) }
}
override fun setValue(statement: Statement, index: Int, value: LongText) {
statement.bind(index, value.value)
}
override fun setValue(statement: Statement, name: String, value: LongText) {
statement.bind(name, value.value)
}
override fun toString(value: LongText): String {
return value.value.toString()
}
}
dave08
01/15/2023, 2:47 PMdata class LongText(val value: String)
dave08
01/15/2023, 2:47 PMdave08
01/15/2023, 2:48 PMdave08
01/15/2023, 2:49 PMToshihiro Nakamura
01/15/2023, 3:04 PMit would be nice to be able to map multiple sql types to the same kotlin primitive... like with my suggestion using a parameter in the @KomapperColumn annotation or some other annotation?The solution with annotations has the weakness that it cannot be used with Template Query. So we want to be cautious about adding new annotations.
dave08
01/15/2023, 3:06 PMdave08
01/15/2023, 3:07 PMdave08
01/15/2023, 3:09 PMToshihiro Nakamura
01/15/2023, 3:11 PMWhy should this make a difference in template queries?This is because the result of Template Query execution is not the data structure of an entity. In other words, Komapper cannot use information from the entity metamodel when converting Template Query results to Kotlin data types. On the other hand, user defined data type is also used in Template Query.
dave08
01/15/2023, 3:12 PMOn the other hand, user defined data type is also used in Template Query??
dave08
01/15/2023, 3:13 PMdave08
01/15/2023, 3:14 PMToshihiro Nakamura
01/15/2023, 3:21 PMdave08
01/15/2023, 3:27 PMToshihiro Nakamura
01/15/2023, 3:33 PMdave08
01/15/2023, 3:34 PMdave08
01/15/2023, 3:36 PMdave08
01/15/2023, 3:38 PMdave08
01/15/2023, 3:40 PMdave08
01/15/2023, 3:40 PMdave08
01/15/2023, 3:49 PMdave08
01/15/2023, 3:50 PMdave08
01/15/2023, 3:52 PMToshihiro Nakamura
01/15/2023, 3:54 PMdave08
01/15/2023, 8:18 PMdave08
01/17/2023, 10:17 AMToshihiro Nakamura
01/17/2023, 11:02 AM@KomapperColumn(mapping = MappingType.CLOB_STRING)
val name: String
dave08
01/17/2023, 11:04 AMMappingType.CLOB_STRING
contain a KClass that does the transformation, and allow the user to specify their own?Toshihiro Nakamura
01/17/2023, 11:09 AMToshihiro Nakamura
01/17/2023, 11:10 AMdave08
01/17/2023, 11:23 AMFurther, we do not want the entity to rely on Jdbc or R2dbc specific converters.Maybe not the converter, but maybe a provider class that provides the appropriate converter? In general, someone writing a converter is making their entity depend on such a specific converter and nothing forces them to write both... but I guess you mean having that reference in the entity declaration... which a provider would solve. But I see your point, that it might not be the nicest api... json serializers/deserializers use this kind of method for custom json converters per field... it does provide a lot of power though...
dave08
01/17/2023, 11:24 AM@KomapperColumn
is that this is really specific to text/clob fields... not integers or any other types...?dave08
01/17/2023, 11:25 AM@KomapperEnum
...dave08
01/17/2023, 11:25 AM@KomapperText(mapping=...)
?Toshihiro Nakamura
01/17/2023, 11:40 AMthis is really specific to text/clob fields... not integers or any other types...?No. Other types may be supported in the future. For example:
@KomapperColumn(mapping = MappingType.BLOB_BYTES)
val file: ByteArray
dave08
01/17/2023, 12:47 PMToshihiro Nakamura
01/17/2023, 2:09 PMdave08
01/17/2023, 2:11 PMToshihiro Nakamura
01/17/2023, 2:24 PMdave08
01/17/2023, 2:25 PMdave08
01/17/2023, 2:26 PMdave08
01/17/2023, 2:28 PMdave08
01/17/2023, 2:29 PMToshihiro Nakamura
01/17/2023, 2:29 PMIn Jasync it’s not CLOB_STRING, it’s TEXT_STRING 🙈?Yes. CLOB_STRING means that Komapper map SQL TEXT to Kotlin String in Jasync.
Toshihiro Nakamura
01/17/2023, 3:50 PMdave08
01/17/2023, 4:17 PMToshihiro Nakamura
01/18/2023, 12:38 PMOr at least allowing to use value classes for user defined types...?Yes, you can use value classes. You can rewrite the LongText data class as a value class in your example above.
@JvmInline
value class LongText constructor internal(val value: String)
If a value class has a non-public constructor, user-defined type can handle it.dave08
01/18/2023, 12:40 PMdave08
01/18/2023, 12:42 PMToshihiro Nakamura
01/19/2023, 9:18 AMI’m just wondering if it could be made a bit more powerful and generic.I have a new idea. Users must do 3 things to map multiple sql types to the same kotlin type. 1. Create a user defined type. In your case, it means that LongText and LongTextTypeR2dbc. 2. Create a mapping object as follows:
object LongTextMapping<String, LongText> : DataTypeMapping {
fun exteriorToInterior(exterior: String) = LongText(exterior)
fun interiorToExterior(interior: LongText) = interior.value
}
3. Specify the above mapping object to `@KomapperColumn`:
@KomapperColumn(mapping = LongTextMapping::class)
val decription: String
Typical use cases such as mapping SQL TEXT to Kotlin String can be supported by Komapper. In that case, steps No. 1 and 2 are not necessary.dave08
01/19/2023, 10:23 AMgetClob(...)
or get(..., String::class)
from say, r2dbc?dave08
01/19/2023, 10:23 AMLongTextTypeR2dbc
...dave08
01/19/2023, 10:24 AMLongTextTypeR2dbc
as the mapping in the @KomapperColumn
?dave08
01/19/2023, 10:25 AMdave08
01/19/2023, 10:49 AMdave08
01/19/2023, 10:58 AMLongTextMapping
might be a bit of boilerplate since LongText
is really just a value class
thats' real value is a String
... also it seems like a DataTypeMapping
IS a DataTypeConverter
that allows mapping back to a primitive type on a specified column... even if it would be required, why not merge the two concepts and be able to use them both ways? To the class without an annotation (perhaps with an option to use another converter to that same class), and to the primitive type with an annotation?dave08
01/19/2023, 10:59 AMToshihiro Nakamura
01/19/2023, 12:02 PM@JvmInline
value class LongText(value: String)
2. Crate a user defined data type that uses the above wrapper class:
class LongTextTypeR2dbc : R2dbcUserDefinedDataType<LongText> { ... }
3. Specify the wrapper class to @KomapperColumn:
@KomapperColumn(wrapper = LongText::class)
val description: String
dave08
01/19/2023, 12:06 PMdave08
01/19/2023, 12:15 PMKotlin Type Database Type
java.math.BigDecimal NUMERIC
java.math.BigInteger NUMERIC
java.sql.Array ARRAY
java.sql.Blob BLOB
java.sql.Clob CLOB
java.sql.NClob CLOB
java.sql.SQLXML CLOB
maybe adding an extra column for value class
wrappers that could also be independent of jdbc or r2dbc (like using String instead of CLOB) and can be used as "wrappers" (is that the right word for this?)...
I'm just thinking out loud about how other users would understand this new concept, so that it can be made in a way that's easy to understand/use...dave08
01/19/2023, 12:16 PMdave08
01/19/2023, 12:21 PMdave08
01/19/2023, 12:22 PMToshihiro Nakamura
01/19/2023, 12:22 PMToshihiro Nakamura
01/19/2023, 12:24 PMdave08
01/19/2023, 12:26 PMClob::class
is also an interiorType, which I don't suppose could be used with such an annotation... only the "alternateType"s that are defined...dave08
01/19/2023, 12:30 PMdave08
01/19/2023, 12:31 PMToshihiro Nakamura
01/19/2023, 12:34 PMdave08
01/19/2023, 12:37 PM@JvmInline
@KomapperAlternateType(["text", "CLOB"])
value class LongText(value: String)
could possibly have ksp generate the custom type, and at the same time allow validation of what can be used in the @KomapperColumn(alternateType=?)
...?dave08
01/19/2023, 12:40 PMdave08
01/19/2023, 12:41 PMdave08
01/19/2023, 12:44 PM@JvmInline
@KomapperAlternateType(["io.r2dbc.spi.Clob", "java.sql.Clob"])
value class LongText(value: String)
which would make a single facade for alternate types of any implementation...dave08
01/19/2023, 12:46 PMToshihiro Nakamura
01/19/2023, 12:49 PMcould possibly have ksp generate the custom type,That is almost impossible. There are special cases of JDBC/R2DBC APIs that are not suited for automatic generation.
dave08
01/19/2023, 12:51 PMToshihiro Nakamura
01/19/2023, 1:06 PMdave08
01/19/2023, 1:10 PMdave08
01/19/2023, 1:13 PMdave08
01/19/2023, 1:14 PMdave08
01/19/2023, 2:45 PMdave08
01/19/2023, 2:46 PMdave08
01/19/2023, 2:46 PMdave08
01/19/2023, 2:47 PMToshihiro Nakamura
01/21/2023, 5:04 AM