package db import ( mcdsldb "git.wntrmute.dev/kyle/mcdsl/db" ) // Migrations is the ordered list of MCR schema migrations. var Migrations = []mcdsldb.Migration{ { Version: 1, Name: "core registry tables", SQL: ` CREATE TABLE IF NOT EXISTS repositories ( id INTEGER PRIMARY KEY, name TEXT NOT NULL UNIQUE, created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ','now')) ); CREATE TABLE IF NOT EXISTS manifests ( id INTEGER PRIMARY KEY, repository_id INTEGER NOT NULL REFERENCES repositories(id) ON DELETE CASCADE, digest TEXT NOT NULL, media_type TEXT NOT NULL, content BLOB NOT NULL, size INTEGER NOT NULL, created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ','now')), UNIQUE(repository_id, digest) ); CREATE INDEX IF NOT EXISTS idx_manifests_repo ON manifests (repository_id); CREATE INDEX IF NOT EXISTS idx_manifests_digest ON manifests (digest); CREATE TABLE IF NOT EXISTS tags ( id INTEGER PRIMARY KEY, repository_id INTEGER NOT NULL REFERENCES repositories(id) ON DELETE CASCADE, name TEXT NOT NULL, manifest_id INTEGER NOT NULL REFERENCES manifests(id) ON DELETE CASCADE, updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ','now')), UNIQUE(repository_id, name) ); CREATE INDEX IF NOT EXISTS idx_tags_repo ON tags (repository_id); CREATE INDEX IF NOT EXISTS idx_tags_manifest ON tags (manifest_id); CREATE TABLE IF NOT EXISTS blobs ( id INTEGER PRIMARY KEY, digest TEXT NOT NULL UNIQUE, size INTEGER NOT NULL, created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ','now')) ); CREATE TABLE IF NOT EXISTS manifest_blobs ( manifest_id INTEGER NOT NULL REFERENCES manifests(id) ON DELETE CASCADE, blob_id INTEGER NOT NULL REFERENCES blobs(id), PRIMARY KEY (manifest_id, blob_id) ); CREATE INDEX IF NOT EXISTS idx_manifest_blobs_blob ON manifest_blobs (blob_id); CREATE TABLE IF NOT EXISTS uploads ( id INTEGER PRIMARY KEY, uuid TEXT NOT NULL UNIQUE, repository_id INTEGER NOT NULL REFERENCES repositories(id) ON DELETE CASCADE, byte_offset INTEGER NOT NULL DEFAULT 0, created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ','now')) );`, }, { Version: 2, Name: "policy and audit tables", SQL: ` CREATE TABLE IF NOT EXISTS policy_rules ( id INTEGER PRIMARY KEY, priority INTEGER NOT NULL DEFAULT 100, description TEXT NOT NULL, rule_json TEXT NOT NULL, enabled INTEGER NOT NULL DEFAULT 1 CHECK (enabled IN (0,1)), created_by TEXT, created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ','now')), updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ','now')) ); CREATE TABLE IF NOT EXISTS audit_log ( id INTEGER PRIMARY KEY, event_time TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ','now')), event_type TEXT NOT NULL, actor_id TEXT, repository TEXT, digest TEXT, ip_address TEXT, details TEXT ); CREATE INDEX IF NOT EXISTS idx_audit_time ON audit_log (event_time); CREATE INDEX IF NOT EXISTS idx_audit_actor ON audit_log (actor_id); CREATE INDEX IF NOT EXISTS idx_audit_event ON audit_log (event_type);`, }, } // Migrate applies all pending migrations. It creates the schema_migrations // tracking table if it does not exist. Migrations are idempotent. func (d *DB) Migrate() error { return mcdsldb.Migrate(d.DB, Migrations) } // SchemaVersion returns the highest applied migration version, or 0 if // no migrations have been applied. func (d *DB) SchemaVersion() (int, error) { return mcdsldb.SchemaVersion(d.DB) }