Serialization
Serialization
Strategies and helpers for converting between Kotlin types and the SQLite storage format.
Serialize collections with JSON
You are free to choose your own strategy for storing collections. A common pattern is to serialize the data as JSON. SQLiteNow ships utility helpers so you can keep the SQL clean and reuse adapters.
CREATE TABLE comment
(
id INTEGER PRIMARY KEY NOT NULL,
-- @@{ field=tags, adapter=custom, propertyType=List<String> }
tags TEXT
)
Then, configure your adapters with jsonDecodeFromSqlite and jsonEncodeToSqlite:
val db = SampleDatabase(
dbName = resolveDatabasePath(dbName = "sample.db", appName = "SampleApp"),
migration = VersionBasedDatabaseMigrations(),
commentAdapters = SampleDatabase.CommentAdapters(
sqlColumnToTags = { value -> value?.jsonDecodeFromSqlite() ?: emptyList() },
tagsToSqlColumn = { tags -> tags?.jsonEncodeToSqlite() }
)
)
Serialize timestamps
For absolute timestamps, prefer storing RFC3339 text and mapping it to kotlin.time.Instant.
CREATE TABLE comment
(
id INTEGER PRIMARY KEY NOT NULL,
-- @@{ field=created_at, adapter=custom, propertyType=kotlin.time.Instant }
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now'))
)
val db = SampleDatabase(
dbName = resolveDatabasePath(dbName = "sample.db", appName = "SampleApp"),
migration = VersionBasedDatabaseMigrations(),
commentAdapters = SampleDatabase.CommentAdapters(
sqlColumnToCreatedAt = { value -> Instant.fromRfc3339String(value) },
createdAtToSqlColumn = { instant -> instant.toRfc3339String() },
)
)
Serialize enums with stable values
Prefer serializing enums using stable values instead of names or ordinals. The EnumByValueLookup
helper simplifies mapping between enum constants and their persisted representation.
CREATE TABLE person_address
(
id INTEGER PRIMARY KEY NOT NULL,
-- @@{ field=address_type, adapter=custom, propertyType=AddressType }
address_type TEXT NOT NULL
)
enum class AddressType(val value: String) {
HOME("home"),
WORK("work");
companion object : EnumByValueLookup<String, AddressType>(entries.associateBy { it.value })
}
val db = SampleDatabase(
dbName = resolveDatabasePath(dbName = "sample.db", appName = "SampleApp"),
migration = VersionBasedDatabaseMigrations(),
personAddressAdapters = SampleDatabase.PersonAddressAdapters(
addressTypeToSqlColumn = { it.value },
sqlColumnToAddressType = { value -> AddressType.from(value) },
)
)