Skip to content

Commit cd32868

Browse files
oyvindbergclaude
andcommitted
Add SQLite support
Wires SQLite (via xerial sqlite-jdbc + foundations-jdbc RC6) into typr as a first-class dialect alongside PostgreSQL, MariaDB, DuckDB, Oracle, SQL Server, and DB2. ## Why SQLite is the most-deployed database on earth and an obvious target for an embedded-DB code generator. Foundations RC6 now ships a full SqliteTypes catalogue (integer affinities with concrete Java mappings, REAL/NUMERIC, TEXT including VARCHAR(n)/CHAR(n), BLOB, date/time as ISO-8601 TEXT, UUID, JSON) plus SqliteConfig with in-memory and file-backed modes, so the typr work is to wire it through the codegen. ## Core wiring - `typr-dsl`: Dialect.SQLITE (double-quote idents, IS / IS NOT null-safe equality, standard LIMIT/OFFSET, CAST() casts). Scala wrapper re-export. - `db.SqliteType` ADT modelling every concrete type SqliteTypes exposes. - `DbType.SQLite` + product/driver detection + TypoDataSource.hikariSqlite{, InMemory,File}; DatabaseKind.SQLITE branch in hikari(). - `SqliteAdapter` (codegen layers 1-5): supportsReturning=true, ON CONFLICT upserts, no native arrays, no schemas. - `internal/sqlite/` package: metadata extraction via raw JDBC against sqlite_master + PRAGMA table_info / pragma_foreign_key_list / pragma_index_list; sqlglot bridge for .sql file analysis; type mapper that follows SQLite's affinity rules and matches the foundations SqliteTypes aliases (BIGINT, INT8, VARCHAR, CLOB, ...). ## Dispatch sites Every per-DbType match got a SQLite arm: MetaDb, InstanceRequirements, generate.scala (incl. PreciseConstraint cases for VarChar/Char/Decimal), DbLibFoundations (folded into the SqlServer|DB2|SQLite no-arrays branch), TypeMapperJvmNew (baseType + precise), TypeMatcher, TypeCompatibilityChecker, ComputedTestInserts, SqlFileReader, TypeSuggester. ## CLI ParsedBoundary/Source.Sqlite, convertSqliteBoundary, fetchSqliteBoundary, generateSqliteForOutput. MetaDbFetch, ConnectionTest, LoadedSource, plus the TUI screens (SchemaPicker, SourceForm, SourceList, MainMenu). The xerial sqlite-jdbc driver runs only the first statement of a multi- statement string in Statement.execute(), so the CLI and the test helpers split on `;` (outside `'...'` literals, ignoring `-- ...` comments) before loading a schema. See the executeBatch helper in Generate.scala. ## Config schema Added `sqlite` to the boundary type enum + a sqliteBoundary $def in typr-config.schema.json. Regenerated SqliteBoundary.scala via `bleep run generate-config-types`. ## Test infrastructure - `sql-init/sqlite/00-schema.sql` exercises every affinity + composite PK, composite FK, UNIQUE, views, precision_types[_null]. - `sql-scripts/sqlite/*.sql`: five representative queries (parameterised selects, group-by, delete, optional params) — analysed through sqlglot with the SQLite schema for type lineage; generated repos resolve column parameters back to typed IDs and user-picked types (e.g. CustomersId, Email) rather than raw primitives. - `testers/sqlite/{java,kotlin,scala}/` with SqliteTestHelper and BasicCrudTest. All 10 tests pass (4 Java, 3 Kotlin, 3 Scala). - `bleep.yaml`: three tester project entries + `org.xerial:sqlite-jdbc: 3.46.1.3` added to typr-codegen. - `typr.yaml`: new `sqlite` boundary + sqlite-java / sqlite-kotlin / sqlite-scala outputs. ## Showcase Wired SQLite into ShowcaseSchema + GeneratedShowcase. Every per-engine dbSpecificCols match (employee, product, customer, address, customer_order, project) and every type helper (varchar/int/bool/decimal/date/timestamp/ bigint) got a SQLite arm. The showcase covers SQLite's convenience types (Json, Uuid, Blob, Text) rather than leaving columns empty. Running `bleep run generate-showcase` produces ~318 SQLite files under site/showcase-generated/sqlite/{java,kotlin,scala}/ (the dir is gitignored and regenerated by the publish pipeline). ## Docs Surfaced SQLite alongside other dialects throughout docs-typr/ — landing page, comparison, configuration, setup, every type-safety concept page (arrays, collection-types, date-time with a SQLite ISO-8601 note, struct-types, maps, domains with a bimap example, enums, precise-types). date-time and setup got SQLite-specific callouts (ISO-8601 storage, foreign-keys-off-by-default). Same for the legacy /docs/ tree and unified-types pages. site/src landing JS updated to seven engines. contributing-add-a-dialect.md at the repo root (NOT on the docs site) distils the touch-point checklist learned here, so the next dialect is faster. ## Cleanup - Removed the inline google-java-format step from GeneratedShowcase.scala (`bleep fmt` already runs gjf 1.33.0; the duplicate step was the source of a JDK 25 NoSuchMethodError). - Deleted dead `CodeSample` component + `codeSamples.js` data file. The generator script the data file claimed to be auto-generated by was never committed to any branch; the component has zero usages. Superseded by ShowcaseSnippet + showcaseFiles.js (webpack require.context) ages ago. - Dropped the stale `site/docs-jdbc/` reference from CLAUDE.md — foundations was extracted to its own repo. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent f8e69cd commit cd32868

