From 24d6f345f6c9f5d9843f493b6015e524a63d6a41 Mon Sep 17 00:00:00 2001 From: Username Date: Wed, 18 Feb 2026 00:28:27 +0100 Subject: [PATCH] tools: add ppf-db for database operations --- tools/ppf-db | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100755 tools/ppf-db diff --git a/tools/ppf-db b/tools/ppf-db new file mode 100755 index 0000000..0f0c644 --- /dev/null +++ b/tools/ppf-db @@ -0,0 +1,154 @@ +#!/bin/bash +# ppf-db -- manage PPF databases +# +# Usage: +# ppf-db [options] +# +# Commands: stats, purge-proxies, vacuum + +set -eu + +# Resolve to real path (handles symlinks from ~/.local/bin/) +SCRIPT_PATH="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")" +SCRIPT_DIR="$(dirname "$(readlink -f "$SCRIPT_PATH")")" +# shellcheck disable=SC1091 +. "$SCRIPT_DIR/lib/ppf-common.sh" + +PROXY_DB="/home/podman/ppf/data/proxies.sqlite" +URL_DB="/home/podman/ppf/data/websites.sqlite" + +# --------------------------------------------------------------------------- +# Usage +# --------------------------------------------------------------------------- +usage() { + cat < [options] + +Manage PPF databases on odin (master). + +Commands: + stats show proxy and URL counts + purge-proxies delete all proxies (keeps URLs) + vacuum reclaim disk space after purge + +Options: + --help show this help + --version show version + +Examples: + ppf-db stats + ppf-db purge-proxies + ppf-db vacuum +EOF + exit 0 +} + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- +run_sql() { + local db="$1" sql="$2" + ansible_cmd "$MASTER" -m raw -a \ + "sudo -u podman sqlite3 '$db' \"$sql\"" 2>/dev/null \ + | grep -vE '^\s*$|^odin|Shared connection|CHANGED|SUCCESS' +} + +# --------------------------------------------------------------------------- +# Commands +# --------------------------------------------------------------------------- +cmd_stats() { + section "Database stats (odin)" + + local proxies total_urls active_urls working + proxies=$(run_sql "$PROXY_DB" "SELECT COUNT(*) FROM proxylist;") + working=$(run_sql "$PROXY_DB" "SELECT COUNT(*) FROM proxylist WHERE failed=0 AND proto IS NOT NULL;") + total_urls=$(run_sql "$URL_DB" "SELECT COUNT(*) FROM uris;") + active_urls=$(run_sql "$URL_DB" "SELECT COUNT(*) FROM uris WHERE error=0;") + + log_info "Proxies: ${proxies} total, ${working} working" + log_info "URLs: ${total_urls} total, ${active_urls} active" +} + +cmd_purge_proxies() { + section "Purging proxies from odin" + + # Get counts before + local before + before=$(run_sql "$PROXY_DB" "SELECT COUNT(*) FROM proxylist;") + log_info "Proxies before: $before" + + # Stop container + log_info "Stopping container..." + compose_cmd "$MASTER" "down" > /dev/null 2>&1 \ + && log_ok "Container stopped" \ + || die "Failed to stop container" + + # Delete proxies + log_info "Deleting proxylist rows..." + run_sql "$PROXY_DB" "DELETE FROM proxylist;" > /dev/null 2>&1 + log_ok "Proxylist purged" + + # Vacuum to reclaim space + log_info "Vacuuming database..." + run_sql "$PROXY_DB" "VACUUM;" > /dev/null 2>&1 + log_ok "Database vacuumed" + + # Verify URLs intact + local urls_after + urls_after=$(run_sql "$URL_DB" "SELECT COUNT(*) FROM uris;") + log_ok "URLs preserved: $urls_after" + + # Start container + log_info "Starting container..." + compose_cmd "$MASTER" "up -d" > /dev/null 2>&1 \ + && log_ok "Container started" \ + || die "Failed to start container" +} + +cmd_vacuum() { + section "Vacuuming database (odin)" + + local before after + before=$(ansible_cmd "$MASTER" -m raw -a \ + "sudo -u podman ls -lh '$PROXY_DB'" 2>/dev/null \ + | grep -oE '[0-9]+[KMG]?' | head -1) + + run_sql "$PROXY_DB" "VACUUM;" > /dev/null 2>&1 + + after=$(ansible_cmd "$MASTER" -m raw -a \ + "sudo -u podman ls -lh '$PROXY_DB'" 2>/dev/null \ + | grep -oE '[0-9]+[KMG]?' | head -1) + + log_ok "Vacuumed: ${before:-?} -> ${after:-?}" +} + +# --------------------------------------------------------------------------- +# Parse args +# --------------------------------------------------------------------------- +[ $# -eq 0 ] && usage + +COMMAND="" + +while [ $# -gt 0 ]; do + case "$1" in + --help|-h) usage ;; + --version|-V) echo "ppf-db $PPF_TOOLS_VERSION"; exit 0 ;; + stats|purge-proxies|vacuum) + [ -n "$COMMAND" ] && die "Multiple commands given" + COMMAND="$1" + ;; + -*) die "Unknown option: $1" ;; + *) die "Unknown command: $1" ;; + esac + shift +done + +[ -z "$COMMAND" ] && die "No command given. Use: stats, purge-proxies, vacuum" + +case "$COMMAND" in + stats) cmd_stats ;; + purge-proxies) cmd_purge_proxies ;; + vacuum) cmd_vacuum ;; +esac + +printf "\n"