1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
import Database from 'better-sqlite3';
import { readFileSync } from 'fs';
import { join, dirname } from 'path';
import { mkdirSync, existsSync } from 'fs';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const DATA_DIR = join(process.cwd(), 'data');
const SCHEMA_PATH = join(__dirname, 'schema.sql');
const dbCache = new Map<string, Database.Database>();
function ensureDataDir(): void {
if (!existsSync(DATA_DIR)) {
mkdirSync(DATA_DIR, { recursive: true });
}
}
function loadSchema(): { globalSchema: string; projectSchema: string } {
const full = readFileSync(SCHEMA_PATH, 'utf-8');
const marker = '-- === PROJECT_SCHEMA ===';
const idx = full.indexOf(marker);
if (idx === -1) {
return { globalSchema: full, projectSchema: '' };
}
return {
globalSchema: full.substring(0, idx).trim(),
projectSchema: full.substring(idx + marker.length).trim(),
};
}
export function getAdminDb(): Database.Database {
if (dbCache.has('admin')) {
return dbCache.get('admin')!;
}
ensureDataDir();
const db = new Database(join(DATA_DIR, 'admin.db'));
db.pragma('journal_mode = WAL');
db.pragma('foreign_keys = ON');
const { globalSchema } = loadSchema();
db.exec(globalSchema);
dbCache.set('admin', db);
return db;
}
export function getProjectDb(projectName: string): Database.Database {
if (dbCache.has(projectName)) {
return dbCache.get(projectName)!;
}
ensureDataDir();
const db = new Database(join(DATA_DIR, `${projectName}.db`));
db.pragma('journal_mode = WAL');
db.pragma('foreign_keys = ON');
const { projectSchema } = loadSchema();
db.exec(projectSchema);
dbCache.set(projectName, db);
return db;
}
export function closeAll(): void {
for (const [name, db] of dbCache) {
db.close();
dbCache.delete(name);
}
}
export function getSetting(key: string): string | undefined {
const db = getAdminDb();
const row = db.prepare('SELECT value FROM settings WHERE key = ?').get(key) as
| { value: string }
| undefined;
return row?.value;
}
export function setSetting(key: string, value: string): void {
const db = getAdminDb();
db.prepare('INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)').run(key, value);
}
|