zumito-db
Version:
Multi-driver database abstraction layer with decorator-based models
96 lines (95 loc) • 3.42 kB
JavaScript
import { MongoCompiler } from '../compiler/MongoCompiler.js';
export class MongoDriver {
client;
db;
compiler = new MongoCompiler();
raw;
async connect(config) {
const { MongoClient } = await import('mongodb');
this.client = new MongoClient(config.uri);
await this.client.connect();
const dbName = config.database || this.extractDbName(config.uri);
this.db = this.client.db(dbName);
this.raw = this.db;
}
async disconnect() {
if (this.client) {
await this.client.close();
}
}
async find(collection, query) {
const { filter, options } = this.compiler.compileFind(query);
const col = this.db.collection(collection);
let cursor = col.find(filter, options);
const results = await cursor.toArray();
return results;
}
async findOne(collection, query) {
const { filter, options } = this.compiler.compileFind(query);
const col = this.db.collection(collection);
return col.findOne(filter, options);
}
async insert(collection, data) {
const col = this.db.collection(collection);
const result = await col.insertOne(data);
return { _id: result.insertedId, ...data };
}
async update(collection, query, data) {
const { filter } = this.compiler.compileFind(query);
const col = this.db.collection(collection);
const result = await col.updateMany(filter, this.compiler.compileUpdate(data));
return result.modifiedCount;
}
async delete(collection, query) {
const { filter } = this.compiler.compileFind(query);
const col = this.db.collection(collection);
const result = await col.deleteMany(filter);
return result.deletedCount;
}
async count(collection, query) {
const { filter } = this.compiler.compileFind(query);
const col = this.db.collection(collection);
return col.countDocuments(filter);
}
async ensureSchema(metadata) {
const collections = await this.db.listCollections().toArray();
const exists = collections.some((c) => c.name === metadata.collection);
if (!exists) {
await this.db.createCollection(metadata.collection);
}
// Create indexes for primary/unique fields
for (const field of metadata.fields) {
if (field.primary || field.unique) {
const col = this.db.collection(metadata.collection);
await col.createIndex({ [field.name]: 1 }, { unique: true });
}
}
}
async dropCollection(name) {
await this.db.collection(name).drop().catch(() => { });
}
async listCollections() {
const cols = await this.db.listCollections().toArray();
return cols.map((c) => c.name);
}
async transaction(fn) {
const session = this.client.startSession();
try {
session.startTransaction();
const result = await fn(session);
await session.commitTransaction();
return result;
}
catch (err) {
await session.abortTransaction();
throw err;
}
finally {
session.endSession();
}
}
extractDbName(uri) {
const match = uri.match(/\/([^/?]+)(\?|$)/);
return match ? match[1] : 'zumito';
}
}