#!/bin/sh
# Migrator script for gobin
set -e
MIGRATION_PATH="${MIGRATION_PATH:-./migrations}"
if [ -z "$DATABASE_URI" ]; then
printf 'DATABASE_URI environment variable is not set\n'
exit 1
fi
# Helper functions
run_sql() {
psql "$@" "$DATABASE_URI"
}
is_migrated() {
name="$1"
printf '%s' "$migrations" | grep "$name" >/dev/null
}
apply_migration() {
name="$1"
if [ -z "$name" ]; then
printf 'Usage: gobin-migrate apply NAME'
exit
fi
if is_migrated "$name"; then
printf '%s: already applied, skipping\n' "$name"
return
fi
file="$MIGRATION_PATH/$name/up.sql"
if [ ! -f "$file" ]; then
printf 'Migration has not been found: %s\n' "$file"
exit 1
fi
printf 'Applying migration %s\n' "$name"
run_sql -f "$file" && \
run_sql -c "insert into _gobin_migrations (name) values ('$name');" >/dev/null
}
revert_migration() {
name="$1"
if [ -z "$name" ]; then
printf 'Usage: gobin-migrate revert NAME'
exit
fi
if ! is_migrated "$name"; then
printf '%s: not applied, skipping\n' "$name"
return
fi
file="$MIGRATION_PATH/$name/down.sql"
if [ ! -f "$file" ]; then
printf 'Reverse migration has not been found: %s\n' "$file"
exit 1
fi
printf 'Reverting migration %s\n' "$name"
run_sql -f "$file" && \
run_sql -c "delete from _gobin_migrations where name='$name';" >/dev/null
}
up_migrations() {
for name in `ls "$MIGRATION_PATH"`; do
apply_migration "$name"
done
}
# Create migrations table
run_sql -c '
create table if not exists _gobin_migrations (
name varchar(255) primary key,
created_at timestamp default now()
);' 2>/dev/null >/dev/null
migrations="$(run_sql --csv -c 'select * from _gobin_migrations;' | \
tail -n +2 | \
awk -F',' '{ print $1 }')"
case "$1" in
apply)
shift 1
apply_migration "$@"
;;
revert)
shift 1
revert_migration "$@"
;;
up)
up_migrations
;;
*)
printf 'Usage: gobin-migrate <up|apply|revert> ARGUMENTS\n'
;;
esac