-- Migration 001: Initial schema -- Creates all tables for the pixa caching image proxy -- Source content blobs -- Files stored at: cache/src-content/// CREATE TABLE IF NOT EXISTS source_content ( content_hash TEXT PRIMARY KEY, content_type TEXT NOT NULL, size_bytes INTEGER NOT NULL, fetched_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -- Source URL metadata - maps URLs to content hashes -- JSON stored at: cache/src-metadata//.json CREATE TABLE IF NOT EXISTS source_metadata ( id INTEGER PRIMARY KEY AUTOINCREMENT, source_host TEXT NOT NULL, source_path TEXT NOT NULL, source_query TEXT NOT NULL DEFAULT '', path_hash TEXT NOT NULL, content_hash TEXT, status_code INTEGER NOT NULL, content_type TEXT, response_headers TEXT, fetched_at DATETIME DEFAULT CURRENT_TIMESTAMP, expires_at DATETIME, etag TEXT, last_modified TEXT, UNIQUE(source_host, source_path, source_query), FOREIGN KEY (content_hash) REFERENCES source_content(content_hash) ); CREATE INDEX IF NOT EXISTS idx_source_meta_host ON source_metadata(source_host); CREATE INDEX IF NOT EXISTS idx_source_meta_path_hash ON source_metadata(path_hash); CREATE INDEX IF NOT EXISTS idx_source_meta_expires ON source_metadata(expires_at); CREATE INDEX IF NOT EXISTS idx_source_meta_content_hash ON source_metadata(content_hash); -- Output/transformed content blobs -- Files stored at: cache/dst-content/// CREATE TABLE IF NOT EXISTS output_content ( content_hash TEXT PRIMARY KEY, content_type TEXT NOT NULL, size_bytes INTEGER NOT NULL, fetched_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -- Request cache - maps full request params to output content CREATE TABLE IF NOT EXISTS request_cache ( id INTEGER PRIMARY KEY AUTOINCREMENT, cache_key TEXT NOT NULL UNIQUE, source_metadata_id INTEGER NOT NULL, output_hash TEXT NOT NULL, width INTEGER NOT NULL, height INTEGER NOT NULL, format TEXT NOT NULL, quality INTEGER NOT NULL DEFAULT 85, fit_mode TEXT NOT NULL DEFAULT 'cover', fetched_at DATETIME DEFAULT CURRENT_TIMESTAMP, access_count INTEGER NOT NULL DEFAULT 1, FOREIGN KEY (source_metadata_id) REFERENCES source_metadata(id), FOREIGN KEY (output_hash) REFERENCES output_content(content_hash) ); CREATE INDEX IF NOT EXISTS idx_request_cache_key ON request_cache(cache_key); CREATE INDEX IF NOT EXISTS idx_request_cache_source ON request_cache(source_metadata_id); CREATE INDEX IF NOT EXISTS idx_request_cache_output ON request_cache(output_hash); CREATE INDEX IF NOT EXISTS idx_request_cache_fetched ON request_cache(fetched_at); -- Negative cache for failed fetches (404s, timeouts, etc.) CREATE TABLE IF NOT EXISTS negative_cache ( id INTEGER PRIMARY KEY AUTOINCREMENT, source_host TEXT NOT NULL, source_path TEXT NOT NULL, source_query TEXT NOT NULL DEFAULT '', status_code INTEGER NOT NULL, error_message TEXT, fetched_at DATETIME DEFAULT CURRENT_TIMESTAMP, expires_at DATETIME NOT NULL, UNIQUE(source_host, source_path, source_query) ); CREATE INDEX IF NOT EXISTS idx_negative_cache_expires ON negative_cache(expires_at); -- Cache statistics for monitoring CREATE TABLE IF NOT EXISTS cache_stats ( id INTEGER PRIMARY KEY CHECK (id = 1), hit_count INTEGER NOT NULL DEFAULT 0, miss_count INTEGER NOT NULL DEFAULT 0, upstream_fetch_count INTEGER NOT NULL DEFAULT 0, upstream_fetch_bytes INTEGER NOT NULL DEFAULT 0, transform_count INTEGER NOT NULL DEFAULT 0, last_updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); INSERT OR IGNORE INTO cache_stats (id) VALUES (1);