Add lib/hook/sql/README.md describing bundle layout, apply order, Nix API (self.lib.hectic.*), shell helper contract, and the steps for adding a new SQL file. Rewrite db-tool README's hectic section: drop stale PG_HECTIC_INHERITANCE / HECTIC_INHERITANCE_SQL env vars, add HECTIC_DOTENV_FILE, document the postgres-init / migrator init / database hydrate responsibility split.
4.0 KiB
hectic SQL bundle
Single source of truth for every object created in the hectic PostgreSQL
schema. Consumed by:
package/migrator— applies the bundle onmigrator init(mandatory).package/db-tool— applies the bundle indatabase hydrate(default; opt out with--no-hook).- External consumers (e.g.
proxydoe) — invokepsql -fdirectly against the paths exposed viaself.lib.hectic.*.path.
Layout
| File | Purpose |
|---|---|
HECTIC_VERSION |
Single version string for the whole bundle (e.g. 0.1.0). Read via lib.fileContents. |
hectic-version.sql |
Templated. Creates hectic.version, inserts the current versionString, raises on mismatch. |
hectic-secret.sql |
Creates hectic.secret, hectic.load_secrets_from_env(text), hectic.get_secret(text). |
hectic-migration.sql |
Creates the hectic.migration table and supporting domains/triggers used by migrator. |
hectic-inheritance.sql |
Creates hectic.created_at, hectic.updated_at, hectic.immutable parent tables and the DDL event triggers that enforce inheritance, attach BEFORE UPDATE triggers, and block DML on immutable tables outside migration_mode. |
hectic-version.sql is templated at Nix evaluation time: @HECTIC_VERSION@
is substituted with the contents of HECTIC_VERSION. All other files are
applied verbatim.
Apply order
The bundle MUST be applied in this order (enforced by
apply-hectic-bundle.sh):
hectic-version.sql— version check first; aborts the rest on mismatch.hectic-secret.sqlhectic-migration.sqlhectic-inheritance.sql
Re-applying the bundle is idempotent — every CREATE uses
IF NOT EXISTS / CREATE OR REPLACE, and the version check accepts a row
that already matches.
Nix API (self.lib.hectic)
self.lib.hectic = {
versionString; # e.g. "0.1.0"
version = { sql; }; # templated
secret = { sql; path; };
migration = { sql; path; };
inheritance = { sql; path; };
applyBundleScript; # ./hook/apply-hectic-bundle.sh
};
.sql is the file contents as a string. .path is the Nix store path of the
verbatim source (only available on non-templated entries; consumers needing a
materialized version of version.sql must do
pkgs.runCommand "hectic-version.sql" { text = self.lib.hectic.version.sql; passAsFile = ["text"]; } ''cp "$textPath" "$out"'').
Shell helper (apply-hectic-bundle.sh)
lib/hook/apply-hectic-bundle.sh is a dash-compatible helper sourced by both
migrator and db-tool. Public entry point:
apply_hectic_bundle <PGURL> [<DOTENV_CONTENT>]
<PGURL>— full PostgreSQL connection string.<DOTENV_CONTENT>— optional. When present, after applying the bundle the helper invokeshectic.load_secrets_from_env(<dotenv>)inside a dollar-quoted ($ps_env$) string so secret values cannot terminate the literal.
Required environment (paths to the SQL files):
HECTIC_VERSION_SQLHECTIC_SECRET_SQLHECTIC_MIGRATION_SQLHECTIC_INHERITANCE_SQL
migrator and db-tool set these via Nix at build time. External consumers
typically invoke psql -f against the paths directly instead of sourcing the
helper.
Adding a new SQL file
- Add
lib/hook/sql/hectic-<name>.sql. - Wire it into
lib/default.nixunderlib.hectic.<name>. - Inject
HECTIC_<NAME>_SQLin bothpackage/migrator/default.nixandpackage/db-tool/default.nix. - Append a
psql -f "$HECTIC_<NAME>_SQL"step tolib/hook/apply-hectic-bundle.shin the correct order. - Bump
HECTIC_VERSIONif the new content changes existing semantics. - Update tests in
test/package/migrator/test/postgresql/init-hectic-bundle/andtest/package/db-tool/test/postgresql/hydrate-hook/.
Versioning
HECTIC_VERSION is a single global version for the bundle, not per-file.
Bump it on any breaking change to the schema. hectic-version.sql raises an
exception when the database row diverges from the bundle version, forcing a
deliberate migration before the rest of the bundle runs.