diff --git a/nix/postgres.nix b/nix/postgres.nix index 858d682..6479540 100644 --- a/nix/postgres.nix +++ b/nix/postgres.nix @@ -201,17 +201,39 @@ in }; initialScript = lib.mkOption { - type = types.nullOr types.str; - default = null; + type = types.submodule ({ config, ... }: { + options = { + before = lib.mkOption { + type = types.nullOr types.str; + default = null; + description = '' + SQL commands to run before the database initialization. + ''; + example = lib.literalExpression '' + CREATE USER postgres SUPERUSER; + CREATE USER bar; + ''; + }; + after = lib.mkOption { + type = types.nullOr types.str; + default = null; + description = '' + SQL commands to run after the database initialization. + ''; + example = lib.literalExpression '' + CREATE TABLE users ( + id SERIAL PRIMARY KEY, + name VARCHAR(50) NOT NULL, + email VARCHAR(50) NOT NULL UNIQUE + ); + ''; + }; + }; + }); + default = { before = null; after = null; }; description = '' Initial SQL commands to run during database initialization. This can be multiple SQL expressions separated by a semi-colon. - - NOTE: initialScript is run /before/ initialDatabases are created. - ''; - example = lib.literalExpression '' - CREATE USER postgres SUPERUSER; - CREATE USER bar; ''; }; }; @@ -280,12 +302,17 @@ in echo "CREATE DATABASE ''${USER:-$(id -nu)};" | postgres --single -E postgres ''; runInitialScript = - if cfg.initialScript != null then - '' - echo "${cfg.initialScript}" | postgres --single -E postgres - '' - else - ""; + let + scriptCmd = sqlScript: '' + echo "${sqlScript}" | postgres --single -E postgres + ''; + in + { + before = with cfg.initialScript; + lib.optionalString (before != null) (scriptCmd before); + after = with cfg.initialScript; + lib.optionalString (after != null) (scriptCmd after); + }; toStr = value: if true == value then @@ -309,8 +336,9 @@ in initdb ${lib.concatStringsSep " " cfg.initdbArgs} set +x - ${runInitialScript} + ${runInitialScript.before} ${setupInitialDatabases} + ${runInitialScript.after} else echo "Postgres data directory already exists. Skipping initialization." fi diff --git a/nix/postgres_test.nix b/nix/postgres_test.nix index 618fccb..4836b3e 100644 --- a/nix/postgres_test.nix +++ b/nix/postgres_test.nix @@ -2,11 +2,10 @@ services.postgres = { enable = true; listen_addresses = "127.0.0.1"; + initialScript.before = "CREATE USER bar;"; + initialScript.after = "CREATE DATABASE foo OWNER bar;"; }; - testScript = - let - psql = "${config.services.postgres.package}/bin/psql"; - in + testScript = let psql = "${config.services.postgres.package}/bin/psql"; in '' process_compose.wait_until(lambda procs: # TODO: Check for 'ready' @@ -14,5 +13,9 @@ ) machine.succeed("echo 'SELECT version();' | ${config.services.postgres.package}/bin/psql -h 127.0.0.1 -U tester") machine.succeed("echo 'SHOW hba_file;' | ${psql} -h 127.0.0.1 -U tester | ${pkgs.gawk}/bin/awk 'NR==3' | ${pkgs.gnugrep}/bin/grep '^ /nix/store'") + # initialScript.before test + machine.succeed("echo \"SELECT 1 FROM pg_roles WHERE rolname = 'bar';\" | ${psql} -h 127.0.0.1 -U tester | grep -q 1") + # initialScript.after test + machine.succeed("echo \"SELECT 1 FROM pg_database WHERE datname = 'foo';\" | ${psql} -h 127.0.0.1 -U tester | grep -q 1") ''; }