fix: NOT NULL on tutor_courses FKs, status CHECK, time format CHECK, add indexes
This commit is contained in:
@@ -12,8 +12,8 @@ CREATE TABLE tutors (
|
||||
);
|
||||
|
||||
CREATE TABLE tutor_courses (
|
||||
tutor_id INTEGER REFERENCES tutors(id),
|
||||
course_id INTEGER REFERENCES courses(id),
|
||||
tutor_id INTEGER NOT NULL REFERENCES tutors(id),
|
||||
course_id INTEGER NOT NULL REFERENCES courses(id),
|
||||
PRIMARY KEY (tutor_id, course_id)
|
||||
);
|
||||
|
||||
@@ -42,9 +42,9 @@ CREATE TABLE slots (
|
||||
session_id INTEGER NOT NULL REFERENCES sessions(id),
|
||||
room_id INTEGER REFERENCES rooms(id),
|
||||
tutor_id INTEGER NOT NULL REFERENCES tutors(id),
|
||||
start_time TEXT NOT NULL,
|
||||
end_time TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'closed',
|
||||
start_time TEXT NOT NULL CHECK (start_time GLOB '??:??'),
|
||||
end_time TEXT NOT NULL CHECK (end_time GLOB '??:??'),
|
||||
status TEXT NOT NULL DEFAULT 'closed' CHECK (status IN ('closed','open','locked')),
|
||||
code TEXT UNIQUE
|
||||
);
|
||||
|
||||
@@ -67,3 +67,13 @@ CREATE TABLE notes (
|
||||
updated_at TEXT NOT NULL CHECK (updated_at GLOB '????-??-??T??:??:??*'),
|
||||
UNIQUE(slot_id, student_id, tutor_id)
|
||||
);
|
||||
|
||||
-- Indexes on high-frequency FK columns (SQLite does not auto-index FKs)
|
||||
CREATE INDEX idx_students_course ON students(course_id);
|
||||
CREATE INDEX idx_sessions_course ON sessions(course_id);
|
||||
CREATE INDEX idx_slots_session ON slots(session_id);
|
||||
CREATE INDEX idx_slots_tutor ON slots(tutor_id);
|
||||
CREATE INDEX idx_attendances_slot ON attendances(slot_id);
|
||||
CREATE INDEX idx_attendances_student ON attendances(student_id);
|
||||
CREATE INDEX idx_notes_slot ON notes(slot_id);
|
||||
CREATE INDEX idx_notes_student ON notes(student_id);
|
||||
|
||||
@@ -2,7 +2,7 @@ use sqlx::{sqlite::SqlitePoolOptions, SqlitePool};
|
||||
|
||||
pub async fn init() -> Result<SqlitePool, sqlx::Error> {
|
||||
let url = std::env::var("DATABASE_URL")
|
||||
.unwrap_or_else(|_| "sqlite:attendance.db".into());
|
||||
.unwrap_or_else(|_| "sqlite:/data/attendance.db".into());
|
||||
let pool = SqlitePoolOptions::new()
|
||||
.after_connect(|conn, _| Box::pin(async move {
|
||||
sqlx::query("PRAGMA foreign_keys = ON")
|
||||
@@ -20,7 +20,7 @@ mod tests {
|
||||
|
||||
// NOTE: #[sqlx::test] injects its own pool, bypassing after_connect.
|
||||
// We test FK enforcement behaviorally: insert a row with a bad FK and assert it fails.
|
||||
// after_connect is manually invoked in the test setup below.
|
||||
// The PRAGMA is manually issued at the top of this test body.
|
||||
#[sqlx::test(migrations = "./migrations")]
|
||||
async fn foreign_keys_enforced(pool: SqlitePool) {
|
||||
// Enable FK for this test connection (mirrors what after_connect does in production)
|
||||
|
||||
Reference in New Issue
Block a user