#!/usr/bin/env bash set -euo pipefail # Repair rebuildable FTS corruption by rebuilding a clean SQLite file from the # readable canonical tables, then swapping the rebuilt file into place. DB_PATH=${SQLITE_DB_PATH:-} if [ -z "${DB_PATH}" ] && [ -f ".env.local" ]; then DB_PATH=$(grep -E '^SQLITE_DB_PATH=' .env.local | sed 's/^SQLITE_DB_PATH=//' | sed 's/^"\(.*\)"$/\1/') || true fi if [ -z "${DB_PATH}" ]; then DB_PATH="$HOME/Library/Application Support/RA-H/db/rah.sqlite" fi if [ ! -f "$DB_PATH" ]; then echo "Error: Resolved DB not found: $DB_PATH" >&2 exit 1 fi DB_DIR="$(dirname "$DB_PATH")" DB_NAME="$(basename "$DB_PATH")" ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" VEC_EXTENSION_PATH="${SQLITE_VEC_EXTENSION_PATH:-$ROOT_DIR/vendor/sqlite-extensions/vec0.dylib}" TS=$(date +"%Y%m%d_%H%M%S") RAW_BACKUP_DIR="$DB_DIR/working/fts_repair_${TS}" REBUILT_DB="$DB_DIR/${DB_NAME}.rebuilt.${TS}" QUOTED_DB_PATH=${DB_PATH//\'/\'\'} HAS_SOURCE_VEC_NODES=$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='vec_nodes';") HAS_SOURCE_VEC_CHUNKS=$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='vec_chunks';") VEC_SQL_HEADER="" VEC_SQL_BODY="" if [ -f "$VEC_EXTENSION_PATH" ]; then if [ "$HAS_SOURCE_VEC_NODES" -gt 0 ] || [ "$HAS_SOURCE_VEC_CHUNKS" -gt 0 ]; then VEC_SQL_HEADER=".load $VEC_EXTENSION_PATH" VEC_SQL_BODY=" CREATE VIRTUAL TABLE vec_nodes USING vec0( node_id INTEGER PRIMARY KEY, embedding FLOAT[1536] ); CREATE VIRTUAL TABLE vec_chunks USING vec0( chunk_id INTEGER PRIMARY KEY, embedding FLOAT[1536] ); " if [ "$HAS_SOURCE_VEC_NODES" -gt 0 ]; then VEC_SQL_BODY="$VEC_SQL_BODY INSERT INTO vec_nodes(node_id, embedding) SELECT node_id, embedding FROM source.vec_nodes; " fi if [ "$HAS_SOURCE_VEC_CHUNKS" -gt 0 ]; then VEC_SQL_BODY="$VEC_SQL_BODY INSERT INTO vec_chunks(chunk_id, embedding) SELECT chunk_id, embedding FROM source.vec_chunks; " fi fi elif [ "$HAS_SOURCE_VEC_NODES" -gt 0 ] || [ "$HAS_SOURCE_VEC_CHUNKS" -gt 0 ]; then echo "Warning: sqlite-vec extension not found at $VEC_EXTENSION_PATH; vec tables will not be restored." >&2 fi mkdir -p "$RAW_BACKUP_DIR" cp -p "$DB_PATH" "$RAW_BACKUP_DIR/$DB_NAME" if [ -f "${DB_PATH}-wal" ]; then cp -p "${DB_PATH}-wal" "$RAW_BACKUP_DIR/${DB_NAME}-wal" fi if [ -f "${DB_PATH}-shm" ]; then cp -p "${DB_PATH}-shm" "$RAW_BACKUP_DIR/${DB_NAME}-shm" fi echo "Raw backup saved to: $RAW_BACKUP_DIR" echo "Preflight source probes:" sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM nodes;" | sed 's/^/ nodes: /' sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM edges;" | sed 's/^/ edges: /' sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM chunks;" | sed 's/^/ chunks: /' sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM nodes_fts;" | sed 's/^/ nodes_fts: /' || true sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM chunks_fts;" | sed 's/^/ chunks_fts: /' || true rm -f "$REBUILT_DB" "${REBUILT_DB}-wal" "${REBUILT_DB}-shm" sqlite3 "$REBUILT_DB" <