diff --git a/scripts/enterdb.sh b/scripts/enterdb.sh new file mode 100644 index 0000000..32ffa94 --- /dev/null +++ b/scripts/enterdb.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env sh +set -eu + +SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +PROJECT_DIR=$(dirname -- "$SCRIPT_DIR") +cd "$PROJECT_DIR" + +fatal() { + printf 'enterdb: %s\n' "$*" >&2 + exit 1 +} + +command -v docker >/dev/null 2>&1 || fatal "docker is not available in PATH" +docker compose version >/dev/null 2>&1 || fatal "docker compose is not available" + +service_running() { + docker compose ps --status running --services 2>/dev/null | grep -Fxq "$1" +} + +# DATABASE_URL from the running application is the source of truth for the selected database engine. +DATABASE_URL_VALUE="" +if service_running app; then + DATABASE_URL_VALUE=$(docker compose exec -T app sh -c 'printf "%s" "${DATABASE_URL:-}"' 2>/dev/null || true) +fi + +case "$DATABASE_URL_VALUE" in + postgres://*|postgresql://*) + DATABASE_ENGINE=postgres + ;; + mysql://*) + DATABASE_ENGINE=mysql + ;; + sqlite://*) + fatal "the application uses SQLite; this script supports PostgreSQL and MySQL" + ;; + "") + POSTGRES_RUNNING=false + MYSQL_RUNNING=false + service_running postgres && POSTGRES_RUNNING=true + service_running mysql && MYSQL_RUNNING=true + + if [ "$POSTGRES_RUNNING" = true ] && [ "$MYSQL_RUNNING" = false ]; then + DATABASE_ENGINE=postgres + elif [ "$MYSQL_RUNNING" = true ] && [ "$POSTGRES_RUNNING" = false ]; then + DATABASE_ENGINE=mysql + elif [ "$POSTGRES_RUNNING" = true ] && [ "$MYSQL_RUNNING" = true ]; then + fatal "PostgreSQL and MySQL are both running, and DATABASE_URL could not be read from the app service" + else + fatal "no running postgres or mysql service was found" + fi + ;; + *) + fatal "unsupported DATABASE_URL: $DATABASE_URL_VALUE" + ;; +esac + +case "$DATABASE_ENGINE" in + postgres) + service_running postgres || fatal "the postgres service is not running" + printf 'Connecting to PostgreSQL...\n' >&2 + exec docker compose exec postgres sh -lc ' + export PGPASSWORD="${POSTGRES_PASSWORD:-rustpad}" + exec psql --host=127.0.0.1 --username="${POSTGRES_USER:-rustpad}" --dbname="${POSTGRES_DB:-rustpad}" + ' + ;; + mysql) + service_running mysql || fatal "the mysql service is not running" + printf 'Connecting to MySQL...\n' >&2 + exec docker compose exec mysql sh -lc ' + if command -v mysql >/dev/null 2>&1; then + client=mysql + elif command -v mariadb >/dev/null 2>&1; then + client=mariadb + else + echo "enterdb: no mysql/mariadb client is available in the container" >&2 + exit 1 + fi + + export MYSQL_PWD="${MYSQL_PASSWORD:-rustpad}" + exec "$client" --user="${MYSQL_USER:-rustpad}" "${MYSQL_DATABASE:-rustpad}" + ' + ;; +esac \ No newline at end of file