package main import "core:time" import "lib:database/sqlite" Storage :: struct { db: ^sqlite.DB, } Error :: union { sqlite.Error, } storage_open :: proc(store: ^Storage, db_path: string) -> Error { db := sqlite.open("data.db") or_return store.db = db return nil } storage_close :: proc(store: ^Storage) -> Error { if err := sqlite.close(store.db); err != nil { ensure(err == .Busy, "database is busy on shutdown!!!") return err } return nil } storage_ensure_schema :: proc(store: ^Storage) -> Error { version := get_schema_version(store.db) or_return // TODO: Move this to .sql files if version < 1 { run_migration_v1(store.db) or_return } return nil } storage_add_to_daily_log :: proc( store: ^Storage, mood: int, sleep: f32, sleep_quality: int, date: time.Time, notes: string, ) -> Error { return nil } // TODO: Clean up version check, close rows before calling next check @(private) get_schema_version :: proc(db: ^sqlite.DB) -> (version: int, err: Error) { rows: ^sqlite.Rows found: bool rows = sqlite.query( db, "SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'schema_version'", ) or_return found = sqlite.rows_next(rows) or_return sqlite.rows_close(rows) or_return if !found { return 0, nil } rows = sqlite.query(db, "SELECT version FROM schema_version") or_return found = sqlite.rows_next(rows) or_return defer sqlite.rows_close(rows) if !found { return 0, nil } sqlite.rows_scan(rows, &version) return } // TODO: Rip all database handling into a storage layer @(private) run_migration_v1 :: proc(db: ^sqlite.DB) -> Error { sql := "-- Create your tables\n" + "CREATE TABLE IF NOT EXISTS schema_version (" + " version INTEGER NOT NULL," + " applied_at TEXT NOT NULL" + ");\n" + "\n" + "CREATE TABLE IF NOT EXISTS daily_log (" + " date TEXT PRIMARY KEY," + " mood INTEGER," + " sleep_quality INTEGER," + " slept_hours REAL," + " notes TEXT," + " created_at TEXT NOT NULL," + " updated_at TEXT NOT NULL" + ");\n" + "\n" + "CREATE TABLE IF NOT EXISTS daily_symptom (" + " id INTEGER PRIMARY KEY AUTOINCREMENT," + " date TEXT NOT NULL," + " symptom TEXT NOT NULL," + " severity INTEGER NOT NULL," + " notes TEXT," + " created_at TEXT NOT NULL" + ");\n" + "\n" + "CREATE TABLE IF NOT EXISTS event (" + " id INTEGER PRIMARY KEY AUTOINCREMENT," + " timestamp TEXT NOT NULL," + " kind TEXT NOT NULL," + " amount REAL," + " unit TEXT," + " notes TEXT," + " created_at TEXT NOT NULL" + ");\n" + "\n" + "-- Record the version\n" + "INSERT INTO schema_version (version, applied_at) VALUES (1, 'now');" return sqlite.exec(db, sql) }