fix: create data dir with 777 perms + handle in code
All checks were successful
Deploy / build-and-deploy (push) Successful in 1m48s
All checks were successful
Deploy / build-and-deploy (push) Successful in 1m48s
This commit is contained in:
110
lib/db/index.ts
110
lib/db/index.ts
@@ -2,63 +2,65 @@ import Database from "better-sqlite3";
|
||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
||||
import * as schema from "./schema";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
|
||||
const DB_PATH = path.join(process.cwd(), "data", "bingo.db");
|
||||
const DB_DIR = path.join(process.cwd(), "data");
|
||||
const DB_PATH = path.join(DB_DIR, "bingo.db");
|
||||
|
||||
function getDb() {
|
||||
const sqlite = new Database(DB_PATH);
|
||||
sqlite.pragma("journal_mode = WAL");
|
||||
sqlite.pragma("foreign_keys = ON");
|
||||
return sqlite;
|
||||
}
|
||||
try {
|
||||
fs.mkdirSync(DB_DIR, { recursive: true, mode: 0o777 });
|
||||
} catch {}
|
||||
|
||||
function initDatabase(sqlite: Database.Database) {
|
||||
sqlite.exec(`
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id TEXT PRIMARY KEY,
|
||||
nickname TEXT UNIQUE NOT NULL,
|
||||
password_hash TEXT NOT NULL,
|
||||
is_admin INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS sessions (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
expires_at TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS campaigns (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
grid_size INTEGER NOT NULL DEFAULT 5,
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
created_by TEXT NOT NULL REFERENCES users(id),
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS bingo_items (
|
||||
id TEXT PRIMARY KEY,
|
||||
campaign_id TEXT NOT NULL REFERENCES campaigns(id) ON DELETE CASCADE,
|
||||
text TEXT NOT NULL,
|
||||
emoji TEXT NOT NULL DEFAULT '💀',
|
||||
sound_category TEXT NOT NULL DEFAULT 'horn',
|
||||
sound_url TEXT,
|
||||
grid_index INTEGER NOT NULL,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS marks (
|
||||
id TEXT PRIMARY KEY,
|
||||
campaign_id TEXT NOT NULL REFERENCES campaigns(id) ON DELETE CASCADE,
|
||||
item_id TEXT NOT NULL REFERENCES bingo_items(id) ON DELETE CASCADE,
|
||||
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_campaign_item_pos ON bingo_items(campaign_id, grid_index);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_unique_mark ON marks(campaign_id, item_id);
|
||||
`);
|
||||
const sqlite = (() => {
|
||||
const s = new Database(DB_PATH);
|
||||
s.pragma("journal_mode = WAL");
|
||||
s.pragma("foreign_keys = ON");
|
||||
return s;
|
||||
})();
|
||||
|
||||
try { sqlite.exec("ALTER TABLE bingo_items ADD COLUMN sound_url TEXT"); } catch {}
|
||||
}
|
||||
sqlite.exec(`
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id TEXT PRIMARY KEY,
|
||||
nickname TEXT UNIQUE NOT NULL,
|
||||
password_hash TEXT NOT NULL,
|
||||
is_admin INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS sessions (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
expires_at TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS campaigns (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
grid_size INTEGER NOT NULL DEFAULT 5,
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
created_by TEXT NOT NULL REFERENCES users(id),
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS bingo_items (
|
||||
id TEXT PRIMARY KEY,
|
||||
campaign_id TEXT NOT NULL REFERENCES campaigns(id) ON DELETE CASCADE,
|
||||
text TEXT NOT NULL,
|
||||
emoji TEXT NOT NULL DEFAULT '💀',
|
||||
sound_category TEXT NOT NULL DEFAULT 'horn',
|
||||
sound_url TEXT,
|
||||
grid_index INTEGER NOT NULL,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS marks (
|
||||
id TEXT PRIMARY KEY,
|
||||
campaign_id TEXT NOT NULL REFERENCES campaigns(id) ON DELETE CASCADE,
|
||||
item_id TEXT NOT NULL REFERENCES bingo_items(id) ON DELETE CASCADE,
|
||||
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_campaign_item_pos ON bingo_items(campaign_id, grid_index);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_unique_mark ON marks(campaign_id, item_id);
|
||||
`);
|
||||
|
||||
try { sqlite.exec("ALTER TABLE bingo_items ADD COLUMN sound_url TEXT"); } catch {}
|
||||
|
||||
const sqlite = getDb();
|
||||
initDatabase(sqlite);
|
||||
export const db = drizzle(sqlite, { schema });
|
||||
|
||||
Reference in New Issue
Block a user