#!/bin/sh set -eu ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd) cd "$ROOT" if [ "$#" -ne 1 ]; then echo "Usage: $0 PATH_TO_CUSTOM_FORMAT_DUMP" >&2 exit 1 fi dump=$1 checksum="$dump.sha256" if [ ! -f "$dump" ] || [ ! -s "$dump" ]; then echo "Dump does not exist or is empty: $dump" >&2 exit 1 fi if [ ! -f "$checksum" ]; then echo "Checksum manifest is required: $checksum" >&2 exit 1 fi env_file="$ROOT/.env" if [ ! -f "$env_file" ]; then echo "Missing $env_file." >&2 exit 1 fi read_env_value() { key=$1 awk -v key="$key" ' index($0, key "=") == 1 { print substr($0, length(key) + 2) found = 1 exit } END { if (!found) exit 1 } ' "$env_file" } database_mode=$(read_env_value DATABASE_MODE 2>/dev/null || printf container) postgres_db=$(read_env_value POSTGRES_DB 2>/dev/null || true) postgres_user=$(read_env_value POSTGRES_USER 2>/dev/null || true) database_url=$(read_env_value DATABASE_URL 2>/dev/null || true) if [ "$database_mode" != container ]; then echo "restore-drill-compose.sh only operates on DATABASE_MODE=container." >&2 exit 1 fi : "${postgres_db:?Set POSTGRES_DB in .env}" : "${postgres_user:?Set POSTGRES_USER in .env}" : "${database_url:?Set DATABASE_URL in .env}" dump_dir=$(CDPATH='' cd -- "$(dirname -- "$dump")" && pwd) dump_name=$(basename -- "$dump") ( cd "$dump_dir" sha256sum --check --status "$(basename -- "$checksum")" ) compose() { "$ROOT/scripts/compose.sh" "$env_file" "$@" } compose exec -T db pg_restore --list <"$dump" >/dev/null drill_db="who_need_help_restore_drill_$(date -u +%Y%m%d%H%M%S)_$$" created=false cleanup() { if [ "$created" = true ]; then compose exec -T db \ dropdb --username "$postgres_user" --if-exists "$drill_db" >/dev/null fi } trap cleanup EXIT HUP INT TERM compose exec -T db \ createdb \ --username "$postgres_user" \ --template template0 \ "$drill_db" created=true compose exec -T db \ pg_restore \ --username "$postgres_user" \ --dbname "$drill_db" \ --exit-on-error \ --no-owner \ --no-privileges <"$dump" tables=$( compose exec -T db \ psql --username "$postgres_user" --dbname "$drill_db" --tuples-only --no-align \ --command " SELECT tablename FROM pg_tables WHERE schemaname = 'public' AND tablename <> 'spatial_ref_sys' ORDER BY tablename; " ) table_count=0 total_rows=0 for table in $tables; do restored_count=$( compose exec -T db \ psql --username "$postgres_user" --dbname "$drill_db" --tuples-only --no-align \ --command "SELECT count(*) FROM \"$table\";" ) table_count=$((table_count + 1)) total_rows=$((total_rows + restored_count)) done if [ "$table_count" -eq 0 ]; then echo "The restored database contains no public application tables." >&2 exit 1 fi postgis_version=$( compose exec -T db \ psql --username "$postgres_user" --dbname "$drill_db" --tuples-only --no-align \ --command "SELECT PostGIS_Lib_Version();" ) case "$database_url" in *\?*) database_base=${database_url%%\?*} database_query="?${database_url#*\?}" ;; *) database_base=$database_url database_query= ;; esac database_prefix=${database_base%/*} if [ "$database_prefix" = "$database_base" ]; then echo "Could not derive the temporary drill DATABASE_URL." >&2 exit 1 fi drill_database_url="$database_prefix/$drill_db$database_query" compose run --rm --no-deps \ --env APP_ROLE=migrate \ --env "DATABASE_URL=$drill_database_url" \ migrate /app/bin/migrate compose run --rm --no-deps \ --env APP_ROLE=migrate \ --env "DATABASE_URL=$drill_database_url" \ migrate /app/bin/who_need_help eval 'WhoNeedHelp.Release.await_migrations()' migration_count=$( compose exec -T db \ psql --username "$postgres_user" --dbname "$drill_db" --tuples-only --no-align \ --command "SELECT count(*) FROM schema_migrations;" ) compose exec -T db \ dropdb --username "$postgres_user" "$drill_db" created=false trap - EXIT HUP INT TERM remaining=$( compose exec -T db \ psql --username "$postgres_user" --dbname postgres --tuples-only --no-align \ --command "SELECT count(*) FROM pg_database WHERE datname = '$drill_db';" ) if [ "$remaining" != "0" ]; then echo "Restore drill database was not removed: $drill_db" >&2 exit 1 fi echo "Restore drill passed for: $dump_name" echo "Readable public tables: $table_count" echo "Restored rows read: $total_rows" echo "Applied migrations: $migration_count" echo "PostGIS library: $postgis_version" echo "Temporary database removed: $drill_db"