Skip to content

Commit 39829eb

Browse files
committed
feat: include migrations on newer version, for all previous
1 parent d965f23 commit 39829eb

File tree

1 file changed

+80
-21
lines changed

1 file changed

+80
-21
lines changed

nix/ext/pgaudit.nix

Lines changed: 80 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,57 @@ let
1313
# Load version configuration from external file
1414
allVersions = (builtins.fromJSON (builtins.readFile ./versions.json)).${pname};
1515

16-
# Filter versions compatible with current PostgreSQL version
16+
# Filter versions compatible with current PostgreSQL version (these get libraries)
1717
supportedVersions = lib.filterAttrs (
1818
_: value: builtins.elem (lib.versions.major postgresql.version) value.postgresql
1919
) allVersions;
2020

2121
# Derived version information
22+
# All versions sorted (for SQL migration files)
23+
allVersionsList = lib.naturalSort (lib.attrNames allVersions);
24+
# Supported versions sorted (for libraries)
2225
versions = lib.naturalSort (lib.attrNames supportedVersions);
2326
latestVersion = lib.last versions;
2427
numberOfVersions = builtins.length versions;
28+
29+
# Build packages only for supported versions (with libraries)
2530
packages = builtins.attrValues (
2631
lib.mapAttrs (name: value: build name value.hash) supportedVersions
2732
);
2833

34+
# Helper function to generate migration SQL file pairs
35+
# Returns a list of {from, to} pairs for sequential migrations
36+
generateMigrationPairs =
37+
versions:
38+
let
39+
indexed = lib.imap0 (i: v: {
40+
idx = i;
41+
version = v;
42+
}) versions;
43+
pairs = lib.filter (x: x.idx > 0) indexed;
44+
in
45+
map (curr: {
46+
from = (lib.elemAt versions (curr.idx - 1));
47+
to = curr.version;
48+
}) pairs;
49+
50+
# All migration pairs across all versions (sequential)
51+
allMigrationPairs = generateMigrationPairs allVersionsList;
52+
53+
# Get the first supported version for this PG major
54+
firstSupportedVersion = lib.head versions;
55+
56+
# Generate bridge migrations from unsupported versions to first supported version
57+
# These are needed when upgrading PostgreSQL major versions
58+
# Only include versions that come BEFORE the first supported version (no backwards migrations)
59+
unsupportedVersions = lib.filter (
60+
v: !(builtins.elem v versions) && (lib.versionOlder v firstSupportedVersion)
61+
) allVersionsList;
62+
bridgeMigrations = map (v: {
63+
from = v;
64+
to = firstSupportedVersion;
65+
}) unsupportedVersions;
66+
2967
# Build function for individual pgaudit versions
3068
build =
3169
version: hash:
@@ -64,26 +102,17 @@ let
64102
# Install shared library with version suffix
65103
mv ${pname}${postgresql.dlSuffix} $out/lib/${pname}-${version}${postgresql.dlSuffix}
66104
67-
# Install SQL files
105+
# Install SQL files with modifications
68106
sed -i '1s/^/DROP EVENT TRIGGER IF EXISTS pgaudit_ddl_command_end; \n/' *.sql
69107
sed -i '1s/^/DROP EVENT TRIGGER IF EXISTS pgaudit_sql_drop; \n/' *.sql
70108
sed -i 's/CREATE FUNCTION/CREATE OR REPLACE FUNCTION/' *.sql
71109
cp *.sql $out/share/postgresql/extension
72110
73-
# Create version-specific control file
111+
# Create version-specific control file pointing to versioned library
74112
sed -e "/^default_version =/d" \
75-
-e "s|^module_pathname = .*|module_pathname = '\$libdir/${pname}'|" \
113+
-e "s|^module_pathname = .*|module_pathname = '\$libdir/${pname}-${version}'|" \
76114
${pname}.control > $out/share/postgresql/extension/${pname}--${version}.control
77115
78-
# For the latest version, create default control file and symlink
79-
if [[ "${version}" == "${latestVersion}" ]]; then
80-
{
81-
echo "default_version = '${latestVersion}'"
82-
cat $out/share/postgresql/extension/${pname}--${latestVersion}.control
83-
} > $out/share/postgresql/extension/${pname}.control
84-
ln -sfn ${pname}-${latestVersion}${postgresql.dlSuffix} $out/lib/${pname}${postgresql.dlSuffix}
85-
fi
86-
87116
runHook postInstall
88117
'';
89118

@@ -104,14 +133,44 @@ buildEnv {
104133
"/share/postgresql/extension"
105134
];
106135
postBuild = ''
107-
# checks
108-
(set -x
109-
test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${
110-
toString (numberOfVersions + 1)
111-
}"
112-
)
113-
114-
# Verify all expected library files are present
136+
# Create symlinks to latest version for library and control file
137+
ln -sfn ${pname}-${latestVersion}${postgresql.dlSuffix} $out/lib/${pname}${postgresql.dlSuffix}
138+
139+
# Create default control file pointing to latest
140+
{
141+
echo "default_version = '${latestVersion}'"
142+
cat $out/share/postgresql/extension/${pname}--${latestVersion}.control
143+
} > $out/share/postgresql/extension/${pname}.control
144+
145+
# Generate cross-version migration SQL files
146+
# For each migration pair, if the target version's base SQL exists but we haven't
147+
# built that version (no library), we need to create migration files to bridge from
148+
# older versions to the first available version on this PG major
149+
${lib.concatMapStringsSep "\n" (pair: ''
150+
# Check if we need to create migration ${pair.from}--${pair.to}.sql
151+
if [[ ! -f "$out/share/postgresql/extension/${pname}--${pair.from}--${pair.to}.sql" ]]; then
152+
# If the target SQL file exists, create the migration by copying it
153+
if [[ -f "$out/share/postgresql/extension/${pname}--${pair.to}.sql" ]]; then
154+
cp "$out/share/postgresql/extension/${pname}--${pair.to}.sql" \
155+
"$out/share/postgresql/extension/${pname}--${pair.from}--${pair.to}.sql"
156+
fi
157+
fi
158+
'') allMigrationPairs}
159+
160+
# Generate bridge migrations from unsupported versions to first supported version
161+
# This handles cross-PostgreSQL-major-version upgrades
162+
${lib.concatMapStringsSep "\n" (pair: ''
163+
# Create bridge migration ${pair.from}--${pair.to}.sql if not already present
164+
if [[ ! -f "$out/share/postgresql/extension/${pname}--${pair.from}--${pair.to}.sql" ]]; then
165+
# The bridge migration is just a copy of the target version's base SQL
166+
if [[ -f "$out/share/postgresql/extension/${pname}--${pair.to}.sql" ]]; then
167+
cp "$out/share/postgresql/extension/${pname}--${pair.to}.sql" \
168+
"$out/share/postgresql/extension/${pname}--${pair.from}--${pair.to}.sql"
169+
fi
170+
fi
171+
'') bridgeMigrations}
172+
173+
# Verify all expected library files are present (one per version + symlink)
115174
expectedFiles=${toString (numberOfVersions + 1)}
116175
actualFiles=$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)
117176

0 commit comments

Comments
 (0)