SQLDelight Boolean mapping is a common requirement because not every SQL dialect stores Boolean values in the same way. SQLite frequently represents a flag with integer values, while application code wants a Kotlin Boolean. A clear custom type and adapter can bridge that difference without spreading conversions through the codebase.
Choose a stable stored representation
For SQLite, use a documented integer convention such as 0 for false and 1 for true. Add a constraint when appropriate so unexpected values cannot enter the table through another tool or older application version.
CREATE TABLE preference (
key TEXT NOT NULL PRIMARY KEY,
enabled INTEGER AS Boolean NOT NULL
);Create a ColumnAdapter
The adapter converts the database value to Kotlin and back. Match the SQL storage type used by the generated interface. Keep the conversion strict enough to catch corrupt values but compatible with any legacy representation that must still be read.
val booleanAdapter = object : ColumnAdapter<Boolean, Long> {
override fun decode(databaseValue: Long) = databaseValue != 0L
override fun encode(value: Boolean) = if (value) 1L else 0L
}Register the adapter at database creation
Generated table adapters are supplied when constructing the database. Centralize this wiring in one factory so tests and every platform use the same conversion.
Write round-trip tests
- Insert true and confirm the stored/generated value reads as true.
- Insert false and confirm it reads as false.
- Test default values created by SQL.
- Test legacy non-zero values only if they are valid for the product.
- Confirm migrations preserve flags when a column is renamed or rebuilt.
Consider nullable flags carefully
A nullable Boolean creates three states: true, false and unknown. Use it only when the third state has a real domain meaning. Otherwise prefer NOT NULL with an explicit default so generated Kotlin types remain simple.
Do not duplicate conversion logic
Avoid manual value == 1L checks throughout repositories. The adapter exists to establish one authoritative mapping between SQL storage and Kotlin domain values.