-- SQLite schema for Fetch ML job persistence -- Complements Redis for task queuing CREATE TABLE IF NOT EXISTS jobs ( id TEXT PRIMARY KEY, job_name TEXT NOT NULL, args TEXT, status TEXT NOT NULL DEFAULT 'pending', priority INTEGER DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, started_at DATETIME, ended_at DATETIME, worker_id TEXT, error TEXT, datasets TEXT, -- JSON array metadata TEXT, -- JSON object updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS job_metrics ( job_id TEXT, metric_name TEXT, metric_value TEXT, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (job_id, metric_name, timestamp), FOREIGN KEY (job_id) REFERENCES jobs(id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS workers ( id TEXT PRIMARY KEY, hostname TEXT, last_heartbeat DATETIME DEFAULT CURRENT_TIMESTAMP, status TEXT DEFAULT 'active', current_jobs INTEGER DEFAULT 0, max_jobs INTEGER DEFAULT 1, metadata TEXT -- JSON object ); CREATE TABLE IF NOT EXISTS system_metrics ( metric_name TEXT, metric_value TEXT, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (metric_name, timestamp) ); -- Indexes for performance CREATE INDEX IF NOT EXISTS idx_jobs_status ON jobs(status); CREATE INDEX IF NOT EXISTS idx_jobs_created_at ON jobs(created_at); CREATE INDEX IF NOT EXISTS idx_jobs_worker_id ON jobs(worker_id); CREATE INDEX IF NOT EXISTS idx_job_metrics_job_id ON job_metrics(job_id); CREATE INDEX IF NOT EXISTS idx_job_metrics_timestamp ON job_metrics(timestamp); CREATE INDEX IF NOT EXISTS idx_workers_heartbeat ON workers(last_heartbeat); CREATE INDEX IF NOT EXISTS idx_system_metrics_timestamp ON system_metrics(timestamp); -- Triggers to update timestamps CREATE TRIGGER IF NOT EXISTS update_jobs_timestamp AFTER UPDATE ON jobs FOR EACH ROW BEGIN UPDATE jobs SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id; END;