feat: run migrations against running database

This commit is contained in:
Orion Kindel 2023-06-11 16:43:53 -05:00
parent 0728ba9714
commit 442d4e8ae0
Signed by untrusted user who does not match committer: orion
GPG Key ID: 6D4165AE4C928719
7 changed files with 62 additions and 13 deletions

3
.env.schema Normal file
View File

@ -0,0 +1,3 @@
POSTGRES_USER=postgres
POSTGRES_PASSWORD=password
POSTGRES_DB=dnim

View File

@ -9,7 +9,7 @@ services:
volumes:
- "./data/base:/var/lib/postgres/data"
env_file:
- "./.env"
- "./.env.schema"
head:
container_name: "head"
image: "postgres:15.3-bullseye"
@ -19,4 +19,4 @@ services:
volumes:
- "./data/head:/var/lib/postgres/data"
env_file:
- "./.env"
- "./.env.schema"

8
schema/000_revision.sql Normal file
View File

@ -0,0 +1,8 @@
create table public.migration
( from_revision text not null
, to_revision text not null
, performed_on timestamp not null default now()
, script text not null
);
insert into migration (from_revision, to_revision, script) values ('empty', 'empty', '');

View File

@ -1,6 +1,6 @@
#! /usr/bin/bash
source ./scripts/env.sh
source ./scripts/env.sh ./.env.schema
rev=${1:-HEAD}
@ -25,17 +25,15 @@ switch_back_to_head() {
}
trap 'switch_back_to_head' EXIT
url=postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:$port/$POSTGRES_DB
url=postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:$port
psql \
--quiet \
$url \
--command="drop schema public cascade; create schema public;" \
1>/dev/null
dropdb=$(mktemp)
echo "drop database dnim with (force); create database dnim;" > "$dropdb"
psql --quiet "$url/postgres" --file="$dropdb" 1>/dev/null
ls ./schema/ | xargs -I{} \
psql \
--quiet \
$url \
"$url/$POSTGRES_DB" \
--file=./schema/{} \
1>/dev/null

View File

@ -2,7 +2,7 @@
set -e
source ./scripts/env.sh
source ./scripts/env.sh ./.env.schema
rev=${1:-}
@ -20,4 +20,4 @@ docker compose up -d
./scripts/build.sh HEAD
echo "migrate from $rev => HEAD" 1>&2
migra --unsafe $base_url $head_url
migra --unsafe $base_url $head_url || echo "migra exited with code $?. this is /probably/ fine" 1>&2

View File

@ -1,3 +1,5 @@
#! /usr/bin/bash
while read line; do export $line; done < ./.env
file=${1:-./.env}
while read line; do export "$line"; done < "$file"

38
scripts/migrate.sh Normal file → Executable file
View File

@ -1,3 +1,41 @@
#! /usr/bin/bash
set -e
source ./scripts/env.sh ./.env
if [[ -n $(git status --porcelain) ]]; then
echo "git working tree dirty" 1>&2;
exit 1;
fi
head=$(git show --format=format:%h -q)
get_dnim_database_count="copy (select count(*) from pg_database where datname = 'dnim') to stdout with null as '';"
dnim_database_count=$(psql "$POSTGRES_ROOT_CONNECTION_URL" -c "$get_dnim_database_count")
if [[ "$dnim_database_count" = "0" ]]; then
echo "fresh database"
psql "$POSTGRES_ROOT_CONNECTION_URL" -c "create database dnim;"
ls ./schema/ | xargs -I{} psql --quiet "$POSTGRES_CONNECTION_URL" --file=./schema/{} 1>/dev/null
last_revision='empty'
script=''
else
get_last_revision="copy (select to_revision from migration order by performed_on desc limit 1) to stdout with null as '';"
last_revision=$(psql "$POSTGRES_CONNECTION_URL" -c "$get_last_revision")
script=$(./scripts/diff.sh "$last_revision")
if [[ "$1" = "--greenlight" ]]; then
psql "$POSTGRES_CONNECTION_URL" -c "$script"
else
to_review="tmp/migrate_${last_revision}_to_${head}.sql"
echo "$script" > "$to_review"
echo "script written to $to_review"
echo "review and rerun with --greenlight to apply migration"
exit
fi
fi
insert_migration="insert into migration (from_revision, to_revision, script) values ('$last_revision', '$head', \$migration\$$script\$migration\$);"
psql "$POSTGRES_CONNECTION_URL" -c "$insert_migration"
echo "inserted migration"