2023-02-22 01:44:27 +00:00
|
|
|
#####################################################################
|
|
|
|
|
|
|
|
DEPENDENCIES+=(
|
|
|
|
pg_dump
|
|
|
|
pg_restore
|
|
|
|
psql
|
|
|
|
)
|
|
|
|
|
|
|
|
REQUIRED_ENV+=()
|
|
|
|
|
|
|
|
#####################################################################
|
|
|
|
|
|
|
|
PSQL() {
|
2023-08-24 23:09:30 +00:00
|
|
|
POSTGRES__SET_LOGIN_ARGS $@
|
|
|
|
eval PGPASSWORD=$(printf '%q ' "$DB_PASS") psql ${PSQL_ARGS[@]}
|
2023-02-22 01:44:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#####################################################################
|
|
|
|
|
|
|
|
PG_DUMP() {
|
2023-08-24 23:09:30 +00:00
|
|
|
local DATA_DIR
|
2023-02-22 01:44:27 +00:00
|
|
|
POSTGRES__SET_LOGIN_ARGS --verbose $@
|
|
|
|
|
|
|
|
local OUTPUT_FILE="$DATA_DIR/backup.$(date '+%Y-%m-%d.%H-%M')"
|
|
|
|
|
2023-08-24 23:09:30 +00:00
|
|
|
|
|
|
|
|
2023-02-22 01:44:27 +00:00
|
|
|
STATUS "
|
2023-08-24 23:09:30 +00:00
|
|
|
making backup of : $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME
|
2023-02-22 01:44:27 +00:00
|
|
|
|
|
|
|
(compressed) : '$OUTPUT_FILE.dump'
|
|
|
|
(safe-raw) : '$OUTPUT_FILE.sql'
|
|
|
|
(raw) : '$OUTPUT_FILE.raw.sql'
|
|
|
|
"
|
|
|
|
|
|
|
|
: \
|
|
|
|
&& STATUS "creating compressed backup..." \
|
2023-08-24 23:09:30 +00:00
|
|
|
&& eval PGPASSWORD=$(printf '%q ' "$DB_PASS") psql ${PSQL_ARGS[@]} \
|
|
|
|
--format custom \
|
|
|
|
--file "$OUTPUT_FILE.dump" \
|
|
|
|
--verbose \
|
2023-02-22 01:44:27 +00:00
|
|
|
&& SUCCESS "completed compressed backup" \
|
|
|
|
&& STATUS "creating raw backup..." \
|
2023-08-24 23:09:30 +00:00
|
|
|
&& pg_restore -f "$OUTPUT_FILE.raw.sql" "$OUTPUT_FILE.dump" \
|
2023-02-22 01:44:27 +00:00
|
|
|
&& SUCCESS "completed raw backup" \
|
|
|
|
&& STATUS "creating single-transaction raw backup..." \
|
2023-08-24 23:09:30 +00:00
|
|
|
&& { echo "BEGIN;\n"; cat "$OUTPUT_FILE.raw.sql"; echo "\nEND;" } > "$OUTPUT_FILE.sql" \
|
2023-02-22 01:44:27 +00:00
|
|
|
&& SUCCESS "completed single-transaction raw backup" \
|
2023-08-24 23:09:30 +00:00
|
|
|
|| { ERROR "error creating backup for '$DB_HOST/$DB_NAME' (see above)"; return 1; }
|
|
|
|
|
|
|
|
SUCCESS "
|
|
|
|
completed backup : $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME
|
|
|
|
|
|
|
|
(compressed) : '$OUTPUT_FILE.dump'
|
|
|
|
(safe-raw) : '$OUTPUT_FILE.sql'
|
|
|
|
(raw) : '$OUTPUT_FILE.raw.sql'
|
|
|
|
"
|
2023-02-22 01:44:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#####################################################################
|
|
|
|
|
|
|
|
PG_RESTORE() {
|
2023-08-24 23:09:30 +00:00
|
|
|
local _ARGS=()
|
|
|
|
local FILE
|
2023-02-22 01:44:27 +00:00
|
|
|
POSTGRES__SET_LOGIN_ARGS $@
|
|
|
|
|
|
|
|
local INPUT_FILE=$(find "$DATA_DIR"/backup.* -type f | FZF 'select database file to restore')
|
|
|
|
|
|
|
|
[ $INPUT_FILE ] && [ -f "$INPUT_FILE" ] || {
|
|
|
|
ERROR 'no file selected or missing backup file; aborting'
|
|
|
|
REMINDER "
|
|
|
|
backups must be *.sql or *.dump files starting with the prefix 'backup.'
|
|
|
|
in the following directory:
|
|
|
|
|
|
|
|
'$DATA_DIR'
|
|
|
|
"
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
local RAW=1
|
|
|
|
[[ $INPUT_FILE =~ \\.dump$ ]] && RAW=0
|
|
|
|
|
|
|
|
STATUS "
|
2023-08-24 23:09:30 +00:00
|
|
|
loading backup for : $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME
|
2023-02-22 01:44:27 +00:00
|
|
|
|
|
|
|
file : '$INPUT_FILE'
|
|
|
|
"
|
|
|
|
|
|
|
|
local EXIT_CODE
|
|
|
|
[[ $RAW -eq 1 ]] && {
|
|
|
|
REMINDER "
|
|
|
|
loading a backup from a raw sql dump may result in data loss
|
|
|
|
|
|
|
|
make sure your database is ready to accept the database file!
|
|
|
|
"
|
|
|
|
|
|
|
|
yN 'continue?' || ABORT
|
|
|
|
|
|
|
|
PSQL < "$INPUT_FILE"
|
|
|
|
EXIT_CODE=$?
|
|
|
|
}
|
|
|
|
|
|
|
|
[[ $RAW -eq 0 ]] && {
|
2023-08-24 23:09:30 +00:00
|
|
|
eval PGPASSWORD=$(printf '%q ' "$DB_PASS") pg_restore ${PSQL_ARGS[@]} \
|
2023-02-22 01:44:27 +00:00
|
|
|
--verbose \
|
|
|
|
--format custom \
|
|
|
|
--single-transaction \
|
|
|
|
"$INPUT_FILE"
|
|
|
|
EXIT_CODE=$?
|
|
|
|
}
|
|
|
|
|
|
|
|
[[ $EXIT_CODE -eq 0 ]] \
|
2023-08-24 23:09:30 +00:00
|
|
|
&& SUCCESS "finished restoring backup for '$DB_HOST/$DB_NAME'" \
|
|
|
|
|| ERROR "error restoring backup for '$DB_HOST/$DB_NAME' (see above)" \
|
2023-02-22 01:44:27 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
return $EXIT_CODE
|
|
|
|
}
|
|
|
|
|
|
|
|
#####################################################################
|
|
|
|
|
|
|
|
POSTGRES__LOGIN_INTERACTIVE() {
|
2023-08-24 23:09:30 +00:00
|
|
|
DEPENDENCIES=(pgcli) CHECK_ENVIRONMENT --optional \
|
|
|
|
&& COMMAND=pgcli || COMMAND=psql
|
|
|
|
|
|
|
|
[[ $COMMAND =~ psql ]] && WARNING "using 'psql' instead"
|
|
|
|
|
2023-02-22 01:44:27 +00:00
|
|
|
POSTGRES__SET_LOGIN_ARGS $@
|
|
|
|
|
2023-08-24 23:09:30 +00:00
|
|
|
STATUS "
|
|
|
|
performing login : $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME
|
|
|
|
working directory : $DATA_DIR
|
|
|
|
"
|
2023-02-22 01:44:27 +00:00
|
|
|
|
2023-08-24 23:09:30 +00:00
|
|
|
eval PGPASSWORD=$(printf '%q ' "$DB_PASS") $COMMAND ${PSQL_ARGS[@]}
|
2023-02-22 01:44:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#####################################################################
|
|
|
|
|
|
|
|
POSTGRES__SET_LOGIN_ARGS() {
|
2023-08-24 23:09:30 +00:00
|
|
|
# allow for manual override with PSQL_ARGS
|
|
|
|
[[ ${#PSQL_ARGS[@]} -gt 0 ]] && return 0
|
|
|
|
|
|
|
|
local DATA_DIR_PREFIX
|
|
|
|
|
2023-02-22 01:44:27 +00:00
|
|
|
while [[ $# -gt 0 ]]
|
|
|
|
do
|
|
|
|
case $1 in
|
2023-08-24 23:09:30 +00:00
|
|
|
-h | --host ) DB_HOST="$2"; shift 1 ;;
|
|
|
|
-p | --port ) DB_PORT="$2"; shift 1 ;;
|
|
|
|
-d | --name ) DB_NAME="$2"; shift 1 ;;
|
|
|
|
-U | --user ) DB_USER="$2"; shift 1 ;;
|
|
|
|
-P | --pass ) DB_PASS="$2"; shift 1 ;;
|
2023-02-22 01:44:27 +00:00
|
|
|
|
2023-08-24 23:09:30 +00:00
|
|
|
--file ) PSQL_FILE="$2"; shift 1 ;;
|
2023-02-22 01:44:27 +00:00
|
|
|
|
2023-08-24 23:09:30 +00:00
|
|
|
--data-dir-prefix ) DATA_DIR_PREFIX="$2"; shift 1 ;;
|
2023-02-22 01:44:27 +00:00
|
|
|
|
2023-08-24 23:09:30 +00:00
|
|
|
* ) PSQL_ARGS+=($1) ;;
|
2023-02-22 01:44:27 +00:00
|
|
|
esac
|
|
|
|
shift 1
|
|
|
|
done
|
|
|
|
|
2023-08-24 23:09:30 +00:00
|
|
|
[ $PSQL_FILE ] && [ ! -f "$PSQL_FILE" ] \
|
|
|
|
&& ERROR "no such file available:\n'$PSQL_FILE'"
|
2023-02-22 01:44:27 +00:00
|
|
|
|
2023-08-24 23:09:30 +00:00
|
|
|
CHECK_ERRORS
|
2023-02-22 01:44:27 +00:00
|
|
|
|
2023-08-24 23:09:30 +00:00
|
|
|
##########################################
|
|
|
|
|
|
|
|
[ $DATA_DIR_PREFIX ] && {
|
|
|
|
DATA_DIR="$SCWRYPTS_DATA_PATH/$DATA_DIR_PREFIX"
|
|
|
|
} || {
|
|
|
|
[ $DB_HOST ] && [ $DB_NAME ] \
|
|
|
|
&& DATA_DIR="$SCWRYPTS_DATA_PATH/db/$DB_HOST/$DB_NAME" \
|
|
|
|
|| DATA_DIR="$EXECUTION_DIR/temp-db" \
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
mkdir -p "$DATA_DIR"
|
2023-02-22 01:44:27 +00:00
|
|
|
cd "$DATA_DIR"
|
|
|
|
|
2023-08-24 23:09:30 +00:00
|
|
|
[ $DB_HOST ] || DB_HOST=127.0.0.1
|
|
|
|
[ $DB_PORT ] || DB_PORT=5432
|
|
|
|
[ $DB_NAME ] || DB_NAME=postgres
|
|
|
|
[ $DB_USER ] || DB_USER=postgres
|
2023-02-22 01:44:27 +00:00
|
|
|
|
2023-08-24 23:09:30 +00:00
|
|
|
PSQL_ARGS+=(-h $DB_HOST -p $DB_PORT -d $DB_NAME -U $DB_USER)
|
|
|
|
}
|