~yerinalexey/gobin

214d93c3dc556c771887dbd53a6bace21b387b93 — Alexey Yerin 5 months ago b955d85
gobin-migrate: parse config, global options
2 files changed, 66 insertions(+), 21 deletions(-)

M README.md
M gobin-migrate
M README.md => README.md +9 -2
@@ 25,10 25,17 @@ go build

## Migrations
```sh
DATABASE_URI=postgres://.. ./gobin-migrate up
./gobin-migrate up
```

`DATABASE_URI` is the same as `databaseUri` in `config.toml`.
or

```sh
./gobin-migrate -c /etc/whatever.toml up
```

**Warning:** TOML parser in `gobin-migrate` is too simple and will not
handle all cases.

If something goes wrong, you can apply migrations manually by running
`up.sql` files in subdirectories of `./migrations`.

M gobin-migrate => gobin-migrate +57 -19
@@ 4,16 4,59 @@

set -e

MIGRATION_PATH="${MIGRATION_PATH:-./migrations}"

if [ -z "$DATABASE_URI" ]; then
  printf 'DATABASE_URI environment variable is not set\n'
migrations_path=./migrations
config=config.toml

usage() {
  cat <<EOF
Usage: gobin-migrate [-m PATH] [-c CONFIG] COMMAND [ARGUMENTS]

Options:
  -m PATH     - set migrations directory (default: ./migrations)
  -c CONFIG   - config file location (default: config.toml)

Commands:
  apply NAME  - run a migration against the databse
  revert NAME - revert a migration
  up          - run all pending migrations
EOF
  exit 1
fi
}

while getopts c:m: opt; do
  case "$opt" in
    c)
      config="$OPTARG"
      ;;
    m)
      migrations_path="$OPTARG"
      ;;
    *)
      usage
      ;;
  esac
done

shift $(($OPTIND - 1))

parse_config() {
  # Disclaimer: really poor TOML parser, do not use under any
  # circumstances

  # gobin accepts both databaseUri or database_uri
  database_uri="$(awk -F '=' '/^(databaseUri|database_uri)/ { gsub(/[ "]/, ""); print $2 }' "$config")"

  if [ -z "$database_uri" ]; then
    printf 'Complicated TOML or databaseUri (database_uri) field is missing\n'
    exit 1
  fi
}

parse_config

# Helper functions
run_sql() {
  psql "$@" "$DATABASE_URI"
  psql "$@" "$database_uri"
}

is_migrated() {


@@ 30,7 73,7 @@ apply_migration() {
    return
  fi

  file="$MIGRATION_PATH/$name/up.sql"
  file="$migrations_path/$name/up.sql"

  if [ ! -f "$file" ]; then
    printf 'Migration has not been found: %s\n' "$file"


@@ 51,7 94,7 @@ revert_migration() {
    return
  fi

  file="$MIGRATION_PATH/$name/down.sql"
  file="$migrations_path/$name/down.sql"

  if [ ! -f "$file" ]; then
    printf 'Reverse migration has not been found: %s\n' "$file"


@@ 65,17 108,18 @@ revert_migration() {
}

up_migrations() {
  for name in `ls "$MIGRATION_PATH"`; do
  for name in `ls "$migrations_path"`; do
    apply_migration "$name"
  done
}

# Create migrations table
run_sql -c '
set client_min_messages = error;
create table if not exists _gobin_migrations (
  name varchar(255) primary key,
  created_at timestamp default now()
);' 2>/dev/null >/dev/null
);' >/dev/null

migrations="$(run_sql --csv -c 'select name from _gobin_migrations;' | \
  tail -n +2)"


@@ 84,20 128,14 @@ case "$1" in
  apply)
    name="$2"

    if [ -z "$name" ]; then
      printf 'Usage: gobin-migrate apply NAME'
      exit
    fi
    [ -z "$name" ] && usage

    apply_migration "$name"
    ;;
  revert)
    name="$2"

    if [ -z "$name" ]; then
      printf 'Usage: gobin-migrate revert NAME'
      exit
    fi
    [ -z "$name" ] && usage

    revert_migration "$name"
    ;;


@@ 105,6 143,6 @@ case "$1" in
    up_migrations
    ;;
  *)
    printf 'Usage: gobin-migrate <up|apply|revert> ARGUMENTS\n'
    usage
    ;;
esac