@athenna/database
Version:
The Athenna database handler for SQL/NoSQL.
199 lines (198 loc) • 5.16 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 { Module, Options, Collection } from '@athenna/common';
import { NotFoundDataException } from '#src/exceptions/NotFoundDataException';
export class Driver {
/**
* Creates a new instance of the Driver.
*/
constructor(connection, client = null) {
/**
* Set the primary key of the driver.
*/
this.primaryKey = 'id';
/**
* Set if this instance is connected with database.
*/
this.isConnected = false;
/**
* Set if the connection will be saved on factory.
*/
this.isSavedOnFactory = false;
/**
* The connection name used for this instance.
*/
this.connection = null;
/**
* Set the table that this instance will work with.
*/
this.tableName = null;
/**
* Set the client of this driver.
*/
this.client = null;
/**
* The main query builder of driver.
*/
this.qb = null;
/**
* Use set query builder instead of creating a new one
* using client.
*/
this.useSetQB = false;
this.connection = connection;
if (client) {
this.client = client;
this.isConnected = true;
this.isSavedOnFactory = true;
}
}
/**
* Import knex in a method to be easier to mock.
*/
getKnex() {
const require = Module.createRequire(import.meta.url);
return require('knex');
}
/**
* Import mongoose in a method to be easier to mock.
*/
getMongoose() {
const require = Module.createRequire(import.meta.url);
let mongoose = require('mongoose');
if (!mongoose.createConnection) {
mongoose = mongoose.default;
}
return mongoose;
}
/**
* Clone the driver instance.
*/
clone() {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return new this.constructor(this.connection, this.client);
}
/**
* Return the client of driver.
*/
getClient() {
return this.client;
}
/**
* Set a client in driver.
*/
setClient(client) {
this.client = client;
return this;
}
/**
* Return the query builder of driver.
*/
getQueryBuilder() {
return this.qb;
}
/**
* Set a query builder in driver.
*/
setQueryBuilder(queryBuilder, options = {}) {
options = Options.create(options, {
useSetQB: false
});
this.qb = queryBuilder;
this.useSetQB = options.useSetQB;
return this;
}
/**
* Set the primary key of the driver.
*/
setPrimaryKey(primaryKey) {
this.primaryKey = primaryKey;
return this;
}
/**
* Create a join clause by join type
*/
joinByType(joinType, table, column1, operation, column2) {
if (!column1) {
this.qb[joinType](table);
return this;
}
if (!operation) {
this.qb[joinType](table, column1);
return this;
}
if (!column2) {
this.qb[joinType](table, column1, operation);
return this;
}
this.qb[joinType](table, column1, operation, column2);
return this;
}
/**
* Find a value in database and return as boolean.
*/
async exists() {
const data = await this.find();
return !!data;
}
/**
* Find a value in database or throw exception if undefined.
*/
async findOrFail() {
const data = await this.find();
if (!data) {
throw new NotFoundDataException(this.connection);
}
return data;
}
/**
* Return a single model instance or, if no results are found,
* execute the given closure.
*/
async findOr(closure) {
const data = await this.find();
if (!data) {
return closure();
}
return data;
}
/**
* Find value in database but returns only the value of
* selected column directly.
*/
async pluck(column) {
const data = await this.find();
return data[column];
}
/**
* Find many values in database but returns only the
* values of selected column directly.
*/
async pluckMany(column) {
const data = await this.findMany();
return data.map(d => d[column]);
}
/**
* Find many values in database and return as a Collection.
*/
async collection() {
return new Collection(await this.findMany());
}
/**
* Executes the given closure when the first argument is true.
*/
when(criteria, closure) {
if (!criteria) {
return this;
}
closure(this, criteria);
return this;
}
}