Skip to content

Instantly share code, notes, and snippets.

@LizAinslie
Last active February 25, 2025 00:32
Show Gist options
  • Save LizAinslie/b45c39eba909cac1f93d33ab48e09e2a to your computer and use it in GitHub Desktop.
Save LizAinslie/b45c39eba909cac1f93d33ab48e09e2a to your computer and use it in GitHub Desktop.
Use kotlin.uuid.Uuid as an index in Exposed, instead of java.util.UUID
@file:OptIn(ExperimentalUuidApi::class)
import org.jetbrains.exposed.dao.Entity
import org.jetbrains.exposed.dao.EntityClass
import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.dao.id.IdTable
import org.jetbrains.exposed.sql.Column
import org.jetbrains.exposed.sql.ColumnType
import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.Table.Dual.clientDefault
import org.jetbrains.exposed.sql.vendors.DataTypeProvider
import org.jetbrains.exposed.sql.vendors.MariaDBDialect
import org.jetbrains.exposed.sql.vendors.currentDialect
import java.sql.ResultSet
import java.util.UUID
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid
import kotlin.uuid.toJavaUuid
import kotlin.uuid.toKotlinUuid
abstract class KotlinUuidTable(name: String) : IdTable<Uuid>(name) {
final override val id = kotlinUuid("id").autoGenerate().entityId()
final override val primaryKey = PrimaryKey(id)
}
abstract class KotlinUuidEntity(id: EntityID<Uuid>) : Entity<Uuid>(id)
abstract class KotlinUuidEntityClass<out E : KotlinUuidEntity>(
table: IdTable<Uuid>,
entityType: Class<E>? = null,
entityCtor: ((EntityID<Uuid>) -> E)? = null
) : EntityClass<Uuid, E>(table, entityType, entityCtor)
class UuidColumnType : ColumnType<Uuid>() {
override fun sqlType(): String = currentDialect.dataTypeProvider.uuidType()
override fun valueFromDB(value: Any): Uuid = when {
value is Uuid -> value
value is UUID -> value.toKotlinUuid()
value is ByteArray -> Uuid.fromByteArray(value)
value is String && value.matches(uuidRegexp) -> Uuid.parse(value)
value is String -> Uuid.fromByteArray(value.toByteArray())
else -> error("Unexpected value of type Uuid: $value of ${value::class.qualifiedName}")
}
override fun notNullValueToDB(value: Uuid): Any = currentDialect.dataTypeProvider.uuidToDB(value)
override fun nonNullValueToString(value: Uuid): String = "'$value'"
override fun readObject(rs: ResultSet, index: Int): Any? = when (currentDialect) {
is MariaDBDialect -> rs.getBytes(index)
else -> super.readObject(rs, index)
}
companion object {
private val uuidRegexp =
Regex("[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}", RegexOption.IGNORE_CASE)
}
}
fun DataTypeProvider.uuidToDB(value: Uuid): Any = uuidToDB(value.toJavaUuid()) // bruh
fun Table.kotlinUuid(name: String): Column<Uuid> = registerColumn(name, UuidColumnType())
/** Uuid column will auto generate its value on a client side just before an insert. */
fun Column<Uuid>.autoGenerate(): Column<Uuid> = clientDefault { Uuid.random() }
@LizAinslie
Copy link
Author

jdbc my behated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment