#!/usr/bin/env bash # =================================================================== # Holt die Server-Sicherungen auf diesen Rechner und prueft sie. # # Eine Sicherung, die auf derselben Platte liegt wie das Original, ist # keine Sicherung -- sie hilft gegen versehentliches Loeschen, aber nicht # gegen einen Plattenausfall. Deshalb dieser Schritt. # # Einfach ausfuehren: bash tools/sicherung-holen.sh # =================================================================== set -euo pipefail ZIEL="$HOME/Documents/Obelix/Sicherungen/workspace" mkdir -p "$ZIEL" echo "Hole Sicherungen vom Server ..." scp -q dogfather-server:/home/dogiweb/workspace-daten/sicherungen/*.db "$ZIEL/" # Die Datenbank kennt hochgeladene Dateien und PDFs nur ueber ihren # Namen -- die Dateien selbst liegen daneben im Dateisystem und stecken # NICHT in der Datenbanksicherung. Ohne diesen Schritt haette man nach # einem Plattenausfall eine Bibliothek voller Verweise auf PDFs, die es # nicht mehr gibt. # # Bewusst nur hier auf dem PC und nicht zusaetzlich auf dem Server: Eine # zweite Kopie auf derselben Platte hilft gegen nichts, was die erste # nicht schon ueberlebt haette. # # scp loescht nie etwas. Wer auf dem Server versehentlich ein PDF # entfernt, hat es hier weiterhin -- das ist Absicht, nicht Nachlaessigkeit. echo "Hole hochgeladene Dateien und die Bibliothek ..." mkdir -p "$ZIEL/dateien" "$ZIEL/wissen" scp -qr dogfather-server:/home/dogiweb/workspace-daten/dateien/. "$ZIEL/dateien/" 2>/dev/null || true scp -qr dogfather-server:/home/dogiweb/workspace-daten/wissen/. "$ZIEL/wissen/" 2>/dev/null || true echo " Dateien: $(find "$ZIEL/dateien" -type f 2>/dev/null | wc -l | tr -d " ") Stueck" echo " Bibliothek: $(find "$ZIEL/wissen" -type f 2>/dev/null | wc -l | tr -d " ") Stueck" # Geprueft wird mit Node, nicht mit dem sqlite3-Programm: Node bringt # SQLite seit Fassung 22 selbst mit, und auf diesem Windows-Rechner ist # sqlite3 gar nicht vorhanden -- die Pruefung haette dann nur # Fragezeichen ausgegeben und trotzdem "fertig" gemeldet. node -e ' const { DatabaseSync } = require("node:sqlite"); const { readdirSync, statSync } = require("node:fs"); const { join } = require("node:path"); const ziel = process.argv[1]; const dateien = readdirSync(ziel).filter((n) => n.endsWith(".db")).sort(); if (!dateien.length) { console.log("\nKeine Sicherung gefunden!"); process.exit(1); } console.log("\nAuf diesem Rechner liegen jetzt:"); let schlecht = 0; for (const name of dateien) { const pfad = join(ziel, name); const kb = Math.round(statSync(pfad).size / 1024); let zeile; try { const d = new DatabaseSync(pfad, { readOnly: true }); const heil = Object.values(d.prepare("PRAGMA integrity_check").get())[0]; const p = d.prepare("SELECT COUNT(*) AS n FROM personen").get().n; const t = d.prepare( "SELECT COUNT(*) AS n FROM sqlite_master WHERE type = \x27table\x27").get().n; d.close(); const gut = heil === "ok" && p > 0; if (!gut) schlecht++; zeile = `${gut ? "ok " : "FEHL"} ${heil}, ${p} Personen, ${t} Tabellen`; } catch (f) { schlecht++; zeile = "FEHL nicht lesbar: " + f.message; } console.log(` ${name.padEnd(28)} ${String(kb + " KB").padStart(8)} ${zeile}`); } console.log(schlecht ? `\n${schlecht} Sicherung(en) sind unbrauchbar!` : "\nAlle Sicherungen sind lesbar und enthalten Daten."); process.exit(schlecht ? 1 : 0); ' "$ZIEL"