-- 001_init.sql PRAGMA foreign_keys = ON; CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, password_salt TEXT NOT NULL, password_hash TEXT NOT NULL, rating INTEGER NOT NULL DEFAULT 0, created_at INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS sessions ( token TEXT PRIMARY KEY, user_id INTEGER NOT NULL, expires_at INTEGER NOT NULL, created_at INTEGER NOT NULL, FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS problems ( id INTEGER PRIMARY KEY AUTOINCREMENT, slug TEXT NOT NULL UNIQUE, title TEXT NOT NULL, statement_md TEXT NOT NULL, difficulty INTEGER NOT NULL DEFAULT 1, source TEXT NOT NULL DEFAULT "", created_at INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS problem_tags ( problem_id INTEGER NOT NULL, tag TEXT NOT NULL, PRIMARY KEY(problem_id, tag), FOREIGN KEY(problem_id) REFERENCES problems(id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS submissions ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL, problem_id INTEGER NOT NULL, language TEXT NOT NULL, code TEXT NOT NULL, status TEXT NOT NULL, score INTEGER NOT NULL DEFAULT 0, time_ms INTEGER NOT NULL DEFAULT 0, memory_kb INTEGER NOT NULL DEFAULT 0, created_at INTEGER NOT NULL, FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, FOREIGN KEY(problem_id) REFERENCES problems(id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS wrong_book ( user_id INTEGER NOT NULL, problem_id INTEGER NOT NULL, last_submission_id INTEGER, note TEXT NOT NULL DEFAULT "", updated_at INTEGER NOT NULL, PRIMARY KEY(user_id, problem_id), FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, FOREIGN KEY(problem_id) REFERENCES problems(id) ON DELETE CASCADE, FOREIGN KEY(last_submission_id) REFERENCES submissions(id) ON DELETE SET NULL ); CREATE INDEX IF NOT EXISTS idx_submissions_user_created_at ON submissions(user_id, created_at DESC); CREATE INDEX IF NOT EXISTS idx_submissions_problem_created_at ON submissions(problem_id, created_at DESC);