diff --git a/kotlin-spark-api/src/main/kotlin/org/jetbrains/kotlinx/spark/api/Encoding.kt b/kotlin-spark-api/src/main/kotlin/org/jetbrains/kotlinx/spark/api/Encoding.kt index 54207bf5..987e83ac 100644 --- a/kotlin-spark-api/src/main/kotlin/org/jetbrains/kotlinx/spark/api/Encoding.kt +++ b/kotlin-spark-api/src/main/kotlin/org/jetbrains/kotlinx/spark/api/Encoding.kt @@ -109,6 +109,11 @@ fun schema(kType: KType): DataType = kotlinEncoderFor(kType).schema() object KotlinTypeInference { + // TODO this hack is a WIP and can give errors + // TODO it's to make data classes get column names like "age" with functions like "getAge" + // TODO instead of column names like "getAge" + var DO_NAME_HACK = false + /** * @param kClass the class for which to infer the encoder. * @param arguments the generic type arguments for the class. @@ -255,22 +260,22 @@ object KotlinTypeInference { currentType == typeOf() -> AgnosticEncoders.`PrimitiveDoubleEncoder$`.`MODULE$` // boxed primitives java / kotlin - currentType == typeOf() -> AgnosticEncoders.`BoxedBooleanEncoder$`.`MODULE$` - currentType == typeOf() -> AgnosticEncoders.`BoxedByteEncoder$`.`MODULE$` - currentType == typeOf() -> AgnosticEncoders.`BoxedShortEncoder$`.`MODULE$` - currentType == typeOf() -> AgnosticEncoders.`BoxedIntEncoder$`.`MODULE$` - currentType == typeOf() -> AgnosticEncoders.`BoxedLongEncoder$`.`MODULE$` - currentType == typeOf() -> AgnosticEncoders.`BoxedFloatEncoder$`.`MODULE$` - currentType == typeOf() -> AgnosticEncoders.`BoxedDoubleEncoder$`.`MODULE$` + currentType.isSubtypeOf() -> AgnosticEncoders.`BoxedBooleanEncoder$`.`MODULE$` + currentType.isSubtypeOf() -> AgnosticEncoders.`BoxedByteEncoder$`.`MODULE$` + currentType.isSubtypeOf() -> AgnosticEncoders.`BoxedShortEncoder$`.`MODULE$` + currentType.isSubtypeOf() -> AgnosticEncoders.`BoxedIntEncoder$`.`MODULE$` + currentType.isSubtypeOf() -> AgnosticEncoders.`BoxedLongEncoder$`.`MODULE$` + currentType.isSubtypeOf() -> AgnosticEncoders.`BoxedFloatEncoder$`.`MODULE$` + currentType.isSubtypeOf() -> AgnosticEncoders.`BoxedDoubleEncoder$`.`MODULE$` // boxed primitives scala - currentType == typeOf() -> AgnosticEncoders.`BoxedBooleanEncoder$`.`MODULE$` - currentType == typeOf() -> AgnosticEncoders.`BoxedByteEncoder$`.`MODULE$` - currentType == typeOf() -> AgnosticEncoders.`BoxedShortEncoder$`.`MODULE$` - currentType == typeOf() -> AgnosticEncoders.`BoxedIntEncoder$`.`MODULE$` - currentType == typeOf() -> AgnosticEncoders.`BoxedLongEncoder$`.`MODULE$` - currentType == typeOf() -> AgnosticEncoders.`BoxedFloatEncoder$`.`MODULE$` - currentType == typeOf() -> AgnosticEncoders.`BoxedDoubleEncoder$`.`MODULE$` + currentType.isSubtypeOf() -> AgnosticEncoders.`BoxedBooleanEncoder$`.`MODULE$` + currentType.isSubtypeOf() -> AgnosticEncoders.`BoxedByteEncoder$`.`MODULE$` + currentType.isSubtypeOf() -> AgnosticEncoders.`BoxedShortEncoder$`.`MODULE$` + currentType.isSubtypeOf() -> AgnosticEncoders.`BoxedIntEncoder$`.`MODULE$` + currentType.isSubtypeOf() -> AgnosticEncoders.`BoxedLongEncoder$`.`MODULE$` + currentType.isSubtypeOf() -> AgnosticEncoders.`BoxedFloatEncoder$`.`MODULE$` + currentType.isSubtypeOf() -> AgnosticEncoders.`BoxedDoubleEncoder$`.`MODULE$` // leaf encoders currentType.isSubtypeOf() -> AgnosticEncoders.`StringEncoder$`.`MODULE$` @@ -482,7 +487,8 @@ object KotlinTypeInference { val writeMethodName = (prop as? KMutableProperty<*>)?.setter?.javaMethod?.name DirtyProductEncoderField( - name = paramName, + doNameHack = DO_NAME_HACK, + columnName = paramName, readMethodName = readMethodName, writeMethodName = writeMethodName, encoder = encoder, @@ -535,9 +541,10 @@ object KotlinTypeInference { } internal open class DirtyProductEncoderField( - private val name: String, // the name used for the column + private val columnName: String, // the name used for the column private val readMethodName: String, // the name of the method used to read the value private val writeMethodName: String?, + private val doNameHack: Boolean, encoder: AgnosticEncoder<*>, nullable: Boolean, metadata: Metadata = Metadata.empty(), @@ -554,12 +561,15 @@ internal open class DirtyProductEncoderField( /** * This dirty trick only works because in [SerializerBuildHelper], [ProductEncoder] - * creates an [Invoke] using [name] first and then calls [name] again to retrieve + * creates an [Invoke] using [columnName] first and then calls [columnName] again to retrieve * the name of the column. This way, we can alternate between the two names. */ override fun name(): String = - if (i++ % 2 == 0) readMethodName - else name + when (doNameHack) { + true -> if (i++ % 2 == 0) readMethodName else columnName + false -> readMethodName + } + override fun canEqual(that: Any?): Boolean = that is AgnosticEncoders.EncoderField