@athenna/database
Version:
The Athenna database handler for SQL/NoSQL.
128 lines (127 loc) • 4.09 kB
JavaScript
/**
* @athenna/database
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { debug } from '#src/debug';
import { FakeDriver } from '#src/database/drivers/FakeDriver';
import { MongoDriver } from '#src/database/drivers/MongoDriver';
import { MySqlDriver } from '#src/database/drivers/MySqlDriver';
import { SqliteDriver } from '#src/database/drivers/SqliteDriver';
import { PostgresDriver } from '#src/database/drivers/PostgresDriver';
import { NotFoundDriverException } from '#src/exceptions/NotFoundDriverException';
import { NotImplementedConfigException } from '#src/exceptions/NotImplementedConfigException';
export class ConnectionFactory {
/**
* Holds all the open connections.
*/
static { this.connections = new Map(); }
/**
* Holds all the Athenna drivers implementations available.
*/
static { this.drivers = new Map()
.set('fake', { driver: FakeDriver })
.set('mongo', { driver: MongoDriver })
.set('mysql', { driver: MySqlDriver })
.set('sqlite', { driver: SqliteDriver })
.set('postgres', { driver: PostgresDriver }); }
/**
* Fabricate a new connection for a specific driver.
*/
static fabricate(con) {
con = this.parseConName(con);
const driverName = this.getConnectionDriver(con);
const Driver = this.drivers.get(driverName).driver;
const connection = this.connections.get(con);
if (!connection) {
this.connections.set(con, { client: null });
return new Driver(con);
}
if (connection.client) {
debug('client found for connection %s using driver %s, using it as default', con, driverName);
return new Driver(con, connection.client);
}
return new Driver(con);
}
/**
* Verify if client is present on a driver connection.
*/
static hasClient(con) {
return !!this.connections.get(con)?.client;
}
/**
* Get client of a connection.
*/
static getClient(con) {
return this.connections.get(con)?.client;
}
/**
* Set connection client on driver.
*/
static setClient(con, client) {
const connection = this.connections.get(con) || {};
connection.client = client;
this.connections.set(con, connection);
}
/**
* Return all available drivers.
*/
static availableDrivers() {
const availableDrivers = [];
for (const key of this.drivers.keys()) {
availableDrivers.push(key);
}
return availableDrivers;
}
/**
* Return all available connections.
*/
static availableConnections() {
const availableConnections = [];
for (const key of this.connections.keys()) {
availableConnections.push(key);
}
return availableConnections;
}
/**
* Define your own database driver implementation to use
* within Database facade.
*
* @example
* ```ts
* import { Driver, ConnectionFactory } from '@athenna/database'
*
* class TestDriver extends Driver {}
*
* ConnectionFactory.createDriver('test', TestDriver)
* ```
*/
static createDriver(name, impl) {
this.drivers.set(name, { driver: impl });
}
/**
* Parse connection config name if is default
*/
static parseConName(con) {
if (con === 'default') {
return Config.get('database.default');
}
return con;
}
/**
* Get the connection configuration of config/database file.
*/
static getConnectionDriver(con) {
const config = Config.get(`database.connections.${con}`);
if (!config) {
throw new NotImplementedConfigException(con);
}
if (!this.drivers.has(config.driver)) {
throw new NotFoundDriverException(config.driver);
}
return config.driver;
}
}