zumito-db
Version:
Multi-driver database abstraction layer with decorator-based models
72 lines (71 loc) • 2.63 kB
JavaScript
import { SqlCompiler } from '../compiler/SqlCompiler.js';
export class SqliteDriver {
db;
compiler = new SqlCompiler();
raw;
async connect(config) {
// @ts-ignore - optional peer dependency
const BetterSqlite3 = await import('better-sqlite3');
this.db = new BetterSqlite3.default(config.filename || ':memory:');
this.db.pragma('journal_mode = WAL');
this.raw = this.db;
}
async disconnect() {
if (this.db) {
this.db.close();
}
}
async find(collection, query) {
const { sql, params } = this.compiler.compileSelect(query);
return this.db.prepare(sql).all(...params);
}
async findOne(collection, query) {
const limited = { ...query, limit: 1 };
const results = await this.find(collection, limited);
return results.length > 0 ? results[0] : null;
}
async insert(collection, data) {
const { sql, params } = this.compiler.compileInsert(collection, data);
const result = this.db.prepare(sql).run(...params);
return { id: result.lastInsertRowid, ...data };
}
async update(collection, query, data) {
const { sql, params } = this.compiler.compileUpdate(collection, data, query);
const result = this.db.prepare(sql).run(...params);
return result.changes;
}
async delete(collection, query) {
const { sql, params } = this.compiler.compileDelete(collection, query);
const result = this.db.prepare(sql).run(...params);
return result.changes;
}
async count(collection, query) {
const { sql, params } = this.compiler.compileCount(collection, query);
const result = this.db.prepare(sql).get(...params);
return result?.count || 0;
}
async ensureSchema(metadata) {
const fields = metadata.fields.map(f => ({
name: f.name,
type: f.type,
primary: f.primary,
nullable: f.nullable,
unique: f.unique,
}));
const sql = this.compiler.compileCreateTable(metadata.collection, fields);
this.db.exec(sql);
}
async dropCollection(name) {
this.db.exec(`DROP TABLE IF EXISTS ${name}`);
}
async listCollections() {
const rows = this.db.prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE '_zumito_%' AND name NOT LIKE 'sqlite_%'`).all();
return rows.map((r) => r.name);
}
async transaction(fn) {
const trx = this.db.transaction(async () => {
return fn(trx);
});
return trx();
}
}