Add files via upload
This commit is contained in:
parent
4c6513a693
commit
6507bc72fe
1 changed files with 51 additions and 24 deletions
73
src/db/db.ts
73
src/db/db.ts
|
|
@ -4,53 +4,80 @@ import { Database } from "bun:sqlite";
|
||||||
mkdirSync("./data", { recursive: true });
|
mkdirSync("./data", { recursive: true });
|
||||||
const db = new Database("./data/mydb.sqlite", { create: true });
|
const db = new Database("./data/mydb.sqlite", { create: true });
|
||||||
|
|
||||||
if (!db.query("SELECT * FROM sqlite_master WHERE type='table'").get()) {
|
// Always keep foreign keys on (SQLite defaults to off).
|
||||||
|
db.exec("PRAGMA foreign_keys = ON;");
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Initial schema bootstrap (fresh install)
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
const hasAnyTable = db.query("SELECT 1 FROM sqlite_master WHERE type='table' LIMIT 1").get();
|
||||||
|
if (!hasAnyTable) {
|
||||||
db.exec(`
|
db.exec(`
|
||||||
CREATE TABLE IF NOT EXISTS users (
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
email TEXT NOT NULL,
|
email TEXT NOT NULL UNIQUE,
|
||||||
password TEXT NOT NULL
|
password TEXT NOT NULL,
|
||||||
|
role TEXT NOT NULL DEFAULT 'user'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS jobs (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
user_id INTEGER NOT NULL,
|
||||||
|
date_created TEXT NOT NULL,
|
||||||
|
status TEXT NOT NULL DEFAULT 'queued',
|
||||||
|
num_files INTEGER NOT NULL DEFAULT 0,
|
||||||
|
finished_files INTEGER NOT NULL DEFAULT 0,
|
||||||
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS file_names (
|
CREATE TABLE IF NOT EXISTS file_names (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
job_id INTEGER NOT NULL,
|
job_id INTEGER NOT NULL,
|
||||||
file_name TEXT NOT NULL,
|
file_name TEXT NOT NULL,
|
||||||
output_file_name TEXT NOT NULL,
|
output_file_name TEXT NOT NULL,
|
||||||
status TEXT DEFAULT 'not started',
|
status TEXT NOT NULL DEFAULT 'queued',
|
||||||
FOREIGN KEY (job_id) REFERENCES jobs(id)
|
FOREIGN KEY (job_id) REFERENCES jobs(id) ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
CREATE TABLE IF NOT EXISTS jobs (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
PRAGMA user_version = 1;
|
||||||
user_id INTEGER NOT NULL,
|
`);
|
||||||
date_created TEXT NOT NULL,
|
|
||||||
status TEXT DEFAULT 'not started',
|
|
||||||
num_files INTEGER DEFAULT 0,
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
||||||
);
|
|
||||||
PRAGMA user_version = 1;`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const dbVersion = (db.query("PRAGMA user_version").get() as { user_version?: number }).user_version;
|
// -----------------------------------------------------------------------------
|
||||||
|
// Version marker (kept for backwards-compatibility; schema is enforced below).
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
const dbVersion = (db.query("PRAGMA user_version").get() as { user_version?: number })
|
||||||
|
.user_version;
|
||||||
|
|
||||||
// v0 -> v1 migration: ensure file_names.status exists (older DBs didn't have it)
|
|
||||||
if ((dbVersion ?? 0) === 0) {
|
if ((dbVersion ?? 0) === 0) {
|
||||||
const fileCols = db.query("PRAGMA table_info(file_names)").all() as { name: string }[];
|
|
||||||
if (!fileCols.some((col) => col.name === "status")) {
|
|
||||||
// keep default aligned with current code paths that assume a non-null status
|
|
||||||
db.exec("ALTER TABLE file_names ADD COLUMN status TEXT NOT NULL DEFAULT 'queued';");
|
|
||||||
}
|
|
||||||
db.exec("PRAGMA user_version = 1;");
|
db.exec("PRAGMA user_version = 1;");
|
||||||
console.log("Updated database to version 1.");
|
console.log("Updated database to version 1.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// One-time migration: Policy A
|
||||||
|
// If the `role` column is newly added AND there are existing users,
|
||||||
|
// make the oldest user (lowest id) an admin.
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
const userColumns = db.query("PRAGMA table_info(users)").all() as { name: string }[];
|
const userColumns = db.query("PRAGMA table_info(users)").all() as { name: string }[];
|
||||||
const hasRoleColumn = userColumns.some((col) => col.name === "role");
|
const hasRoleColumn = userColumns.some((col) => col.name === "role");
|
||||||
|
|
||||||
if (!hasRoleColumn) {
|
if (!hasRoleColumn) {
|
||||||
db.exec("ALTER TABLE users ADD COLUMN role TEXT NOT NULL DEFAULT 'user';");
|
db.exec("ALTER TABLE users ADD COLUMN role TEXT NOT NULL DEFAULT 'user';");
|
||||||
console.log("Added 'role' column to users table.");
|
|
||||||
|
const oldest = db
|
||||||
|
.query("SELECT id FROM users ORDER BY id ASC LIMIT 1")
|
||||||
|
.get() as { id: number } | null;
|
||||||
|
|
||||||
|
if (oldest) {
|
||||||
|
db.query("UPDATE users SET role = 'admin' WHERE id = ?").run(oldest.id);
|
||||||
|
console.log("Added 'role' column; promoted oldest existing user to admin (Policy A).");
|
||||||
|
} else {
|
||||||
|
console.log("Added 'role' column to users table (no users to promote).");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable WAL mode
|
// enable WAL mode (better concurrency for Bun + SQLite)
|
||||||
db.exec("PRAGMA journal_mode = WAL;");
|
db.exec("PRAGMA journal_mode = WAL;");
|
||||||
|
|
||||||
export default db;
|
export default db;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue