CREATE TABLE IF NOT EXISTS source ( id INTEGER PRIMARY KEY, created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, name TEXT NOT NULL, slug TEXT NOT NULL UNIQUE, source_type TEXT NOT NULL CHECK (source_type IN ('feed', 'pangea')), notes TEXT NOT NULL DEFAULT '' ); CREATE TABLE IF NOT EXISTS source_feed ( source_id INTEGER PRIMARY KEY, feed_url TEXT NOT NULL, etag TEXT, last_modified TEXT, FOREIGN KEY (source_id) REFERENCES source(id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS source_pangea ( source_id INTEGER PRIMARY KEY, domain TEXT NOT NULL, category_name TEXT NOT NULL, content_type TEXT NOT NULL, only_newest INTEGER NOT NULL CHECK (only_newest IN (0, 1)), max_articles INTEGER NOT NULL, oldest_article INTEGER NOT NULL, include_authors INTEGER NOT NULL CHECK (include_authors IN (0, 1)), exclude_media INTEGER NOT NULL CHECK (exclude_media IN (0, 1)), include_content INTEGER NOT NULL CHECK (include_content IN (0, 1)), content_format TEXT NOT NULL, FOREIGN KEY (source_id) REFERENCES source(id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS job ( id INTEGER PRIMARY KEY, source_id INTEGER NOT NULL UNIQUE, created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, enabled INTEGER NOT NULL CHECK (enabled IN (0, 1)), spider_arguments TEXT NOT NULL DEFAULT '', cron_minute TEXT NOT NULL, cron_hour TEXT NOT NULL, cron_day_of_month TEXT NOT NULL, cron_day_of_week TEXT NOT NULL, cron_month TEXT NOT NULL, FOREIGN KEY (source_id) REFERENCES source(id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS job_execution ( id INTEGER PRIMARY KEY, job_id INTEGER NOT NULL, created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, started_at TEXT, ended_at TEXT, running_status INTEGER NOT NULL DEFAULT 0 CHECK (running_status BETWEEN 0 AND 4), requests_count INTEGER NOT NULL DEFAULT 0, items_count INTEGER NOT NULL DEFAULT 0, warnings_count INTEGER NOT NULL DEFAULT 0, errors_count INTEGER NOT NULL DEFAULT 0, bytes_count INTEGER NOT NULL DEFAULT 0, retries_count INTEGER NOT NULL DEFAULT 0, exceptions_count INTEGER NOT NULL DEFAULT 0, cache_size_count INTEGER NOT NULL DEFAULT 0, cache_object_count INTEGER NOT NULL DEFAULT 0, raw_stats TEXT NOT NULL DEFAULT '{}', FOREIGN KEY (job_id) REFERENCES job(id) ON DELETE CASCADE ); CREATE INDEX IF NOT EXISTS job_enabled_idx ON job (enabled); CREATE INDEX IF NOT EXISTS job_execution_job_created_at_idx ON job_execution (job_id, created_at DESC); CREATE INDEX IF NOT EXISTS job_execution_status_started_at_idx ON job_execution (running_status, started_at DESC); CREATE INDEX IF NOT EXISTS job_execution_status_ended_at_idx ON job_execution (running_status, ended_at DESC); CREATE TRIGGER IF NOT EXISTS source_set_updated_at AFTER UPDATE ON source FOR EACH ROW BEGIN UPDATE source SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id; END; CREATE TRIGGER IF NOT EXISTS job_set_updated_at AFTER UPDATE ON job FOR EACH ROW BEGIN UPDATE job SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id; END;