-- Ginxsom Blossom Server Database Schema -- SQLite database for blob metadata and server configuration -- Enable foreign key constraints PRAGMA foreign_keys = ON; -- Main blobs table for storing blob metadata CREATE TABLE IF NOT EXISTS blobs ( sha256 TEXT PRIMARY KEY NOT NULL, -- SHA-256 hash (64 hex chars) size INTEGER NOT NULL, -- File size in bytes type TEXT NOT NULL, -- MIME type uploaded_at INTEGER NOT NULL, -- Unix timestamp uploader_pubkey TEXT, -- Nostr public key (optional) filename TEXT, -- Original filename (optional) CHECK (length(sha256) = 64), -- Ensure valid SHA-256 hash length CHECK (size >= 0), -- Ensure non-negative size CHECK (uploaded_at > 0) -- Ensure valid timestamp ); -- Server configuration table for key-value settings CREATE TABLE IF NOT EXISTS server_config ( key TEXT PRIMARY KEY NOT NULL, -- Configuration key value TEXT NOT NULL, -- Configuration value description TEXT, -- Human-readable description updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')) -- Last update timestamp ); -- Indexes for performance optimization CREATE INDEX IF NOT EXISTS idx_blobs_uploaded_at ON blobs(uploaded_at); CREATE INDEX IF NOT EXISTS idx_blobs_uploader_pubkey ON blobs(uploader_pubkey); CREATE INDEX IF NOT EXISTS idx_blobs_type ON blobs(type); CREATE INDEX IF NOT EXISTS idx_blobs_size ON blobs(size); -- Insert default server configuration INSERT OR IGNORE INTO server_config (key, value, description) VALUES ('max_file_size', '104857600', 'Maximum file size in bytes (100MB)'), ('require_auth', 'false', 'Whether authentication is required for uploads'), ('allowed_types', '*', 'Allowed MIME types (* for all)'), ('server_name', 'ginxsom', 'Server name for responses'), ('storage_quota', '10737418240', 'Total storage quota in bytes (10GB)'), ('cleanup_interval', '86400', 'Cleanup interval in seconds (daily)'), ('max_upload_rate', '1048576', 'Max upload rate per client in bytes/sec (1MB/s)'); -- View for storage statistics CREATE VIEW IF NOT EXISTS storage_stats AS SELECT COUNT(*) as total_blobs, SUM(size) as total_bytes, AVG(size) as avg_blob_size, MIN(uploaded_at) as first_upload, MAX(uploaded_at) as last_upload, COUNT(DISTINCT uploader_pubkey) as unique_uploaders FROM blobs; -- View for recent uploads (last 24 hours) CREATE VIEW IF NOT EXISTS recent_uploads AS SELECT sha256, size, type, uploaded_at, uploader_pubkey, filename, datetime(uploaded_at, 'unixepoch') as uploaded_datetime FROM blobs WHERE uploaded_at > (strftime('%s', 'now') - 86400) ORDER BY uploaded_at DESC;