DynamicTypes
The dynamic_dto types this client knows, and what you do with them: register, and - where strategy or the class leaves the question open - wrap.
Registration is explicit and states the name, rather than deriving it from the class. A discriminator is stored in the data: derived from the class, renaming the class would change it silently and every row written before the rename would stop being readable, at runtime, on whichever query reached one first. The name can come from DynamicallyMappable instead, which is a declaration rather than a derivation and moves with the class rather than tracking it.
What registration buys is both directions. A dynamic_dto column carrying a registered name comes back as that class, and a column carrying several different names comes back as whatever supertype was asked for - which is how one column holds a sealed hierarchy. Going the other way, an instance of a registered class is written as a dynamic_dto without being wrapped, on the terms strategy sets.
db.dynamicTypes.install() // or put DYNAMIC_DTO_DDL in a migration
db.dynamicTypes.register<LandGrant>("land_grant")
db.dynamicTypes.register<MilitaryPension>("military_pension")
db.insertInto("veterans").values(listOf("id", "benefit"))
.update("id" to 1, "benefit" to LandGrant("Gallia", 120))
val benefits: List<Benefit> = db.select("benefit").from("veterans").fetchFields()Registration is global to the database the client is connected to, the driver's type registry being keyed that way, so it belongs at startup and not per request.
Constructors
Properties
The contextual serializers writing each registered enum under the label PostgreSQL holds, rather than under the Kotlin constant's own name.
How payloads are read and written. The default is octaviusJson, which is strict - a payload carrying a field the class does not declare is an error rather than something dropped - and carries octaviusSerializersModule, so a @Contextual BigDecimal or date keeps in JSON what it would have kept in a column. Where the payload is built in SQL with jsonb_build_object, its keys have to match the Kotlin property names - supply a Json with JsonNamingStrategy.SnakeCase if the SQL side names them the way SQL usually does, and put that module on it too.
When an unwrapped instance of a registered class is written as a dynamic_dto.
Functions
The Json a conversion should run on: the query's own where one was given, the client's otherwise, and either way with the enums registered right now folded in.
A write converter for these registrations that encodes payloads with json rather than with the client's own, and the mirror of resultConverter.
Registers T under the name its DynamicallyMappable declares.
Registers kClass under the name its DynamicallyMappable declares.
Registers kClass by looking its serializer up from its own type.
Registers kClass with a serializer supplied by the caller.
The registration for an exact class, which is how a value being written finds its own.
A read converter for these registrations that decodes payloads with json rather than with the client's own.
Wraps value for writing, saying that the dynamic_dto form is the one meant.