379 files changed

Lines changed: 25459 additions & 1081 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CLAUDE.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ Typr is a database code generator that creates type-safe JVM code from database
1515
- **DuckDB** - embedded analytical database
1616
- **SQL Server** - T-SQL specific features
1717
- **Oracle** - including OBJECT and MULTISET types
18+
- **DB2** - including distinct types
19+
- **SQLite** - embedded, type-affinity model with foundations SqliteTypes aliases
1820

1921
## Foundations JDBC
2022

21-
`foundations-jdbc` is a standalone JDBC wrapper library with perfect type modeling for all supported databases. See `site/docs-jdbc/` for full documentation.
23+
`foundations-jdbc` is a standalone JDBC wrapper library with perfect type modeling for all supported databases. It lives in its own repository (`dev.typr.foundations:foundations-jdbc`, currently RC6) — typr depends on it as a Maven artifact, not as a submodule. Its docs ship from that repo, not from this one.
2224

2325
## Build System
2426

@@ -143,6 +145,7 @@ All databases use `sql-init/{database}/` for schema initialization, mounted to `
143145
- **SQL Server**: `sql-init/sqlserver/` - Custom entrypoint `00-entrypoint.sh` starts server and runs SQL
144146
- **DB2**: `sql-init/db2/` - Shell script `00-run-sql.sh` runs SQL files
145147
- **DuckDB**: `sql-init/duckdb/` - Loaded by generation script (embedded database, no docker)
148+
- **SQLite**: `sql-init/sqlite/` - Loaded by generation script (embedded database, no docker)
146149

147150
### Ensuring Databases Are Up to Date
148151

@@ -296,6 +299,8 @@ typr/ # Main code generator
296299
│ ├── mariadb/ # MariaDB adapter
297300
│ ├── oracle/ # Oracle adapter
298301
│ ├── duckdb/ # DuckDB adapter
302+
│ ├── db2/ # DB2 adapter
303+
│ ├── sqlite/ # SQLite adapter
299304
│ └── sqlserver/ # SQL Server adapter
300305
│ └── openapi/ # OpenAPI code generation
301306
@@ -308,6 +313,8 @@ testers/ # Integration test projects
308313
├── duckdb/ # DuckDB testers (java, kotlin, scala)
309314
├── oracle/ # Oracle testers (java, kotlin, scala)
310315
├── sqlserver/ # SQL Server testers (java, kotlin, scala)
316+
├── db2/ # DB2 testers (java, kotlin, scala)
317+
├── sqlite/ # SQLite testers (java, kotlin, scala)
311318
└── openapi/ # OpenAPI framework testers
312319
├── java/ # JAX-RS, Spring, Quarkus
313320
├── kotlin/ # JAX-RS, Spring, Quarkus
@@ -332,14 +339,18 @@ sql-init/ # Schema files (mounted to Docker)
332339
├── mariadb/ # MariaDB schemas
333340
├── oracle/ # Oracle schemas
334341
├── sqlserver/ # SQL Server schemas
335-
└── duckdb/ # DuckDB schemas (loaded by script)
342+
├── duckdb/ # DuckDB schemas (loaded by script)
343+
├── db2/ # DB2 schemas
344+
└── sqlite/ # SQLite schemas (loaded by script)
336345
337346
sql-scripts/ # SQL query files for code generation
338347
├── postgres/ # PostgreSQL SQL queries
339348
├── mariadb/ # MariaDB SQL queries
340349
├── sqlserver/ # SQL Server SQL queries
341350
├── oracle/ # Oracle SQL queries
342-
└── duckdb/ # DuckDB SQL queries
351+
├── duckdb/ # DuckDB SQL queries
352+
├── db2/ # DB2 SQL queries
353+
└── sqlite/ # SQLite SQL queries
343354
344355
typr-internal-sql/ # Internal SQL for Typr codegen
345356
```

