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.DB open 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 plain PRAGMA and sqlite_master queries, so the production opener (single connection, WAL mode) needs no read-only variant.
  • A TypeNormaliser. Any db.EnginePort satisfies this, so pass the same engine you would use at runtime, for example db_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:

SQLite pieces:

Framework docs:

External: