dave08
11/15/2021, 2:11 PM/** Creates an enumeration column, with the specified [name], for storing enums of type [klass] by the result of [kprop]. */
fun <T : Enum<T>> Table.enumerationByField(name: String, klass: KClass<T>, kprop: KProperty1<T, Int>): Column<T> =
    registerColumn(name, EnumerationColumnByFieldType(klass, kprop))
/**
 * Enumeration column for storing enums of type [klass] by the result of [kprop].
 */
class EnumerationColumnByFieldType<T : Enum<T>>(
    /** Returns the enum class used in this column type. */
    val klass: KClass<T>,
    val kprop: KProperty1<T, Int>
) : ColumnType() {
    override fun sqlType(): String = currentDialect.dataTypeProvider.integerType()
    @Suppress("UNCHECKED_CAST")
    override fun valueFromDB(value: Any): T = when (value) {
        is Number -> klass.java.enumConstants!!.first { kprop.get(it) == value }
        is Enum<*> -> value as T
        else -> error("$value of ${value::class.qualifiedName} is not valid for enum ${klass.simpleName}")
    }
    override fun notNullValueToDB(value: Any): Int = when (value) {
        is Int -> value
        is Enum<*> -> kprop.get(value as T)
        else -> error("$value of ${value::class.qualifiedName} is not valid for enum ${klass.simpleName}")
    }
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false
        if (!super.equals(other)) return false
        other as EnumerationColumnType<*>
        if (klass != other.klass) return false
        return true
    }
    override fun hashCode(): Int {
        var result = super.hashCode()
        result = 31 * result + klass.hashCode()
        return result
    }
}