cc工作前备份
This commit is contained in:
91
src/db/database.ts
Normal file
91
src/db/database.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
// ZCLAW 数据库管理
|
||||
import Database from 'better-sqlite3';
|
||||
import { existsSync, mkdirSync } from 'fs';
|
||||
import { dirname } from 'path';
|
||||
import { SCHEMA_SQL } from './schema';
|
||||
import { createLogger } from '../utils/logger';
|
||||
|
||||
const log = createLogger('Database');
|
||||
|
||||
let _db: Database.Database | null = null;
|
||||
|
||||
export function initDatabase(dbPath: string): Database.Database {
|
||||
// 确保目录存在
|
||||
const dir = dirname(dbPath);
|
||||
if (!existsSync(dir)) {
|
||||
mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
|
||||
_db = new Database(dbPath);
|
||||
|
||||
// 启用 WAL 模式提升性能
|
||||
_db.pragma('journal_mode = WAL');
|
||||
_db.pragma('foreign_keys = ON');
|
||||
|
||||
// 创建表
|
||||
_db.exec(SCHEMA_SQL);
|
||||
|
||||
log.info(`Database initialized at ${dbPath}`);
|
||||
return _db;
|
||||
}
|
||||
|
||||
export function getDatabase(): Database.Database {
|
||||
if (!_db) {
|
||||
throw new Error('Database not initialized. Call initDatabase() first.');
|
||||
}
|
||||
return _db;
|
||||
}
|
||||
|
||||
export function closeDatabase(): void {
|
||||
if (_db) {
|
||||
_db.close();
|
||||
_db = null;
|
||||
log.info('Database closed');
|
||||
}
|
||||
}
|
||||
|
||||
// 通用 CRUD 辅助
|
||||
export class BaseDAO<T extends Record<string, any>> {
|
||||
constructor(
|
||||
protected tableName: string,
|
||||
protected db: Database.Database = getDatabase()
|
||||
) {}
|
||||
|
||||
findById(id: string): T | undefined {
|
||||
return this.db.prepare(`SELECT * FROM ${this.tableName} WHERE id = ?`).get(id) as T | undefined;
|
||||
}
|
||||
|
||||
findAll(where?: string, params?: any[]): T[] {
|
||||
const sql = where
|
||||
? `SELECT * FROM ${this.tableName} WHERE ${where}`
|
||||
: `SELECT * FROM ${this.tableName}`;
|
||||
return (params ? this.db.prepare(sql).all(...params) : this.db.prepare(sql).all()) as T[];
|
||||
}
|
||||
|
||||
insert(data: Partial<T>): void {
|
||||
const keys = Object.keys(data);
|
||||
const placeholders = keys.map(() => '?').join(', ');
|
||||
const sql = `INSERT OR REPLACE INTO ${this.tableName} (${keys.join(', ')}) VALUES (${placeholders})`;
|
||||
this.db.prepare(sql).run(...Object.values(data));
|
||||
}
|
||||
|
||||
update(id: string, data: Partial<T>): void {
|
||||
const sets = Object.keys(data).map(k => `${k} = ?`).join(', ');
|
||||
const sql = `UPDATE ${this.tableName} SET ${sets} WHERE id = ?`;
|
||||
this.db.prepare(sql).run(...Object.values(data), id);
|
||||
}
|
||||
|
||||
delete(id: string): void {
|
||||
this.db.prepare(`DELETE FROM ${this.tableName} WHERE id = ?`).run(id);
|
||||
}
|
||||
|
||||
count(where?: string, params?: any[]): number {
|
||||
const sql = where
|
||||
? `SELECT COUNT(*) as count FROM ${this.tableName} WHERE ${where}`
|
||||
: `SELECT COUNT(*) as count FROM ${this.tableName}`;
|
||||
const result = params
|
||||
? this.db.prepare(sql).get(...params) as { count: number }
|
||||
: this.db.prepare(sql).get() as { count: number };
|
||||
return result.count;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user