SQLite catalogue provider
SQLite schema-introspection adapter that builds a db.CatalogueProviderPort by running PRAGMA table_xinfo, index_list, and friends against a live database.
Overview
Catalogues are build-time artefacts. The Piko querier code generator needs your schema shape (tables, columns, indexes, generated columns) before it can produce typed Go query code. The default path replays your migration files through the engine parser. This provider takes the alternative route. It opens the SQLite file, runs PRAGMAs, and produces the same Catalogue structure from what is on disk.
Choose this provider when the SQLite file, not your *.up.sql files, is the source of truth. That covers a vendor-supplied dataset, a database produced by another tool, or an existing app moving into Piko. It also captures generated columns (STORED and VIRTUAL) the way SQLite reports them. Reach for the default migration-replay path when your migration files are the canonical schema and you want generation to run without a database connection.
It is a drop-in CatalogueProviderPort. The querier service treats migration replay and live introspection as interchangeable adapters behind one port, so swapping between them is a single field change. Both paths return the same querier_dto.Catalogue shape, so every downstream step (typed query methods, generated-column awareness) is identical.
It is not a runtime service. Introspection runs once during code generation. The generated .sql.go files then run at runtime against any SQLite driver. There is no piko.With* registration. You wire this into a custom querier-service composition by passing it as the CatalogueProvider port.
Requirements
- A
*sql.DBopen against the SQLite database you want to introspect. Either the CGO driver or the pure-Go driver works, and PRAGMA queries are dialect-standard. Introspection reads through plainPRAGMAandsqlite_masterqueries, so the production opener (single connection, WAL mode) needs no read-only variant. - A
TypeNormaliser. Anydb.EnginePortsatisfies this, so pass the same engine you would use at runtime, for exampledb_engine_sqlite.NewSQLiteEngine().
Configuration
import (
"piko.sh/piko/wdk/db/db_catalogue_sqlite"
"piko.sh/piko/wdk/db/db_driver_sqlite_nocgo"
"piko.sh/piko/wdk/db/db_engine_sqlite"
)
connection, err := db_driver_sqlite_nocgo.Open(ctx, "data/app.db", db_driver_sqlite_nocgo.Config{})
if err != nil {
return err
}
defer connection.Close()
engine := db_engine_sqlite.NewSQLiteEngine()
provider := db_catalogue_sqlite.NewPragmaIntrospectionProvider(connection, engine)
The provider's only public method is BuildCatalogue(ctx):
catalogue, sourceErrors, err := provider.BuildCatalogue(ctx)
if err != nil {
return err
}
Bootstrap
There is no piko.With* registration. The stock db_engine_sqlite.SQLite() engine config leaves its CatalogueFactory hook nil, so SQLite does not auto-wire a live introspection provider. You compose the querier service by hand and set the provider as the CatalogueProvider port.
NewQuerierService requires the Engine, Emitter, and FileReader ports. It fails fast at construction if any is nil. The CatalogueProvider port is optional. Set it to this provider to override the default migration-replay path:
import (
"os"
"piko.sh/piko/wdk/db"
"piko.sh/piko/wdk/db/db_catalogue_sqlite"
"piko.sh/piko/wdk/db/db_engine_sqlite"
)
engine := db_engine_sqlite.NewSQLiteEngine()
catalogue := db_catalogue_sqlite.NewPragmaIntrospectionProvider(connection, engine)
querier, err := db.NewQuerierService(db.QuerierPorts{
Engine: engine,
Emitter: db.NewSQLEmitter(),
FileReader: db.NewFSFileReader(os.DirFS("internal/app")),
CatalogueProvider: catalogue,
})
if err != nil {
return err
}
When CatalogueProvider is nil, the querier service builds the catalogue from migration files through the engine parser instead. Because the provider is one CatalogueProviderPort, db.NewCompositeCatalogueProvider can union-merge it with other catalogue sources when query files cross schemas.
See also
Sibling catalogues:
- PostgreSQL Catalogue,
pg_catalog-based introspection for Postgres.
SQLite pieces:
- SQLite engine, runtime engine and dialect; pair the same engine instance with this catalogue.
- SQLite Driver (CGO), the canonical mattn driver.
- SQLite Driver (No CGO), pure-Go alternative.
Framework docs:
- How to use databases and queries, the end-to-end codegen workflow and where catalogues fit.
- Database API reference,
CatalogueProviderPort,EnginePort, and the querier types.
External:
- SQLite PRAGMA reference, the introspection commands this provider uses.
PRAGMA table_xinfo, column listing including hidden/generated columns.