203 行
7.0 KiB
SQL
203 行
7.0 KiB
SQL
-- 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 '',
|
|
statement_url TEXT NOT NULL DEFAULT '',
|
|
llm_profile_json TEXT NOT NULL DEFAULT '{}',
|
|
sample_input TEXT NOT NULL DEFAULT '',
|
|
sample_output 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,
|
|
contest_id INTEGER,
|
|
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,
|
|
compile_log TEXT NOT NULL DEFAULT '',
|
|
runtime_log TEXT NOT NULL DEFAULT '',
|
|
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,
|
|
FOREIGN KEY(contest_id) REFERENCES contests(id) ON DELETE SET NULL
|
|
);
|
|
|
|
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 TABLE IF NOT EXISTS contests (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
title TEXT NOT NULL,
|
|
starts_at INTEGER NOT NULL,
|
|
ends_at INTEGER NOT NULL,
|
|
rule_json TEXT NOT NULL DEFAULT '{}'
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS contest_problems (
|
|
contest_id INTEGER NOT NULL,
|
|
problem_id INTEGER NOT NULL,
|
|
idx INTEGER NOT NULL,
|
|
PRIMARY KEY(contest_id, problem_id),
|
|
FOREIGN KEY(contest_id) REFERENCES contests(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(problem_id) REFERENCES problems(id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS contest_registrations (
|
|
contest_id INTEGER NOT NULL,
|
|
user_id INTEGER NOT NULL,
|
|
registered_at INTEGER NOT NULL,
|
|
PRIMARY KEY(contest_id, user_id),
|
|
FOREIGN KEY(contest_id) REFERENCES contests(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS kb_articles (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
slug TEXT NOT NULL UNIQUE,
|
|
title TEXT NOT NULL,
|
|
content_md TEXT NOT NULL,
|
|
created_at INTEGER NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS kb_article_links (
|
|
article_id INTEGER NOT NULL,
|
|
problem_id INTEGER NOT NULL,
|
|
PRIMARY KEY(article_id, problem_id),
|
|
FOREIGN KEY(article_id) REFERENCES kb_articles(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(problem_id) REFERENCES problems(id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS import_jobs (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
status TEXT NOT NULL,
|
|
trigger TEXT NOT NULL DEFAULT 'manual',
|
|
total_count INTEGER NOT NULL DEFAULT 0,
|
|
processed_count INTEGER NOT NULL DEFAULT 0,
|
|
success_count INTEGER NOT NULL DEFAULT 0,
|
|
failed_count INTEGER NOT NULL DEFAULT 0,
|
|
options_json TEXT NOT NULL DEFAULT '{}',
|
|
last_error TEXT NOT NULL DEFAULT '',
|
|
started_at INTEGER NOT NULL,
|
|
finished_at INTEGER,
|
|
updated_at INTEGER NOT NULL,
|
|
created_at INTEGER NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS import_job_items (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
job_id INTEGER NOT NULL,
|
|
source_path TEXT NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'queued',
|
|
title TEXT NOT NULL DEFAULT '',
|
|
difficulty INTEGER NOT NULL DEFAULT 0,
|
|
problem_id INTEGER,
|
|
error_text TEXT NOT NULL DEFAULT '',
|
|
started_at INTEGER,
|
|
finished_at INTEGER,
|
|
updated_at INTEGER NOT NULL,
|
|
created_at INTEGER NOT NULL,
|
|
FOREIGN KEY(job_id) REFERENCES import_jobs(id) ON DELETE CASCADE,
|
|
UNIQUE(job_id, source_path)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS problem_drafts (
|
|
user_id INTEGER NOT NULL,
|
|
problem_id INTEGER NOT NULL,
|
|
language TEXT NOT NULL DEFAULT 'cpp',
|
|
code TEXT NOT NULL DEFAULT '',
|
|
stdin TEXT NOT NULL DEFAULT '',
|
|
updated_at INTEGER NOT NULL,
|
|
created_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
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS problem_solution_jobs (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
problem_id INTEGER NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'queued',
|
|
progress INTEGER NOT NULL DEFAULT 0,
|
|
message TEXT NOT NULL DEFAULT '',
|
|
created_by INTEGER NOT NULL DEFAULT 0,
|
|
max_solutions INTEGER NOT NULL DEFAULT 3,
|
|
created_at INTEGER NOT NULL,
|
|
started_at INTEGER,
|
|
finished_at INTEGER,
|
|
updated_at INTEGER NOT NULL,
|
|
FOREIGN KEY(problem_id) REFERENCES problems(id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS problem_solutions (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
problem_id INTEGER NOT NULL,
|
|
variant INTEGER NOT NULL DEFAULT 1,
|
|
title TEXT NOT NULL DEFAULT '',
|
|
idea_md TEXT NOT NULL DEFAULT '',
|
|
explanation_md TEXT NOT NULL DEFAULT '',
|
|
code_cpp TEXT NOT NULL DEFAULT '',
|
|
complexity TEXT NOT NULL DEFAULT '',
|
|
tags_json TEXT NOT NULL DEFAULT '[]',
|
|
source TEXT NOT NULL DEFAULT 'llm',
|
|
created_at INTEGER NOT NULL,
|
|
updated_at INTEGER NOT NULL,
|
|
FOREIGN KEY(problem_id) REFERENCES problems(id) ON DELETE CASCADE
|
|
);
|
|
|
|
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);
|
|
CREATE INDEX IF NOT EXISTS idx_submissions_contest_user_created_at ON submissions(contest_id, user_id, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_problem_tags_tag ON problem_tags(tag);
|
|
CREATE INDEX IF NOT EXISTS idx_kb_article_links_problem_id ON kb_article_links(problem_id);
|
|
CREATE INDEX IF NOT EXISTS idx_import_jobs_created_at ON import_jobs(created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_import_jobs_status ON import_jobs(status, updated_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_import_job_items_job_status ON import_job_items(job_id, status, updated_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_problem_drafts_updated ON problem_drafts(updated_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_problem_solution_jobs_problem ON problem_solution_jobs(problem_id, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_problem_solutions_problem ON problem_solutions(problem_id, variant, id);
|