#!/bin/bash
# sqlmorph — Oracle PL/SQL install script.  Built by Oninit LLC.
#
# Installs every *.sql file in the current directory (or BUNDLE_DIR) into
# the target Oracle database via sqlplus. Emitted .sql files use
# `CREATE OR REPLACE PROCEDURE/FUNCTION` (idempotent on Oracle); pipelined
# iterator bundles also re-create their TYPE row/tbl objects.
#
# Each file is run via `sqlplus -S user/pw@db @<file>` with EXIT ON ERROR
# so the script halts on the first install failure.
#
# Usage:
#   ./install.oracle.sh -u <user> -p <password> -c <connect-string>
#   ./install.oracle.sh -u sqlmorph -p secret -c localhost:1521/FREEPDB1
#
# Or via env:
#   ORA_USER=sqlmorph ORA_PWD=secret ORA_CONNECT=localhost:1521/FREEPDB1 \
#       ./install.oracle.sh
set -euo pipefail

USER="${ORA_USER:-}"
PWD="${ORA_PWD:-}"
CONNECT="${ORA_CONNECT:-}"
BUNDLE_DIR="${BUNDLE_DIR:-.}"

while [[ $# -gt 0 ]]; do
    case "$1" in
        -u) USER="$2"; shift 2 ;;
        -p) PWD="$2"; shift 2 ;;
        -c) CONNECT="$2"; shift 2 ;;
        -h|--help) sed -n '2,21p' "$0" | sed 's/^# \?//' ; exit 0 ;;
        *) echo "unknown arg: $1" >&2 ; exit 2 ;;
    esac
done

if [[ -z "$USER" || -z "$PWD" || -z "$CONNECT" ]]; then
    echo "Oracle USER + PWD + CONNECT required (set ORA_USER / ORA_PWD / ORA_CONNECT or pass -u/-p/-c)." >&2
    exit 2
fi

if ! command -v sqlplus >/dev/null 2>&1; then
    echo "sqlplus not on PATH — install the Oracle instant client." >&2
    exit 2
fi

shopt -s nullglob
ordered=("$BUNDLE_DIR"/*.sql)

if [[ ${#ordered[@]} -eq 0 ]]; then
    echo "no *.sql files found in $BUNDLE_DIR" >&2
    exit 2
fi

echo "==> sqlmorph Oracle install (user=$USER, connect=$CONNECT)"
fail=0
for f in "${ordered[@]}"; do
    echo "    sqlplus @$f"
    # The leading `WHENEVER SQLERROR EXIT FAILURE` aborts the script on
    # PL/SQL compile/runtime errors so we don't keep installing past a
    # broken procedure.
    if ! { echo "WHENEVER SQLERROR EXIT FAILURE"
           echo "@$f"
           echo "EXIT" ; } | sqlplus -S -L "$USER/$PWD@$CONNECT"; then
        echo "    FAILED: $f" >&2
        fail=1
    fi
done
echo "==> $( [ $fail -eq 0 ] && echo 'ok' || echo 'errors above' )"
exit $fail
