Files
fn_registry/bash/functions/infra/backup_sqlite_db.sh
T
egutierrez 625569485f feat(doctor): add fn doctor CLI + 14 functions for system management
Adds `fn doctor` read-only diagnostic command with subcommands artefacts,
services, sync, uses-functions, unused, and --json flag for agents.
Each subcommand wraps a registry function in functions/infra/.

New functions:
- artefact_doctor, services_status, pc_locations_drift,
  audit_uses_functions, find_unused_functions (Go diagnostics)
- backup_sqlite_db, rotate_backups, wait_for_http, wait_for_port,
  port_kill, tail_journal, pre_commit_hook_install (bash utilities)
- notify_telegram (Go HTTP)
- backup_all pipeline (tag launcher)

Plus prior session leftovers (scan_secrets_in_dirty, append_diary_entry,
git utilities, http_session_cookie_middleware, compile/full-git pipelines).

Fixes pc_locations_drift filepath.Join bug with absolute dir_path.
Documents fn doctor in CLAUDE.md, .claude/rules/fn_doctor.md (rule 23),
docs/architecture.md, CHANGELOG.md (2026-05-07), and diary entry.

First fn doctor uses-functions run found drift in 7/12 apps (deuda
para sincronizar app.md con imports reales).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 01:42:10 +02:00

67 lines
1.9 KiB
Bash

#!/usr/bin/env bash
# backup_sqlite_db — Snapshot atomico de una BD SQLite usando VACUUM INTO.
# Mas seguro que cp: no corrompe si hay escrituras concurrentes.
backup_sqlite_db() {
local source="$1"
local dest="$2"
# Verificar dependencia sqlite3
if ! command -v sqlite3 &>/dev/null; then
echo "backup_sqlite_db: sqlite3 no encontrado en PATH" >&2
return 5
fi
# Verificar que source existe
if [[ ! -f "$source" ]]; then
echo "backup_sqlite_db: source no existe: $source" >&2
return 1
fi
# Verificar que source es SQLite valido (header magico)
local header
header=$(head -c 16 "$source" 2>/dev/null | strings | head -n1)
if [[ "$header" != "SQLite format 3" ]]; then
echo "backup_sqlite_db: source no es una BD SQLite valida: $source" >&2
return 2
fi
# Crear directorio destino si no existe
local dest_dir
dest_dir=$(dirname "$dest")
if [[ ! -d "$dest_dir" ]]; then
mkdir -p "$dest_dir" || {
echo "backup_sqlite_db: no se pudo crear directorio: $dest_dir" >&2
return 3
}
fi
# Si el destino existe, borrarlo para que VACUUM INTO no falle
if [[ -f "$dest" ]]; then
rm -f "$dest"
fi
# Ejecutar VACUUM INTO (escape de comillas simples en el path)
local escaped_dest="${dest//\'/\'\'}"
if ! sqlite3 "$source" "VACUUM INTO '${escaped_dest}';" 2>/dev/null; then
echo "backup_sqlite_db: fallo en VACUUM INTO: source=$source dest=$dest" >&2
return 3
fi
# Verificar que dest existe y tiene tamaño > 0
if [[ ! -f "$dest" ]]; then
echo "backup_sqlite_db: dest no fue creado: $dest" >&2
return 3
fi
local bytes
bytes=$(wc -c < "$dest" 2>/dev/null)
if [[ -z "$bytes" || "$bytes" -eq 0 ]]; then
echo "backup_sqlite_db: dest tiene tamaño 0: $dest" >&2
return 4
fi
echo "OK ${bytes} bytes -> ${dest}"
return 0
}