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)
}