bleep.yaml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,42 @@ projects:
149149
sources:
150150
- ./generated-and-checked-in
151151
- ./src/scala
152+
testers/sqlite/java:
153+
dependencies:
154+
- com.fasterxml.jackson.core:jackson-annotations:2.17.2
155+
- com.fasterxml.jackson.core:jackson-databind:2.17.2
156+
- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.17.2
157+
- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2
158+
- com.github.sbt:junit-interface:0.13.3
159+
- junit:junit:4.13.2
160+
- org.xerial:sqlite-jdbc:3.46.1.3
161+
dependsOn: typr-dsl
162+
isTestProject: true
163+
java:
164+
options: -proc:none
165+
platform:
166+
name: jvm
167+
sources:
168+
- ./generated-and-checked-in
169+
- ./src/java
170+
testers/sqlite/kotlin:
171+
dependencies: org.xerial:sqlite-jdbc:3.46.1.3
172+
extends: template-kotlin-db-tester
173+
testers/sqlite/scala:
174+
dependencies:
175+
- com.fasterxml.jackson.core:jackson-annotations:2.17.2
176+
- com.fasterxml.jackson.core:jackson-databind:2.17.2
177+
- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.17.2
178+
- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2
179+
- com.github.sbt:junit-interface:0.13.3
180+
- junit:junit:4.13.2
181+
- org.xerial:sqlite-jdbc:3.46.1.3
182+
dependsOn: typr-dsl-scala
183+
extends: template-scala-3
184+
isTestProject: true
185+
sources:
186+
- ./generated-and-checked-in
187+
- ./src/scala
152188
testers/duckdb/java:
153189
dependencies:
154190
- com.fasterxml.jackson.core:jackson-annotations:2.17.2
@@ -937,6 +973,7 @@ projects:
937973
- org.playframework.anorm::anorm:2.7.0
938974
- org.postgresql:postgresql:42.7.3
939975
- org.slf4j:slf4j-nop:2.0.13
976+
- org.xerial:sqlite-jdbc:3.46.1.3
940977
dependsOn: typr-dsl-scala
941978
extends:
942979
- template-scala-3

