2026-06-25 15:53:01 +08:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
skill_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
|
|
|
|
2026-07-15 16:13:46 +08:00
|
|
|
environment="online"
|
|
|
|
|
if [[ "${1:-}" == "online" || "${1:-}" == "production" || "${1:-}" == "test" ]]; then
|
|
|
|
|
environment="$1"
|
|
|
|
|
shift
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
case "${environment}" in
|
|
|
|
|
online|production)
|
|
|
|
|
password_file="${HIGHGO_PASSWORD_FILE:-$skill_dir/.password}"
|
|
|
|
|
ssh_host="${HIGHGO_ONLINE_SSH_HOST:-root@124.243.245.42}"
|
|
|
|
|
ssh_port="${HIGHGO_ONLINE_SSH_PORT:-}"
|
|
|
|
|
psql_path="${HIGHGO_ONLINE_PSQL_PATH:-/opt/HighGo4.5.7-see/bin/psql}"
|
|
|
|
|
db_host="${HIGHGO_ONLINE_DB_HOST:-39.98.44.136}"
|
|
|
|
|
db_port="${HIGHGO_ONLINE_DB_PORT:-6023}"
|
|
|
|
|
db_name="${HIGHGO_ONLINE_DB_NAME:-highgo}"
|
|
|
|
|
db_user="${HIGHGO_ONLINE_DB_USER:-sysdba}"
|
|
|
|
|
;;
|
|
|
|
|
test)
|
|
|
|
|
password_file="${HIGHGO_TEST_PASSWORD_FILE:-${HIGHGO_PASSWORD_FILE:-$skill_dir/.password}}"
|
|
|
|
|
ssh_host="${HIGHGO_TEST_SSH_HOST:-root@47.111.103.66}"
|
|
|
|
|
ssh_port="${HIGHGO_TEST_SSH_PORT:-22}"
|
|
|
|
|
psql_path="${HIGHGO_TEST_PSQL_PATH:-/opt/HighGo4.5.7-see/bin/psql}"
|
|
|
|
|
db_host="${HIGHGO_TEST_DB_HOST:-127.0.0.1}"
|
|
|
|
|
db_port="${HIGHGO_TEST_DB_PORT:-5866}"
|
|
|
|
|
db_name="${HIGHGO_TEST_DB_NAME:-highgo}"
|
|
|
|
|
db_user="${HIGHGO_TEST_DB_USER:-sysdba}"
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
echo "Unknown environment: ${environment}" >&2
|
|
|
|
|
echo "Usage: $0 [online|production|test] 'SELECT ...'" >&2
|
|
|
|
|
exit 2
|
|
|
|
|
;;
|
|
|
|
|
esac
|
2026-06-25 15:53:01 +08:00
|
|
|
|
|
|
|
|
if [[ ! -r "$password_file" ]]; then
|
|
|
|
|
echo "HighGo password file is missing or unreadable: $password_file" >&2
|
|
|
|
|
exit 2
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [[ $# -eq 0 ]]; then
|
2026-07-15 16:13:46 +08:00
|
|
|
echo "Usage: $0 [online|production|test] 'SELECT ...'" >&2
|
2026-06-25 15:53:01 +08:00
|
|
|
exit 2
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
sql="$*"
|
|
|
|
|
if [[ ! "$sql" =~ ^[[:space:]]*(SELECT|select|WITH|with|SHOW|show|EXPLAIN|explain)([[:space:]]|$) ]]; then
|
|
|
|
|
echo "Rejected: only SELECT, WITH, SHOW, and EXPLAIN queries are allowed." >&2
|
|
|
|
|
exit 3
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
sql_without_final_semicolon="${sql%;}"
|
|
|
|
|
if [[ "$sql_without_final_semicolon" == *';'* ]]; then
|
|
|
|
|
echo "Rejected: multiple SQL statements are not allowed." >&2
|
|
|
|
|
exit 3
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
password="$(<"$password_file")"
|
|
|
|
|
sql_base64="$(printf '%s' "$sql" | base64 | tr -d '\n')"
|
|
|
|
|
|
2026-07-15 16:13:46 +08:00
|
|
|
printf -v quoted_psql_path '%q' "$psql_path"
|
|
|
|
|
printf -v quoted_db_host '%q' "$db_host"
|
|
|
|
|
printf -v quoted_db_port '%q' "$db_port"
|
|
|
|
|
printf -v quoted_db_user '%q' "$db_user"
|
|
|
|
|
printf -v quoted_db_name '%q' "$db_name"
|
|
|
|
|
|
|
|
|
|
ssh_args=(-o BatchMode=yes -o ConnectTimeout=10)
|
|
|
|
|
if [[ -n "${ssh_port}" ]]; then
|
|
|
|
|
ssh_args+=(-p "${ssh_port}")
|
|
|
|
|
fi
|
|
|
|
|
|
2026-06-25 15:53:01 +08:00
|
|
|
{
|
|
|
|
|
printf '%s\n' "$password"
|
|
|
|
|
printf '%s\n' "$sql_base64"
|
2026-07-15 16:13:46 +08:00
|
|
|
} | ssh "${ssh_args[@]}" "$ssh_host" \
|
|
|
|
|
"read -r PGPASSWORD; read -r SQL_BASE64; export PGPASSWORD; export PGOPTIONS='-c default_transaction_read_only=on -c search_path=shz,public -c statement_timeout=30000'; SQL=\$(printf '%s' \"\$SQL_BASE64\" | base64 -d); exec ${quoted_psql_path} -X --no-psqlrc -h ${quoted_db_host} -p ${quoted_db_port} -U ${quoted_db_user} -d ${quoted_db_name} -v ON_ERROR_STOP=1 -P pager=off -c \"\$SQL\""
|