zumito-db
Version:
Multi-driver database abstraction layer with decorator-based models
104 lines (103 loc) • 3.58 kB
JavaScript
import { Repository } from './Repository.js';
import { buildModelMetadata, getModelMetadata } from './metadata/ModelMetadata.js';
import { MigrationRunner } from './migrations/MigrationRunner.js';
import { Migrator } from './migrations/Migrator.js';
import { MemoryDriver } from './drivers/MemoryDriver.js';
export class DatabaseManager {
driver;
repositories = new Map();
modelMetadata = new Map();
migrationRunner;
_migrator;
_config;
constructor() {
this.migrationRunner = new MigrationRunner(this);
this._migrator = new Migrator(this, this.migrationRunner);
}
get migrator() {
return this._migrator;
}
async connect(config) {
this._config = config;
this.driver = await this.loadDriver(config.default, config.drivers[config.default]);
await this.driver.connect(config.drivers[config.default]);
if (config.models) {
for (const Model of config.models) {
this.registerModel(Model);
}
}
}
async disconnect() {
if (this.driver) {
await this.driver.disconnect();
}
}
registerModel(modelClass) {
const metadata = getModelMetadata(modelClass) || buildModelMetadata(modelClass);
this.modelMetadata.set(metadata.collection, metadata);
}
getRepository(modelClass) {
const metadata = getModelMetadata(modelClass) || buildModelMetadata(modelClass);
if (!this.repositories.has(metadata.collection)) {
this.repositories.set(metadata.collection, new Repository(this.driver, metadata));
}
return this.repositories.get(metadata.collection);
}
async ensureSchemas() {
for (const [, metadata] of this.modelMetadata) {
await this.driver.ensureSchema(metadata);
}
}
getDriver() {
return this.driver;
}
async transaction(fn) {
if (!this.driver.transaction) {
throw new Error('Transactions are not supported by this driver');
}
return this.driver.transaction(async (_session) => {
return fn(this);
});
}
async dropCollection(name) {
await this.driver.dropCollection(name);
}
async listCollections() {
return this.driver.listCollections();
}
getCollectionMetadata() {
return Array.from(this.modelMetadata.values()).map(m => ({
name: m.collection,
fields: m.fields.map(f => ({
name: f.name,
propertyKey: f.propertyKey,
type: f.type,
primary: f.primary,
unique: f.unique,
nullable: f.nullable,
default: f.default,
})),
relations: m.relations,
}));
}
async loadDriver(name, _config) {
switch (name) {
case 'memory':
return new MemoryDriver();
case 'mongo': {
const mod = await import('./drivers/MongoDriver.js');
return new mod.MongoDriver();
}
case 'sqlite': {
const mod = await import('./drivers/SqliteDriver.js');
return new mod.SqliteDriver();
}
case 'tingo': {
const mod = await import('./drivers/TingoDriver.js');
return new mod.TingoDriver();
}
default:
throw new Error(`Unknown driver: ${name}. Available drivers: memory, mongo, sqlite, tingo`);
}
}
}