contributing-add-a-dialect.md

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# Adding a new database dialect
2+
3+
A walkthrough of every file you need to touch, in roughly the order you should touch them. The
4+
SQLite support PR is the cleanest recent reference — every step below points at a SQLite analogue.
5+
6+
## 0. What the upstream `foundations-jdbc` library must already provide
7+
8+
`typr` is the code generator; the runtime types and codecs live in the external
9+
`dev.typr.foundations:foundations-jdbc` library. Before you start, make sure that library exposes:
10+
11+
- A typed types catalogue, e.g. `dev.typr.foundations.XxxTypes` with one entry per declarable type
12+
(integer/varchar/decimal/date/…). Each entry is a `XxxType<JvmType>` carrying the read/write
13+
codec and JSON codec.
14+
- `dev.typr.foundations.connect.XxxConfig` for building a JDBC connection, and
15+
`DatabaseKind.XXX` enum value.
16+
- Scala and Kotlin wrappers: `dev.typr.foundationssc.XxxTypes` and
17+
`dev.typr.foundationskt.XxxTypes`.
18+
19+
If any of these are missing, send the PR to foundations first.
20+
21+
## 1. Add a `Dialect` entry
22+
23+
File: `typr-dsl/src/java/dev/typr/dsl/Dialect.java` — the DSL's per-dialect SQL grammar bits
24+
(identifier quoting, casts, null-safe comparison, LIMIT/OFFSET, tuple-IN support).
25+
26+
The `Dialect` interface has reasonable defaults for everything except `bigint()`, `quoteIdent()`,
27+
`escapeIdent()`, `typeCast()`, `columnRef()`, `nullSafeEquals()`, `nullSafeNotEquals()` — override
28+
just what differs from the default (PostgreSQL-shaped) behaviour.
29+
30+
Re-export it in the Scala wrapper at
31+
`typr-dsl-scala/src/scala/dev/typr/dslsc/package.scala`'s `object Dialect`.
32+
33+
(Kotlin can use the Java static field directly — no wrapper needed.)
34+
35+
## 2. Define the `db.XxxType` ADT
36+
37+
File: `typr-codegen/src/scala/typr/db.scala`.
38+
39+
Add a `sealed trait XxxType extends Type` plus one `case object` (or `case class` for parameterised
40+
types like `Decimal(precision, scale)`) per concrete declarable type. Add `XxxType` to the
41+
`Unknown` mixin trait list at the bottom — that's the fallback for unrecognised JDBC type names.
42+
43+
## 3. Add `DbType.Xxx` + connection plumbing
44+
45+
Files:
46+
47+
- `typr-codegen/src/scala/typr/DbType.scala` — add `case object Xxx extends DbType` returning your
48+
adapter, plus a branch in `detect(...)` and `detectFromDriver(...)`.
49+
- `typr-codegen/src/scala/typr/TypoDataSource.scala` — add a `hikariXxx*(...)` constructor and a
50+
`DatabaseKind.XXX` branch in `hikari(...)`.
51+
52+
## 4. Write the codegen adapter
53+
54+
File: `typr-codegen/src/scala/typr/internal/codegen/XxxAdapter.scala`.
55+
56+
Mirror `DuckDbAdapter` (closest in spirit for most embedded DBs) or `Db2Adapter` (single-schema,
57+
no native arrays). Five layers:
58+
59+
1. **SQL syntax**`quoteIdent`, `typeCast`, the various `columnReadCast`/`columnWriteCast` (most
60+
dialects can return `Code.Empty`).
61+
2. **Runtime types** — point at `XxxTypes` / `XxxType` / `XxxText` and pick a `typeFieldName`
62+
(e.g. `xxxType`).
63+
3. **Capabilities**`supportsArrays`, `supportsReturning`, `supportsCopyStreaming`, the upsert
64+
strategy.
65+
4. **SQL templates** — upsert (`ON CONFLICT` vs `MERGE`), conflict update clause, returning clause.
66+
5. **Schema DDL**`dropSchemaDdl` / `createSchemaDdl`. For dialects without schemas (SQLite,
67+
embedded DBs), return a SQL comment.
68+
69+
## 5. Write the metadata-extraction package
70+
71+
Directory: `typr-codegen/src/scala/typr/internal/xxx/`. Four files:
72+
73+
- `XxxJdbcMetadata.scala` — wraps `ResultSetMetaData` into `MetadataColumn`. This is essentially
74+
identical across dialects — copy `DuckDbJdbcMetadata` and rename.
75+
- `XxxTypeMapperDb.scala` — maps the declared/JDBC type name string to a `db.XxxType`. Read your
76+
database's reference for type aliases; many dialects accept synonyms (BIGINT/INT8/LONG/…).
77+
- `XxxSqlFileMetadata.scala` — analyses user-supplied `.sql` files using sqlglot. Copy
78+
`DuckDbSqlFileMetadata`; the only dialect-specific bits are (a) how you read the schema (the
79+
catalogue queries) and (b) the sqlglot `dialect` string.
80+
- `XxxMetaDb.scala` — reads tables/columns/PKs/FKs/uniques/views from the database catalogue.
81+
Look at how your DB exposes metadata (information_schema, system catalog views, or PRAGMAs) and
82+
shape the queries to fit. Return a `MetaDb(dbType, relations, enums = Nil, domains = Nil, …)`.
83+
84+
## 6. Wire all dispatch sites
85+
86+
These are the files that have one `case DbType.X => …` arm per dialect. Each new dialect needs an
87+
arm added everywhere:
88+
89+
- `typr-codegen/src/scala/typr/MetaDb.scala` — both the `typeMapperDb` match and the `fromDb`
90+
match.
91+
- `typr-codegen/src/scala/typr/internal/InstanceRequirements.scala` — the heuristic name guess
92+
and the `dbTypeFieldNameFor` map.
93+
- `typr-codegen/src/scala/typr/internal/generate.scala` — the `databaseName` string used as a
94+
TypeDefinition discriminator, **plus** the precision-types case list near the bottom that emits
95+
`PreciseConstraint.*` for `VarChar(Some(n))` etc.
96+
- `typr-codegen/src/scala/typr/internal/codegen/DbLibFoundations.scala` — selectByIds /
97+
deleteByIds bodies. If your DB has no native arrays (most non-Postgres do), fold it into the
98+
existing `case DbType.SqlServer | DbType.DB2 | …` arms rather than copy-pasting.
99+
- `typr-codegen/src/scala/typr/internal/sqlfiles/SqlFileReader.scala` — dispatch to your
100+
`XxxSqlFileMetadata`.
101+
- `typr-codegen/src/scala/typr/internal/TypeMapperJvmNew.scala` — both the `baseType` and the
102+
precise-types match. (`TypeMapperJvmOld` is PostgreSQL-only legacy; skip.)
103+
- `typr-codegen/src/scala/typr/internal/TypeMatcher.scala``typeName` (for the matcher's
104+
per-column name string).
105+
- `typr-codegen/src/scala/typr/internal/TypeCompatibilityChecker.scala` — add a `CompatibilityClass`
106+
arm for every Java-equivalent class (String/Boolean/Int/Long/…) so cross-dialect Bridge type
107+
matching works.
108+
- `typr-codegen/src/scala/typr/internal/ComputedTestInserts.scala` — the `case`s for max-length
109+
detection on text columns.
110+
- `typr/src/scala/typr/bridge/TypeSuggester.scala` — group types into the "text/integer/numeric/
111+
boolean/temporal/uuid/json" buckets the bridge UI uses.
112+
113+
## 7. CLI wiring
114+
115+
- `typr-config.schema.json` — add `"xxx"` to the boundary `type` enum and add a `xxxBoundary`
116+
definition (use `duckdbBoundary` as a template for embedded DBs, or `databaseBoundary` for
117+
server-based ones).
118+
- Run `bleep run generate-config-types` to regenerate the typed config classes
119+
(`XxxBoundary.scala` shows up under `typr-codegen/generated-and-checked-in-jsonschema/`).
120+
- `typr/src/scala/typr/cli/config/ConfigParser.scala` — add `Some("xxx") => …` arms for source
121+
*and* boundary parsing, and add `ParsedSource.Xxx` / `ParsedBoundary.Xxx` cases.
122+
- `typr/src/scala/typr/cli/config/ConfigToOptions.scala``convertXxxBoundary` + `convertXxxSource`.
123+
- `typr/src/scala/typr/cli/commands/Generate.scala``fetchXxxBoundary`, `fetchXxxSource`,
124+
`generateXxxForOutput`, plus the two dispatch sites in `runTwoPhaseGeneration`. Watch for any
125+
driver-specific quirks loading the schema (SQLite's xerial driver, for example, can't run
126+
multi-statement strings in a single `execute()` — the SQLite path splits on `;` first).
127+
- `typr/src/scala/typr/cli/app/MetaDbFetch.scala` — add a `ParsedSource.Xxx` arm + `fetchXxx`.
128+
- `typr/src/scala/typr/cli/app/ConnectionTest.scala` — add a `ParsedSource.Xxx` arm + `tryXxx`,
129+
and include `Xxx` in `isTestable`'s pattern.
130+
- `typr/src/scala/typr/cli/app/LoadedSource.scala` — include `ParsedSource.Xxx` in the database
131+
pattern arm.
132+
- The TUI screens (`SchemaPicker`, `SourceForm`, `SourceList`, `MainMenu`) — fold the new kind
133+
string into the existing `"duckdb" | "xxx"` cases for path-style sources, or use the database
134+
patterns for host/port sources.
135+
136+
## 8. Build wiring
137+
138+
- `bleep.yaml` — add three tester project entries (`testers/xxx/java`, `testers/xxx/kotlin`,
139+
`testers/xxx/scala`), each with the right JDBC driver dependency. Also add the driver to the
140+
`typr-codegen` project's dependencies so the CLI can connect.
141+
- `typr.yaml` — add a boundary entry (with `schema_sql`, `sql_scripts`, `path` or host/port) and
142+
three outputs (`xxx-java`, `xxx-kotlin`, `xxx-scala`).
143+
144+
## 9. Test data + scripts
145+
146+
- `sql-init/xxx/00-schema.sql` — exercise every column type your `db.XxxType` ADT models, plus
147+
composite PK, composite FK, UNIQUE, views, and `precision_types[_null]` for precise-type
148+
generation.
149+
- `sql-scripts/xxx/*.sql` — half a dozen parameterised queries covering SELECT, INSERT-with-
150+
RETURNING, UPDATE, DELETE, JOIN.
151+
152+
## 10. Testers
153+
154+
Under `testers/xxx/{java,kotlin,scala}` add a `src/{lang}/testdb/XxxTestHelper` and a
155+
`BasicCrudTest` that exercises the generated repos. Mirror `testers/duckdb/{java,kotlin,scala}`
156+
if your driver supports multi-statement `execute()`, you can use `connectionInitSql(schema)`
157+
directly; otherwise split the schema yourself (SQLite shows this pattern).
158+
159+
## 11. Generate, fmt, test
160+
161+
```bash
162+
bleep run typr -- generate --source xxx --accept
163+
bleep fmt
164+
bleep test testers/xxx
165+
```
166+
167+
## Things that bit me on SQLite specifically
168+
169+
- **Single connection, in-memory.** `:memory:` databases live inside one JDBC connection; opening
170+
a second connection gives you an empty DB. Foundations' `singleConnectionMode()` handles the
171+
reuse but `connectionInitSql` runs once via a *single* `stmt.execute(...)` — for drivers that
172+
don't accept multi-statement strings (xerial SQLite is one) the schema only partially loads.
173+
The fix is to bypass `connectionInitSql` and run statements one at a time during a one-shot
174+
init, then switch the transactor to `rollbackOnly()` for tests.
175+
- **No schemas.** Force `SchemaMode.SingleSchema("main")` in your `convertXxxBoundary`, and emit
176+
`RelationName(None, name)` in metadata. SQLite's `main` namespace isn't really a schema.
177+
- **Type affinity, not declared type.** SQLite stores values in five storage classes regardless
178+
of column declaration — your `XxxTypeMapperDb` needs to match common synonyms (BIGINT, INT8,
179+
INT2, VARCHAR(n), CLOB, …) to a specific `db.XxxType` so the codecs round-trip. The full
180+
affinity-substring fallback at the bottom of `SqliteTypeMapperDb` handles "anything goes" cases
181+
(`VARYING CHARACTER`, `DOUBLE PRECISION`, etc.).
182+
- **Foreign keys off by default.** SQLite needs `PRAGMA foreign_keys = ON` per connection. The
183+
foundations `SqliteConfig.Builder.foreignKeys(true)` sets it via a driver property, but if
184+
you're opening raw JDBC for tests, set it yourself.

