dbcube
Version:
160 lines (151 loc) • 5.12 kB
text/typescript
import { Config } from '@dbcube/core';
import { Database } from '@dbcube/query-builder';
import FileUtils from './FileUtils';
import path from 'path';
import { createRequire } from 'module';
/**
* Dbcube ORM - Main class for database management
*
* A lightweight, flexible ORM that supports multiple database engines including
* MySQL, PostgreSQL, SQLite, and MongoDB with a fluent query builder interface.
*
* @example
* ```typescript
* import { Dbcube } from 'dbcube';
*
* const dbcube = new Dbcube();
* await dbcube.init();
*
* // Get a database connection
* const db = dbcube.database('myDatabase');
*
* // Use query builder
* const users = await db.table('users').select().where('active', true).get();
* ```
*
* @class
* @author Albert Araya
* @license MIT
*/
export class Dbcube {
private static instance: Dbcube;
private configPath!: string;
private config: any;
private databases!: Record<string, any>;
/**
* Creates a new Dbcube instance (Singleton pattern)
*
* @constructor
* @example
* ```typescript
* const dbcube = new Dbcube();
* ```
*/
constructor() {
if (Dbcube.instance) {
return Dbcube.instance;
}
this.configPath = path.join(process.cwd(), 'dbcube.config.js');
this.config = new Config();
this.databases = {};
Dbcube.instance = this;
}
/**
* Loads configuration from dbcube.config.js file
*
* @private
* @returns {Promise<void>}
* @throws {Error} If config file doesn't exist
*/
async loadConfig() {
const exists = await FileUtils.fileExists(this.configPath);
exists ?? console.log('❌ Dont exists config file, please create a dbcube.config.js file');
}
/**
* Initializes the Dbcube ORM with database configurations
*
* @param {Object} configCreate - Optional configuration for creating new database
* @param {string} [configCreate.databaseName] - Name of the database to create
* @param {string} [configCreate.motor] - Database engine (mysql, postgres, sqlite, mongodb)
* @param {any} [configCreate.configAnswers] - Additional configuration answers
* @returns {Promise<void>}
*
* @example
* ```typescript
* // Initialize with existing config
* await dbcube.init();
*
* // Initialize with new database creation
* await dbcube.init({
* databaseName: 'myapp',
* motor: 'mysql'
* });
* ```
*/
init(configCreate: { databaseName?: string; motor?: string; configAnswers?: any } = {}) {
let config: any;
try {
// Use createRequire for better Next.js compatibility
// Use __filename for CJS, process.cwd() for ESM
const requireUrl = typeof __filename !== 'undefined' ? __filename : process.cwd();
const require = createRequire(requireUrl);
// Clear require cache to ensure fresh load
delete require.cache[require.resolve(this.configPath)];
const configModule = require(this.configPath);
config = configModule.default || configModule;
} catch (error: any) {
console.log('❌ Config load error:', error);
if (error.code === 'MODULE_NOT_FOUND') {
console.log('❌ Config file not found, please create a dbcube.config.js file');
return;
}
throw error;
}
config(this.config);
const databases = Object.keys(this.config.getAllDatabases());
for (const database of databases) {
this.databases[database] = new Database(database);
}
if (configCreate.databaseName) {
this.databases[configCreate.databaseName] = new Database(configCreate.databaseName);
}
}
/**
* Gets a database connection instance for query building
*
* @param {string} databaseName - Name of the database configuration
* @returns {Database} Database instance with query builder capabilities
*
* @example
* ```typescript
* // Get database connection
* const db = dbcube.database('myapp');
*
* // Use query builder methods
* const users = await db.table('users')
* .select(['id', 'name', 'email'])
* .where('status', 'active')
* .orderBy('created_at', 'desc')
* .limit(10)
* .get();
*
* // Insert data
* await db.table('users').insert({
* name: 'John Doe',
* email: 'john@example.com'
* });
*
* // Update data
* await db.table('users')
* .where('id', 1)
* .update({ status: 'inactive' });
*
* // Delete data
* await db.table('users').where('id', 1).delete();
* ```
*/
database(databaseName: string) {
return this.databases[databaseName];
}
}
export default Dbcube;