-- Migration 001: Initial Vaultik schema -- All core tables for tracking files, chunks, blobs, snapshots, and uploads. -- Files table: stores metadata about files in the filesystem CREATE TABLE IF NOT EXISTS files ( id TEXT PRIMARY KEY, -- UUID path TEXT NOT NULL UNIQUE, source_path TEXT NOT NULL DEFAULT '', -- The source directory this file came from mtime INTEGER NOT NULL, -- whole seconds since the Unix epoch mtime_nsec INTEGER NOT NULL, -- nanoseconds within that second, 0 to 999999999 size INTEGER NOT NULL, mode INTEGER NOT NULL, uid INTEGER NOT NULL, gid INTEGER NOT NULL, link_target TEXT ); -- Create index on path for efficient lookups CREATE INDEX IF NOT EXISTS idx_files_path ON files(path); -- File chunks table: maps files to their constituent chunks CREATE TABLE IF NOT EXISTS file_chunks ( file_id TEXT NOT NULL, idx INTEGER NOT NULL, chunk_hash TEXT NOT NULL, PRIMARY KEY (file_id, idx), FOREIGN KEY (file_id) REFERENCES files(id) ON DELETE CASCADE, FOREIGN KEY (chunk_hash) REFERENCES chunks(chunk_hash) ); -- Index for efficient chunk lookups (used in orphan detection) CREATE INDEX IF NOT EXISTS idx_file_chunks_chunk_hash ON file_chunks(chunk_hash); -- Chunks table: stores unique content-defined chunks CREATE TABLE IF NOT EXISTS chunks ( chunk_hash TEXT PRIMARY KEY, size INTEGER NOT NULL ); -- Blobs table: stores packed, compressed, and encrypted blob information CREATE TABLE IF NOT EXISTS blobs ( id TEXT PRIMARY KEY, blob_hash TEXT UNIQUE, created_ts INTEGER NOT NULL, finished_ts INTEGER, uncompressed_size INTEGER NOT NULL DEFAULT 0, compressed_size INTEGER NOT NULL DEFAULT 0, uploaded_ts INTEGER ); -- Blob chunks table: maps chunks to the blobs that contain them CREATE TABLE IF NOT EXISTS blob_chunks ( blob_id TEXT NOT NULL, chunk_hash TEXT NOT NULL, offset INTEGER NOT NULL, length INTEGER NOT NULL, PRIMARY KEY (blob_id, chunk_hash), FOREIGN KEY (blob_id) REFERENCES blobs(id) ON DELETE CASCADE, FOREIGN KEY (chunk_hash) REFERENCES chunks(chunk_hash) ); -- Index for efficient chunk lookups (used in orphan detection) CREATE INDEX IF NOT EXISTS idx_blob_chunks_chunk_hash ON blob_chunks(chunk_hash); -- Chunk files table: reverse mapping of chunks to files CREATE TABLE IF NOT EXISTS chunk_files ( chunk_hash TEXT NOT NULL, file_id TEXT NOT NULL, file_offset INTEGER NOT NULL, length INTEGER NOT NULL, PRIMARY KEY (chunk_hash, file_id), FOREIGN KEY (chunk_hash) REFERENCES chunks(chunk_hash), FOREIGN KEY (file_id) REFERENCES files(id) ON DELETE CASCADE ); -- Index for efficient file lookups (used in orphan detection) CREATE INDEX IF NOT EXISTS idx_chunk_files_file_id ON chunk_files(file_id); -- Snapshots table: tracks backup snapshots CREATE TABLE IF NOT EXISTS snapshots ( id TEXT PRIMARY KEY, hostname TEXT NOT NULL, vaultik_version TEXT NOT NULL, vaultik_git_revision TEXT NOT NULL, started_at INTEGER NOT NULL, completed_at INTEGER, file_count INTEGER NOT NULL DEFAULT 0, chunk_count INTEGER NOT NULL DEFAULT 0, blob_count INTEGER NOT NULL DEFAULT 0, total_size INTEGER NOT NULL DEFAULT 0, blob_size INTEGER NOT NULL DEFAULT 0, blob_uncompressed_size INTEGER NOT NULL DEFAULT 0, compression_ratio REAL NOT NULL DEFAULT 1.0, compression_level INTEGER NOT NULL DEFAULT 3, upload_bytes INTEGER NOT NULL DEFAULT 0, upload_duration_ms INTEGER NOT NULL DEFAULT 0 ); -- Snapshot files table: maps snapshots to files CREATE TABLE IF NOT EXISTS snapshot_files ( snapshot_id TEXT NOT NULL, file_id TEXT NOT NULL, PRIMARY KEY (snapshot_id, file_id), FOREIGN KEY (snapshot_id) REFERENCES snapshots(id) ON DELETE CASCADE, FOREIGN KEY (file_id) REFERENCES files(id) ON DELETE CASCADE ); -- Index for efficient file lookups (used in orphan detection) CREATE INDEX IF NOT EXISTS idx_snapshot_files_file_id ON snapshot_files(file_id); -- Snapshot blobs table: maps snapshots to blobs CREATE TABLE IF NOT EXISTS snapshot_blobs ( snapshot_id TEXT NOT NULL, blob_id TEXT NOT NULL, blob_hash TEXT NOT NULL, PRIMARY KEY (snapshot_id, blob_id), FOREIGN KEY (snapshot_id) REFERENCES snapshots(id) ON DELETE CASCADE, FOREIGN KEY (blob_id) REFERENCES blobs(id) ON DELETE CASCADE ); -- Index for efficient blob lookups (used in orphan detection) CREATE INDEX IF NOT EXISTS idx_snapshot_blobs_blob_id ON snapshot_blobs(blob_id); -- Uploads table: tracks blob upload metrics CREATE TABLE IF NOT EXISTS uploads ( blob_hash TEXT PRIMARY KEY, snapshot_id TEXT NOT NULL, uploaded_at INTEGER NOT NULL, size INTEGER NOT NULL, duration_ms INTEGER NOT NULL, FOREIGN KEY (blob_hash) REFERENCES blobs(blob_hash), FOREIGN KEY (snapshot_id) REFERENCES snapshots(id) ON DELETE CASCADE ); -- Index for efficient snapshot lookups CREATE INDEX IF NOT EXISTS idx_uploads_snapshot_id ON uploads(snapshot_id); -- Local metadata: keyed, host-local settings that bind the state of the -- local index database to external context. The primary use is -- storage_url: once a backup writes blobs to a destination, the local -- index is only valid against that destination — if the configured -- storage_url later changes, the scanner would silently think already- -- known chunks are still on the new (empty) destination and skip -- uploading them, corrupting future snapshots. On every mutating -- command startup, we compare the configured storage_url to the stored -- one and refuse to proceed on mismatch. CREATE TABLE IF NOT EXISTS local_meta ( key TEXT PRIMARY KEY, value TEXT NOT NULL );