agentsclimarketplace

Portable schema generator

Skill Tibsfox/gsd-skill-creator/examples/skills/gsd-meta/portable-schema-generator

Emit Postgres.sql and SQLite.sql from a single schema spec so tools work across both drivers without duplicating DDL by hand. Use when designing a schema that needs to support both shared Postgres deployments and zero-config SQLite. Reduces two-file sync burden to a single source edit.From its SKILL.md

Install
npx -y skills add Tibsfox/gsd-skill-creator --skill portable-schema-generator

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.

SKILL.md

4.2 KB, 902 tokens by cl100k_base, as published. Nobody here has run it

Portable Schema Generator

Two-driver schemas mean two migration files. Hand-keeping them in sync drifts fast. This skill captures the translation rules and the minimal tooling that keeps them aligned.

When to Use

  • Your tool needs to work on both Postgres and SQLite
  • You want fresh-project onboarding to be zero-config (SQLite default) while shared-infra deployments keep Postgres
  • A single schema change should land in both driver files with no manual diff-copying

Core Differences

ConcernPostgresSQLite
SchemasCREATE SCHEMA foo; SET search_path TO fooNamespace-flat — prefix names instead
AutoincrementBIGSERIAL PRIMARY KEYINTEGER PRIMARY KEY AUTOINCREMENT
TimestampsTIMESTAMPTZ DEFAULT now()TEXT DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))
BooleansBOOLEANINTEGER (0/1)
Enums via CHECKCHECK (col IN ('a','b'))Same — both support inline CHECK
Foreign keysOn by defaultPRAGMA foreign_keys = ON required at connect
Updated-at triggerCREATE TRIGGER ... EXECUTE FUNCTION touch_updated_at()CREATE TRIGGER ... BEGIN UPDATE ... END
Cascading dropsON DELETE CASCADESame, but only enforced with foreign_keys = ON
Reserved-word casingCase-insensitiveCase-insensitive, but be consistent

Translation Rules

When authoring the Postgres version first:

  1. Strip schema prefix for SQLite — CREATE SCHEMA IF NOT EXISTS foo; and SET search_path are removed. Keep bare table names.
  2. Replace BIGSERIAL with INTEGER PRIMARY KEY AUTOINCREMENT.
  3. Replace TIMESTAMPTZ with TEXT; default becomes (strftime('%Y-%m-%dT%H:%M:%fZ','now')).
  4. Replace BOOLEAN with INTEGER (values 0/1 at insert time — use an adapter coercion).
  5. Drop RESTART IDENTITY on truncates (SQLite uses DELETE FROM sqlite_sequence WHERE name = 'table' instead).
  6. Rewrite function-style triggers to inline BEGIN ... END trigger bodies.

File Layout

migrations/<feature>/
  001-init.postgres.sql
  001-init.sqlite.sql
  002-next.postgres.sql
  002-next.sqlite.sql

Numbered pairs. The adapter picks the right one based on cfg.db.driver.

Adapter Runtime Responsibilities

The query adapter at runtime should:

  • Rewrite $N placeholders → ? for SQLite
  • Strip release_history. schema prefix for SQLite
  • Translate now()strftime(...), ::type casts → drop
  • Coerce JS booleans → 0/1 on param bindings
  • Provide a portable truncate(table) helper

Reference implementation: tools/release-history/db.mjs in this repo.

Workflow

  1. Author the Postgres version first (richer type system reduces ambiguity).
  2. Translate row-by-row using the rules above into the SQLite version.
  3. Test both: apply each migration to a disposable DB, run schema-check script against the adapter.
  4. Commit both files together; never commit one without the other.

Anti-patterns to avoid

  • Single mixed-syntax file — both drivers will try to parse it and one or both will fail.
  • Runtime translation of whole migration files — too many edge cases.
  • Letting the Postgres file diverge "just for now" — alignment rots quickly.

Example (from this repo)

See migrations/release-history/001-init.postgres.sql and migrations/release-history/001-init.sqlite.sql. Six tables (release, feature, metric, retrospective, lesson, publish_target). Same semantics, driver-idiomatic DDL.

Related

  • env-setup — database credentials and .env conventions
  • file-operation-patterns — migration file naming discipline

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.