67 lines
1.7 KiB
TypeScript
67 lines
1.7 KiB
TypeScript
import fs from 'fs';
|
|
import path from 'path';
|
|
import sqlite3 from 'sqlite3';
|
|
import { open, Database } from 'sqlite';
|
|
import { config } from './config';
|
|
|
|
let db: Database<sqlite3.Database, sqlite3.Statement> | null = null;
|
|
|
|
export async function getDb(): Promise<Database<sqlite3.Database, sqlite3.Statement>> {
|
|
if (db) return db;
|
|
|
|
const dbDir = path.dirname(config.dbPath);
|
|
if (!fs.existsSync(dbDir)) {
|
|
fs.mkdirSync(dbDir, { recursive: true });
|
|
}
|
|
|
|
db = await open({
|
|
filename: config.dbPath,
|
|
driver: sqlite3.Database,
|
|
});
|
|
|
|
await initSchema();
|
|
return db;
|
|
}
|
|
|
|
async function initSchema(): Promise<void> {
|
|
const database = await getDb();
|
|
|
|
await database.exec(`
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id TEXT PRIMARY KEY,
|
|
username TEXT UNIQUE NOT NULL,
|
|
password_hash TEXT NOT NULL,
|
|
role TEXT NOT NULL DEFAULT 'admin',
|
|
created_at TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS accounts (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
access_key_id TEXT NOT NULL,
|
|
access_key_secret TEXT NOT NULL,
|
|
region TEXT NOT NULL,
|
|
endpoint TEXT,
|
|
is_active INTEGER NOT NULL DEFAULT 0,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_accounts_active ON accounts(is_active);
|
|
|
|
CREATE TABLE IF NOT EXISTS operation_logs (
|
|
id TEXT PRIMARY KEY,
|
|
user_id TEXT,
|
|
username TEXT,
|
|
action TEXT NOT NULL,
|
|
target_type TEXT NOT NULL,
|
|
target_ids TEXT,
|
|
details TEXT,
|
|
created_at TEXT NOT NULL
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_logs_created ON operation_logs(created_at);
|
|
CREATE INDEX IF NOT EXISTS idx_logs_action ON operation_logs(action);
|
|
`);
|
|
}
|