feat: postgres hooks
This commit is contained in:
@@ -102,7 +102,8 @@ in {
|
|||||||
|
|
||||||
# Consolidated SQL bundles for the `hectic` schema. Single source of truth
|
# Consolidated SQL bundles for the `hectic` schema. Single source of truth
|
||||||
# for everything that creates objects in the `hectic` namespace, used by
|
# for everything that creates objects in the `hectic` namespace, used by
|
||||||
# migrator (init-time), db-tool (postgres-init), and pkgs.hectic.postgres-secrets.
|
# migrator (init-time) and db-tool (postgres-init + hydrate). Consumers apply
|
||||||
|
# the full bundle via lib/hook/apply-hectic-bundle.sh.
|
||||||
#
|
#
|
||||||
# The whole hectic system shares one `versionString`; `hectic-version.sql`
|
# The whole hectic system shares one `versionString`; `hectic-version.sql`
|
||||||
# registers (`'hectic'`, versionString) into `hectic.version` and raises an
|
# registers (`'hectic'`, versionString) into `hectic.version` and raises an
|
||||||
@@ -126,6 +127,7 @@ in {
|
|||||||
secret = static ./hook/sql/hectic-secret.sql;
|
secret = static ./hook/sql/hectic-secret.sql;
|
||||||
migration = static ./hook/sql/hectic-migration.sql;
|
migration = static ./hook/sql/hectic-migration.sql;
|
||||||
inheritance = static ./hook/sql/hectic-inheritance.sql;
|
inheritance = static ./hook/sql/hectic-inheritance.sql;
|
||||||
|
applyBundleScript = ./hook/apply-hectic-bundle.sh;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Back-compat alias. Prefer `self.lib.hectic.inheritance`.
|
# Back-compat alias. Prefer `self.lib.hectic.inheritance`.
|
||||||
|
|||||||
58
lib/hook/apply-hectic-bundle.sh
Normal file
58
lib/hook/apply-hectic-bundle.sh
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#!/bin/dash
|
||||||
|
# Applies the full hectic SQL bundle to a PostgreSQL database, in order:
|
||||||
|
# 1. version (hard-fails on version mismatch)
|
||||||
|
# 2. secret (hectic.secret table + load_secrets_from_env + get_secret)
|
||||||
|
# 3. migration (hectic.migration table + domains + sha256_lower trigger)
|
||||||
|
# 4. inheritance (created_at/updated_at/immutable enforcement triggers)
|
||||||
|
#
|
||||||
|
# Idempotent: each SQL file uses IF NOT EXISTS / CREATE OR REPLACE.
|
||||||
|
#
|
||||||
|
# Required env (caller injects from Nix):
|
||||||
|
# HECTIC_VERSION_SQL - path to hectic-version.sql (substituted)
|
||||||
|
# HECTIC_SECRET_SQL - path to hectic-secret.sql
|
||||||
|
# HECTIC_MIGRATION_SQL - path to hectic-migration.sql
|
||||||
|
# HECTIC_INHERITANCE_SQL - path to hectic-inheritance.sql
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# apply_hectic_bundle <PGURL> [<DOTENV_CONTENT>]
|
||||||
|
#
|
||||||
|
# If DOTENV_CONTENT is non-empty, it is loaded into hectic.secret via
|
||||||
|
# hectic.load_secrets_from_env() after the bundle is applied.
|
||||||
|
|
||||||
|
apply_hectic_bundle() {
|
||||||
|
pgurl="${1:-}"
|
||||||
|
env_content="${2:-}"
|
||||||
|
|
||||||
|
if [ -z "$pgurl" ]; then
|
||||||
|
printf '%s\n' 'apply-hectic-bundle: PGURL is required (arg 1)' >&2
|
||||||
|
return 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
for var in HECTIC_VERSION_SQL HECTIC_SECRET_SQL HECTIC_MIGRATION_SQL HECTIC_INHERITANCE_SQL; do
|
||||||
|
eval "val=\${$var:-}"
|
||||||
|
if [ -z "$val" ]; then
|
||||||
|
printf '%s\n' "apply-hectic-bundle: $var not set" >&2
|
||||||
|
return 3
|
||||||
|
fi
|
||||||
|
if [ ! -r "$val" ]; then
|
||||||
|
printf '%s\n' "apply-hectic-bundle: $var not readable: $val" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
psql "$pgurl" -v ON_ERROR_STOP=1 -f "$HECTIC_VERSION_SQL" || return 1
|
||||||
|
psql "$pgurl" -v ON_ERROR_STOP=1 -f "$HECTIC_SECRET_SQL" || return 1
|
||||||
|
psql "$pgurl" -v ON_ERROR_STOP=1 -f "$HECTIC_MIGRATION_SQL" || return 1
|
||||||
|
psql "$pgurl" -v ON_ERROR_STOP=1 -f "$HECTIC_INHERITANCE_SQL" || return 1
|
||||||
|
|
||||||
|
if [ -n "$env_content" ]; then
|
||||||
|
# Dollar-quote with $ps_env$ tag to preserve all content verbatim.
|
||||||
|
psql "$pgurl" -v ON_ERROR_STOP=1 <<SQL || return 1
|
||||||
|
SELECT hectic.load_secrets_from_env(\$ps_env\$
|
||||||
|
$env_content
|
||||||
|
\$ps_env\$);
|
||||||
|
SQL
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
@@ -942,15 +942,21 @@ subcommand_hydrate() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [ ! "${HYDRATE_NO_HOOK+x}" ]; then
|
if [ ! "${HYDRATE_NO_HOOK+x}" ]; then
|
||||||
log info "hectic secrets hook"
|
log info "hectic bundle hook"
|
||||||
# shellcheck disable=SC2059
|
# shellcheck disable=SC2059
|
||||||
printf "${BBLACK}"
|
printf "${BBLACK}"
|
||||||
sh "${LOCAL_DIR}/lib/hook/postgres-secrets.sh" "$PGURL" "$ENVIRONMENT"
|
dotenv_content=""
|
||||||
|
if [ -n "${HECTIC_DOTENV_FILE:-}" ] && [ -r "$HECTIC_DOTENV_FILE" ]; then
|
||||||
|
dotenv_content="$(cat "$HECTIC_DOTENV_FILE")"
|
||||||
|
elif [ -n "${ENVIRONMENT:-}" ] && [ -r "${LOCAL_DIR}/.env.${ENVIRONMENT}" ]; then
|
||||||
|
dotenv_content="$(cat "${LOCAL_DIR}/.env.${ENVIRONMENT}")"
|
||||||
|
fi
|
||||||
|
apply_hectic_bundle "$PGURL" "$dotenv_content"
|
||||||
|
|
||||||
# shellcheck disable=SC2059
|
# shellcheck disable=SC2059
|
||||||
printf "${NC}"
|
printf "${NC}"
|
||||||
else
|
else
|
||||||
log info "skipping hectic secrets hook"
|
log info "skipping hectic bundle hook"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local mock_arg=""
|
local mock_arg=""
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ dash, hectic, postgresql_17, neovim, openssh, coreutils, gawk, lib, runCommand }:
|
{ dash, hectic, postgresql_17, neovim, openssh, coreutils, gawk, lib, runCommand, self }:
|
||||||
let
|
let
|
||||||
shell = "${dash}/bin/dash";
|
shell = "${dash}/bin/dash";
|
||||||
|
|
||||||
@@ -9,6 +9,23 @@ let
|
|||||||
cp ${hecticInheritanceSqlPath} "$out/share/hectic/hectic-inheritance.sql"
|
cp ${hecticInheritanceSqlPath} "$out/share/hectic/hectic-inheritance.sql"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
# Materialize the templated version SQL into the Nix store as a real file
|
||||||
|
# so it can be passed by path to psql -f (alongside the static siblings).
|
||||||
|
hecticVersionSqlFile = pkgs-writeText "hectic-version.sql" self.lib.hectic.version.sql;
|
||||||
|
pkgs-writeText = name: text: runCommand name { inherit text; passAsFile = [ "text" ]; } ''
|
||||||
|
cp "$textPath" "$out"
|
||||||
|
'';
|
||||||
|
|
||||||
|
hecticEnv = ''
|
||||||
|
HECTIC_VERSION_SQL=${hecticVersionSqlFile}
|
||||||
|
HECTIC_SECRET_SQL=${self.lib.hectic.secret.path}
|
||||||
|
HECTIC_MIGRATION_SQL=${self.lib.hectic.migration.path}
|
||||||
|
HECTIC_INHERITANCE_SQL=${self.lib.hectic.inheritance.path}
|
||||||
|
export HECTIC_VERSION_SQL HECTIC_SECRET_SQL HECTIC_MIGRATION_SQL HECTIC_INHERITANCE_SQL
|
||||||
|
'';
|
||||||
|
|
||||||
|
applyBundle = builtins.readFile self.lib.hectic.applyBundleScript;
|
||||||
|
|
||||||
mkDatabase =
|
mkDatabase =
|
||||||
{ postgresql ? postgresql_17 }:
|
{ postgresql ? postgresql_17 }:
|
||||||
hectic.writeShellApplication {
|
hectic.writeShellApplication {
|
||||||
@@ -17,7 +34,6 @@ let
|
|||||||
"errexit"
|
"errexit"
|
||||||
"nounset"
|
"nounset"
|
||||||
];
|
];
|
||||||
# SC2209: false positive — PAGER_OR_CAT=cat stores the string "cat" intentionally
|
|
||||||
excludeShellChecks = [ "SC2209" ];
|
excludeShellChecks = [ "SC2209" ];
|
||||||
name = "database";
|
name = "database";
|
||||||
runtimeInputs = [ hectic.migrator hectic.parse-uri postgresql neovim openssh coreutils gawk ];
|
runtimeInputs = [ hectic.migrator hectic.parse-uri postgresql neovim openssh coreutils gawk ];
|
||||||
@@ -27,6 +43,8 @@ let
|
|||||||
${builtins.readFile hectic.helpers.posix-shell.change_namespace}
|
${builtins.readFile hectic.helpers.posix-shell.change_namespace}
|
||||||
${builtins.readFile hectic.helpers.posix-shell.quote}
|
${builtins.readFile hectic.helpers.posix-shell.quote}
|
||||||
${builtins.readFile hectic.helpers.posix-shell.pager_or_cat}
|
${builtins.readFile hectic.helpers.posix-shell.pager_or_cat}
|
||||||
|
${hecticEnv}
|
||||||
|
${applyBundle}
|
||||||
${builtins.readFile ./database.sh}
|
${builtins.readFile ./database.sh}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
@@ -44,11 +62,7 @@ let
|
|||||||
name = "postgres-init";
|
name = "postgres-init";
|
||||||
runtimeInputs = [ postgresql coreutils ];
|
runtimeInputs = [ postgresql coreutils ];
|
||||||
|
|
||||||
text = ''
|
text = builtins.readFile ./postgres-init.sh;
|
||||||
HECTIC_INHERITANCE_SQL_DEFAULT="${hecticInheritance}/share/hectic/hectic-inheritance.sql"
|
|
||||||
export HECTIC_INHERITANCE_SQL_DEFAULT
|
|
||||||
${builtins.readFile ./postgres-init.sh}
|
|
||||||
'';
|
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
description = "Initialize local PostgreSQL instance";
|
description = "Initialize local PostgreSQL instance";
|
||||||
|
|||||||
@@ -48,16 +48,6 @@ postgres_init_main() {
|
|||||||
fi
|
fi
|
||||||
psql -h "$sockdir" -p "$PG_PORT" -d "$db" -v ON_ERROR_STOP=1 -c 'select 1;' || return 1
|
psql -h "$sockdir" -p "$PG_PORT" -d "$db" -v ON_ERROR_STOP=1 -c 'select 1;' || return 1
|
||||||
|
|
||||||
if [ "${PG_HECTIC_INHERITANCE:-1}" = "1" ]; then
|
|
||||||
sql_file="${HECTIC_INHERITANCE_SQL:-${HECTIC_INHERITANCE_SQL_DEFAULT:-}}"
|
|
||||||
if [ -z "$sql_file" ]; then
|
|
||||||
printf '%s\n' 'postgres-init: PG_HECTIC_INHERITANCE=1 but no SQL file resolved (set HECTIC_INHERITANCE_SQL)' >&2
|
|
||||||
return 3
|
|
||||||
fi
|
|
||||||
[ -r "$sql_file" ] || { printf '%s\n' "postgres-init: hectic-inheritance SQL not readable: $sql_file" >&2; return 1; }
|
|
||||||
psql -h "$sockdir" -p "$PG_PORT" -U "$user" -d "$db" -v ON_ERROR_STOP=1 -f "$sql_file" || return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
export POSTGRESQL_HOST="$sockdir" POSTGRESQL_PORT="$PG_PORT" POSTGRESQL_USER="$user" POSTGRESQL_DATABASE="$db"
|
export POSTGRESQL_HOST="$sockdir" POSTGRESQL_PORT="$PG_PORT" POSTGRESQL_USER="$user" POSTGRESQL_DATABASE="$db"
|
||||||
_pg_url="postgresql://${POSTGRESQL_USER}@/${POSTGRESQL_DATABASE}?host=${POSTGRESQL_HOST}&port=${POSTGRESQL_PORT}"
|
_pg_url="postgresql://${POSTGRESQL_USER}@/${POSTGRESQL_DATABASE}?host=${POSTGRESQL_HOST}&port=${POSTGRESQL_PORT}"
|
||||||
case $PG_URL_VAR in ''|*[!ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_]* ) printf '%s\n' 'postgres-init: invalid PG_URL_VAR' >&2; return 1 ;; esac
|
case $PG_URL_VAR in ''|*[!ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_]* ) printf '%s\n' 'postgres-init: invalid PG_URL_VAR' >&2; return 1 ;; esac
|
||||||
|
|||||||
@@ -107,7 +107,7 @@
|
|||||||
};
|
};
|
||||||
nativeBuildInputs = with pkgs; [pkg-config curl];
|
nativeBuildInputs = with pkgs; [pkg-config curl];
|
||||||
};
|
};
|
||||||
dbToolPkgs = pkgs.callPackage ./db-tool {};
|
dbToolPkgs = pkgs.callPackage ./db-tool { inherit self; };
|
||||||
in {
|
in {
|
||||||
py3-datetime = pkgs.callPackage ./py3-datetime.nix {};
|
py3-datetime = pkgs.callPackage ./py3-datetime.nix {};
|
||||||
py3-marzban = pkgs.callPackage ./py3-marzban.nix { inherit self; };
|
py3-marzban = pkgs.callPackage ./py3-marzban.nix { inherit self; };
|
||||||
@@ -140,7 +140,7 @@ in {
|
|||||||
deploy = pkgs.callPackage ./deploy { inherit inputs; };
|
deploy = pkgs.callPackage ./deploy { inherit inputs; };
|
||||||
shellplot = pkgs.callPackage ./shellplot {};
|
shellplot = pkgs.callPackage ./shellplot {};
|
||||||
onlinepubs2man = pkgs.callPackage ./onlinepubs2man {};
|
onlinepubs2man = pkgs.callPackage ./onlinepubs2man {};
|
||||||
migrator = pkgs.callPackage ./migrator {};
|
migrator = pkgs.callPackage ./migrator { inherit self; };
|
||||||
"parse-uri" = pkgs.callPackage ./parse-uri {};
|
"parse-uri" = pkgs.callPackage ./parse-uri {};
|
||||||
"db-tool" = dbToolPkgs."db-tool";
|
"db-tool" = dbToolPkgs."db-tool";
|
||||||
"postgres-init" = dbToolPkgs."postgres-init";
|
"postgres-init" = dbToolPkgs."postgres-init";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ dash, hectic, sqlite, postgresql_17, gawk }:
|
{ dash, hectic, sqlite, postgresql_17, gawk, runCommand, self }:
|
||||||
let
|
let
|
||||||
shell = "${dash}/bin/dash";
|
shell = "${dash}/bin/dash";
|
||||||
bashOptions = [
|
bashOptions = [
|
||||||
@@ -6,6 +6,21 @@ let
|
|||||||
"nounset"
|
"nounset"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
hecticVersionSqlFile = runCommand "hectic-version.sql" {
|
||||||
|
text = self.lib.hectic.version.sql;
|
||||||
|
passAsFile = [ "text" ];
|
||||||
|
} ''cp "$textPath" "$out"'';
|
||||||
|
|
||||||
|
hecticEnv = ''
|
||||||
|
HECTIC_VERSION_SQL=${hecticVersionSqlFile}
|
||||||
|
HECTIC_SECRET_SQL=${self.lib.hectic.secret.path}
|
||||||
|
HECTIC_MIGRATION_SQL=${self.lib.hectic.migration.path}
|
||||||
|
HECTIC_INHERITANCE_SQL=${self.lib.hectic.inheritance.path}
|
||||||
|
export HECTIC_VERSION_SQL HECTIC_SECRET_SQL HECTIC_MIGRATION_SQL HECTIC_INHERITANCE_SQL
|
||||||
|
'';
|
||||||
|
|
||||||
|
applyBundle = builtins.readFile self.lib.hectic.applyBundleScript;
|
||||||
|
|
||||||
migrator = hectic.writeShellApplication {
|
migrator = hectic.writeShellApplication {
|
||||||
inherit shell bashOptions;
|
inherit shell bashOptions;
|
||||||
name = "migrator";
|
name = "migrator";
|
||||||
@@ -13,6 +28,8 @@ let
|
|||||||
|
|
||||||
text = ''
|
text = ''
|
||||||
${builtins.readFile hectic.helpers.posix-shell.log}
|
${builtins.readFile hectic.helpers.posix-shell.log}
|
||||||
|
${hecticEnv}
|
||||||
|
${applyBundle}
|
||||||
${builtins.readFile ./migrator.sh}
|
${builtins.readFile ./migrator.sh}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -170,35 +170,19 @@ init() {
|
|||||||
|
|
||||||
db_type=$(detect_db_type)
|
db_type=$(detect_db_type)
|
||||||
|
|
||||||
# INHERITS is PostgreSQL-only feature
|
if [ "$db_type" = "postgresql" ]; then
|
||||||
[ ${INHERITS_LIST+x} ] && {
|
if ! apply_hectic_bundle "$DB_URL"; then
|
||||||
if [ "$db_type" != "postgresql" ]; then
|
log error "init failed: hectic bundle apply"
|
||||||
log error "INHERITS is only supported for PostgreSQL"
|
exit 13
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
oldIFS="$IFS"
|
init_sql_extra="$(init_sql)"
|
||||||
IFS=','
|
if [ -n "$init_sql_extra" ]; then
|
||||||
check_inherits=
|
if ! db_exec "$init_sql_extra"; then
|
||||||
for table in $INHERITS_LIST; do
|
log error "init failed"
|
||||||
check_inherits="$(printf '%s\nSELECT 1 FROM %s LIMIT 1;' "$check_inherits" "$table")"
|
exit 13
|
||||||
done
|
|
||||||
IFS="$oldIFS"
|
|
||||||
|
|
||||||
check_inherits=$(printf '%s\n' \
|
|
||||||
'BEGIN;' \
|
|
||||||
"$check_inherits" \
|
|
||||||
'COMMIT;')
|
|
||||||
|
|
||||||
if ! db_exec "$check_inherits"; then
|
|
||||||
log error "init failed: ${WHITE}one of inherits table does not exists: ${CYAN}$INHERITS_LIST"
|
|
||||||
exit 5
|
|
||||||
fi
|
fi
|
||||||
}
|
|
||||||
|
|
||||||
if ! db_exec "$(init_sql)"; then
|
|
||||||
log error "init failed"
|
|
||||||
exit 13
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,86 +193,11 @@ error_handler_no_db_url() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init_sql_postgresql() {
|
init_sql_postgresql() {
|
||||||
local sql inherits
|
# PostgreSQL init is delegated to apply_hectic_bundle (full hectic bundle
|
||||||
|
# applied as one unit on every `migrator init`). This function returns
|
||||||
inherits=
|
# empty for the dry-run / db_exec path; bundle SQL paths are exposed via
|
||||||
[ ${INHERITS_LIST+x} ] && inherits="$(printf 'INHERITS(%s)' "$INHERITS_LIST")"
|
# HECTIC_*_SQL env vars for inspection if needed.
|
||||||
|
printf ''
|
||||||
sql="$(cat <<EOF
|
|
||||||
BEGIN;
|
|
||||||
|
|
||||||
DO \$\$
|
|
||||||
DECLARE
|
|
||||||
ver TEXT;
|
|
||||||
BEGIN
|
|
||||||
CREATE SCHEMA IF NOT EXISTS hectic;
|
|
||||||
|
|
||||||
-- NOTE(yukkop): check version table exists
|
|
||||||
IF EXISTS (
|
|
||||||
SELECT 1
|
|
||||||
FROM pg_class c
|
|
||||||
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
||||||
WHERE c.relname = 'version'
|
|
||||||
AND n.nspname = 'hectic'
|
|
||||||
AND c.relkind = 'r'
|
|
||||||
) THEN
|
|
||||||
SELECT v.version INTO ver FROM hectic.version v WHERE v.name = 'migrator';
|
|
||||||
IF ver IS NOT NULL AND ver != '$VERSION' THEN
|
|
||||||
RAISE EXCEPTION 'Incompatible migrator versions: % and $VERSION', ver;
|
|
||||||
END IF;
|
|
||||||
ELSE
|
|
||||||
CREATE TABLE hectic.version (
|
|
||||||
name TEXT PRIMARY KEY,
|
|
||||||
version TEXT NOT NULL,
|
|
||||||
installed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
||||||
)$inherits;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- NOTE(yukkop): check migrator is registered in version table
|
|
||||||
IF NOT EXISTS (
|
|
||||||
SELECT 1 FROM hectic.version WHERE name = 'migrator'
|
|
||||||
) THEN
|
|
||||||
INSERT INTO hectic.version (name, version) VALUES ('migrator', '$VERSION');
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- NOTE(yukkop): create migrator-specific objects if not yet present
|
|
||||||
IF NOT EXISTS (
|
|
||||||
SELECT 1
|
|
||||||
FROM pg_class c
|
|
||||||
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
||||||
WHERE c.relname = 'migration'
|
|
||||||
AND n.nspname = 'hectic'
|
|
||||||
AND c.relkind = 'r'
|
|
||||||
) THEN
|
|
||||||
CREATE DOMAIN hectic.migration_name AS TEXT CHECK (VALUE ~ '^[0-9]{14}-.*');
|
|
||||||
CREATE DOMAIN hectic.sha256 AS CHAR(64) CHECK (VALUE ~ '^[0-9a-f]{64}\$');
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION hectic.sha256_lower() RETURNS trigger AS \$fn\$
|
|
||||||
BEGIN
|
|
||||||
NEW.hash = lower(NEW.hash);
|
|
||||||
RETURN NEW;
|
|
||||||
END;
|
|
||||||
\$fn\$ LANGUAGE plpgsql;
|
|
||||||
|
|
||||||
CREATE TABLE hectic.migration (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
name hectic.migration_name UNIQUE NOT NULL,
|
|
||||||
hash hectic.sha256 UNIQUE NOT NULL,
|
|
||||||
applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
||||||
)$inherits;
|
|
||||||
|
|
||||||
CREATE TRIGGER hectic_t_sha256_lower
|
|
||||||
BEFORE INSERT OR UPDATE ON hectic.migration
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION hectic.sha256_lower();
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
\$\$;
|
|
||||||
|
|
||||||
COMMIT;
|
|
||||||
EOF
|
|
||||||
)"
|
|
||||||
|
|
||||||
printf '%s' "$sql"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init_sql_sqlite() {
|
init_sql_sqlite() {
|
||||||
@@ -1102,7 +1011,7 @@ if ! [ "${AS_LIBRARY+x}" ]; then
|
|||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
--inherits)
|
--inherits)
|
||||||
INHERITS_LIST="${INHERITS_LIST+$INHERITS_LIST\"}$2"
|
log warn "--inherits is deprecated and ignored: hectic schema is auto-exempt from inheritance enforcement"
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
--*|-*) REMAINING_ARS="$REMAINING_ARS $(quote "$1")"; shift ;; # unknown global -> pass through
|
--*|-*) REMAINING_ARS="$REMAINING_ARS $(quote "$1")"; shift ;; # unknown global -> pass through
|
||||||
@@ -1110,7 +1019,6 @@ if ! [ "${AS_LIBRARY+x}" ]; then
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
[ "${INHERITS_LIST+x}" ] && INHERITS_LIST="$(printf '%s' "$INHERITS_LIST" | sed -E 's/"/,/g; s/([^,]+)/"\1"/g')"
|
|
||||||
[ "${SUBCOMMAND+x}" ] || { log error "no subcommand specified. Use 'migrator help' for usage information."; exit 1; }
|
[ "${SUBCOMMAND+x}" ] || { log error "no subcommand specified. Use 'migrator help' for usage information."; exit 1; }
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user