Files
bun-notes/src/server/db.ts
T
2026-04-16 16:05:22 +02:00

66 lines
2.0 KiB
TypeScript

import { Database } from "bun:sqlite";
import { mkdirSync } from "fs";
import path from "path";
let dbInstance: Database | null = null;
function migrate(database: Database) {
database.run(`
CREATE TABLE IF NOT EXISTS snippets (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
body TEXT NOT NULL DEFAULT '',
sort_order INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
`);
database.run(`
CREATE TABLE IF NOT EXISTS tags (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE COLLATE NOCASE
);
`);
database.run(`
CREATE TABLE IF NOT EXISTS snippet_tags (
snippet_id INTEGER NOT NULL REFERENCES snippets(id) ON DELETE CASCADE,
tag_id INTEGER NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
PRIMARY KEY (snippet_id, tag_id)
);
`);
database.run(`
CREATE TABLE IF NOT EXISTS tag_tree_nodes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE COLLATE NOCASE,
parent_id INTEGER REFERENCES tag_tree_nodes(id) ON DELETE CASCADE,
color TEXT,
label_prefix TEXT
);
`);
try {
database.run(`ALTER TABLE tag_tree_nodes ADD COLUMN label_prefix TEXT`);
} catch {
/* Spalte existiert bereits */
}
database.run(`CREATE INDEX IF NOT EXISTS idx_tag_tree_parent ON tag_tree_nodes(parent_id);`);
database.run(`CREATE INDEX IF NOT EXISTS idx_snippets_updated ON snippets(updated_at);`);
try {
database.run(`ALTER TABLE snippets ADD COLUMN deadline_at TEXT`);
} catch {
/* Spalte existiert bereits */
}
database.run(`CREATE INDEX IF NOT EXISTS idx_snippets_deadline ON snippets(deadline_at);`);
}
export function getDb(): Database {
if (dbInstance) return dbInstance;
const dir = path.join(process.cwd(), "data");
mkdirSync(dir, { recursive: true });
const file = path.join(dir, "notes.sqlite");
dbInstance = new Database(file);
dbInstance.run("PRAGMA journal_mode = WAL;");
dbInstance.run("PRAGMA foreign_keys = ON;");
migrate(dbInstance);
return dbInstance;
}