UNPKG

zumito-db

Version:

Multi-driver database abstraction layer with decorator-based models

96 lines (95 loc) 3.42 kB
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'; } }