Spaces:
Build error
Build error
| """SQLite database connection and table initialization for OpportunityRadar.""" | |
| import sqlite3 | |
| import os | |
| from pathlib import Path | |
| from loguru import logger | |
| DB_PATH = Path(os.getenv("DATABASE_PATH", str(Path(__file__).resolve().parent.parent / "opportunityradar.db"))) | |
| def get_connection(): | |
| """Create and return a SQLite connection with row factory enabled. | |
| Returns: | |
| sqlite3.Connection: A connection to the local SQLite database. | |
| """ | |
| conn = sqlite3.connect(str(DB_PATH)) | |
| conn.row_factory = sqlite3.Row | |
| return conn | |
| def init_db(): | |
| """Create the sources, snapshots, and student_profiles tables if they do not already exist. | |
| This is safe to call multiple times — it uses IF NOT EXISTS and checks column existence. | |
| """ | |
| # Ensure parent directory exists (critical if a custom DATABASE_PATH is used in a volume) | |
| DB_PATH.parent.mkdir(parents=True, exist_ok=True) | |
| logger.info("Initializing database at {}", DB_PATH) | |
| conn = get_connection() | |
| cursor = conn.cursor() | |
| # --- 1. Create Tables (Base Schema) --- | |
| # Sources table | |
| cursor.execute(""" | |
| CREATE TABLE IF NOT EXISTS sources ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| name TEXT NOT NULL, | |
| url TEXT NOT NULL UNIQUE, | |
| css_selector TEXT NOT NULL, | |
| is_js_rendered BOOLEAN DEFAULT 0, | |
| active BOOLEAN DEFAULT 1, | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | |
| ); | |
| """) | |
| # Snapshots table | |
| cursor.execute(""" | |
| CREATE TABLE IF NOT EXISTS snapshots ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| source_id INTEGER NOT NULL, | |
| content_hash TEXT NOT NULL, | |
| raw_content TEXT, | |
| checked_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| changed BOOLEAN DEFAULT 0, | |
| FOREIGN KEY (source_id) REFERENCES sources(id) | |
| ); | |
| """) | |
| # Student Profiles table | |
| cursor.execute(""" | |
| CREATE TABLE IF NOT EXISTS student_profiles ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| email TEXT UNIQUE NOT NULL, | |
| name TEXT, | |
| branch TEXT NOT NULL, | |
| year INTEGER NOT NULL, | |
| college TEXT, | |
| update_count INTEGER DEFAULT 0, | |
| verified BOOLEAN DEFAULT 0, | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | |
| ); | |
| """) | |
| # --- 2. Migrations (Updates to Existing Tables) --- | |
| # Sources: Add category and tags | |
| cursor = conn.execute("PRAGMA table_info(sources)") | |
| columns = [row[1] for row in cursor.fetchall()] | |
| if "category" not in columns: | |
| conn.execute("ALTER TABLE sources ADD COLUMN category TEXT DEFAULT 'general'") | |
| logger.info("Added category column to sources table") | |
| if "tags" not in columns: | |
| conn.execute("ALTER TABLE sources ADD COLUMN tags TEXT DEFAULT '[\"all\"]'") | |
| logger.info("Added tags column to sources table") | |
| # Student Profiles: Add update_count (for users who already had the table from V2) | |
| cursor = conn.execute("PRAGMA table_info(student_profiles)") | |
| columns = [row[1] for row in cursor.fetchall()] | |
| if "update_count" not in columns: | |
| conn.execute("ALTER TABLE student_profiles ADD COLUMN update_count INTEGER DEFAULT 0") | |
| logger.info("Added update_count column to student_profiles table") | |
| conn.commit() | |
| conn.close() | |
| logger.info("Database initialized at {}", DB_PATH) | |