58 lines
1.5 KiB
TypeScript
58 lines
1.5 KiB
TypeScript
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
|
|
import Database from 'better-sqlite3';
|
|
|
|
import type { AppConfig } from './config.js';
|
|
|
|
const schemaSql = `
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id TEXT PRIMARY KEY,
|
|
username TEXT NOT NULL UNIQUE,
|
|
password_hash TEXT NOT NULL,
|
|
token_version INTEGER NOT NULL DEFAULT 1,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS save_snapshots (
|
|
user_id TEXT PRIMARY KEY,
|
|
version INTEGER NOT NULL,
|
|
saved_at TEXT NOT NULL,
|
|
bottom_tab TEXT NOT NULL,
|
|
game_state_json TEXT NOT NULL,
|
|
current_story_json TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS runtime_settings (
|
|
user_id TEXT PRIMARY KEY,
|
|
music_volume REAL NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS custom_world_profiles (
|
|
user_id TEXT NOT NULL,
|
|
profile_id TEXT NOT NULL,
|
|
payload_json TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
PRIMARY KEY (user_id, profile_id),
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
);
|
|
`;
|
|
|
|
export type AppDatabase = Database.Database;
|
|
|
|
export function createDatabase(config: AppConfig) {
|
|
const sqliteDir = path.dirname(config.sqlitePath);
|
|
fs.mkdirSync(sqliteDir, { recursive: true });
|
|
|
|
const db = new Database(config.sqlitePath);
|
|
db.pragma('journal_mode = WAL');
|
|
db.pragma('foreign_keys = ON');
|
|
db.exec(schemaSql);
|
|
return db;
|
|
}
|