site/docs-typr/boundaries/databases/readme.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ The compiler checks your application code. But at the database boundary, you're
2222

2323
Typr DB treats your database schema as the source of truth:
2424

25-
1. **Read your schema** from PostgreSQL, MariaDB, Oracle, SQL Server, DuckDB, or DB2
25+
1. **Read your schema** from PostgreSQL, MariaDB, Oracle, SQL Server, DuckDB, DB2, or SQLite
2626
2. **Generate typed code** for every table, view, and relationship
2727
3. **Enforce at compile time** that all database access uses the correct types
2828

@@ -57,6 +57,7 @@ When you change a column, rename a table, or modify a relationship—the compile
5757
| SQL Server | Full support |
5858
| DuckDB | Full support |
5959
| IBM DB2 | Full support |
60+
| SQLite | Full support |
6061

6162
## Supported Languages
6263

site/docs-typr/boundaries/databases/setup.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ For complete installation and configuration instructions, see the [Getting Start
1919
| Oracle | Full support including OBJECT and MULTISET types |
2020
| DuckDB | Full support for embedded analytical workloads |
2121
| IBM DB2 | Full support including distinct types |
22+
| SQLite | Full support for embedded workloads — every type affinity, RETURNING, ON CONFLICT upserts |
23+
24+
:::tip SQLite foreign keys
25+
SQLite parses `REFERENCES` clauses but doesn't enforce them unless `PRAGMA foreign_keys = ON` is set on each connection. The `SqliteConfig.Builder.foreignKeys(true)` helper writes this as a driver property so every pooled connection inherits it — turn it on explicitly if you're building a `SqliteConfig` by hand.
26+
:::
2227

2328
### Configuration Example
2429

@@ -54,6 +59,7 @@ Each database has unique features that Typr models with full fidelity:
5459
- **Oracle**: OBJECT types, nested tables, MULTISET
5560
- **SQL Server**: Alias types, table-valued parameters
5661
- **DuckDB**: Nested types, structs, lists
62+
- **SQLite**: Type-affinity model with aliases (BIGINT/INT8/VARCHAR/CLOB...), ISO-8601 date/time as TEXT, no schemas
5763

5864
See [Type Safety](/typr/boundaries/databases/type-safety/id-types) for details on how these are represented in generated code.
5965

site/docs-typr/boundaries/databases/type-safety/arrays.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Typr provides full support for array and list types across databases that suppor
1818
| Oracle | VARRAY, Nested Table | Via collection types |
1919
| SQL Server | - | No array support |
2020
| DB2 | - | No array support |
21+
| SQLite | - | No array support |
2122

2223
## PostgreSQL Arrays
2324

site/docs-typr/boundaries/databases/type-safety/collection-types.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Some databases support collection types for storing multiple values in a single
1818
| SQL Server | Table-valued parameters | Procedure parameters only |
1919
| MariaDB/MySQL | JSON arrays | No native arrays |
2020
| DB2 | - | No native collections |
21+
| SQLite | - | No native collections |
2122

2223
## PostgreSQL Arrays
2324

@@ -97,7 +98,7 @@ Currently mapped to String for flexibility. Native Map support is planned.
9798

9899
## Databases Without Collection Support
99100

100-
MariaDB/MySQL, SQL Server (outside of table types), and DB2 don't have native array types. Alternatives:
101+
MariaDB/MySQL, SQL Server (outside of table types), DB2, and SQLite don't have native array types. Alternatives:
101102
- **JSON arrays** - Flexible but less type-safe
102103
- **Junction tables** - For many-to-many relationships
103104
- **Table-valued parameters** (SQL Server) - For procedure parameters

site/docs-typr/boundaries/databases/type-safety/date-time.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,17 @@ DuckDB has modern date/time handling:
6666
- Microsecond precision
6767
- No timezone conversion issues
6868

69+
### SQLite
70+
71+
SQLite has no native date/time storage class — values are stored as ISO-8601 TEXT (the xerial driver default). Typr generates `LocalDate` / `LocalTime` / `LocalDateTime` / `Instant` codecs that parse and produce the ISO-8601 format, matching the SqliteTypes catalogue.
72+
73+
- `DATE``LocalDate` (ISO-8601 date)
74+
- `TIME``LocalTime`
75+
- `DATETIME` / `TIMESTAMP``LocalDateTime`
76+
- `TIMESTAMP` (with `Z` suffix) → `Instant`
77+
78+
Other SQLite date storage modes (INTEGER unix epoch, REAL Julian day) are configurable via `SqliteConfig.dateClass(...)` but require custom codecs — they don't round-trip through the default Typr codegen.
79+
6980
### Oracle
7081

7182
Oracle uses different type names:

0 commit comments

Comments
 (0)