lupdo
Version:
Database Abstraction Layer for Node js
217 lines (216 loc) • 8.91 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PdoDriver = void 0;
const node_events_1 = require("node:events");
const uuid_1 = require("uuid");
const constants_1 = require("../constants");
const pdo_error_1 = require("../errors/pdo-error");
const pdo_pool_1 = require("./pdo-pool");
const pdo_prepared_statement_1 = require("./pdo-prepared-statement");
const pdo_statement_1 = require("./pdo-statement");
const pdo_transaction_1 = require("./pdo-transaction");
class PdoDriver extends node_events_1.EventEmitter {
constructor(driver, userPoolOptions, userAttributes) {
super();
this.instances = {
transaction: pdo_transaction_1.default,
preparedStatement: pdo_prepared_statement_1.default,
statement: pdo_statement_1.default,
};
this.defaultAttributes = {
[constants_1.ATTR_FETCH_DIRECTION]: constants_1.FETCH_FORWARD,
[constants_1.ATTR_CASE]: constants_1.CASE_NATURAL,
[constants_1.ATTR_NULLS]: constants_1.NULL_NATURAL,
[constants_1.ATTR_DEBUG]: constants_1.DEBUG_DISABLED,
};
this.driverAttributes = {};
this.processedAttributes = null;
this.processedPoolOptions = null;
this.poolEvents = {};
this.hasDebug = false;
this.initializedPool = null;
this.disconnected = false;
this.forceReconnect = false;
this.userAttributes = userAttributes;
const { created, destroyed, acquired, released, killed, ...otherOptions } = userPoolOptions;
this.userPoolOptions = otherOptions;
this.poolEvents = { created, destroyed, acquired, released, killed };
Object.assign(this.defaultAttributes, {
[constants_1.ATTR_DRIVER_NAME]: driver,
});
}
reconnect() {
if (this.disconnected) {
this.initializedPool = new pdo_pool_1.default(this.poolOptions);
this.assignPoolEvents();
this.disconnected = false;
}
}
async disconnect() {
await this.pool.destroy();
this.pool.removeAllListeners('acquireSuccess');
this.pool.removeAllListeners('release');
this.disconnected = true;
}
get poolOptions() {
if (this.processedPoolOptions === null) {
this.processedPoolOptions = {
min: 2,
max: 10,
acquireTimeoutMillis: 10000,
createTimeoutMillis: 5000,
...this.userPoolOptions,
propagateCreateError: false,
validate: (connection) => {
return this.validateRawConnection(connection);
},
create: async () => {
const connection = await this.createConnection();
const uuid = (0, uuid_1.v4)();
if (this.version === undefined) {
this.version = await this.getVersionFromConnection(connection);
}
if (typeof this.poolEvents.created === 'function') {
const pdoConnection = this.createPdoConnection(connection);
pdoConnection.version = this.version;
await this.poolEvents.created(uuid, pdoConnection);
}
connection.__lupdo_uuid = uuid;
connection.__lupdo_killed = false;
if (this.hasDebug) {
console.log(`Pdo Pool Resource Created: ${connection.__lupdo_uuid}`);
}
return connection;
},
kill: async (connection) => {
if (connection !== undefined) {
await this.destroyConnection(connection);
connection.__lupdo_killed = true;
if (typeof this.poolEvents.killed === 'function') {
this.poolEvents.killed(connection.__lupdo_uuid);
}
if (this.hasDebug) {
console.log(`Pdo Pool Resource Killed: ${connection.__lupdo_uuid}`);
}
}
},
destroy: async (connection) => {
if (connection !== undefined && !connection.__lupdo_killed) {
const uuid = connection.__lupdo_uuid;
await this.closeConnection(connection);
if (typeof this.poolEvents.destroyed === 'function') {
await this.poolEvents.destroyed(uuid);
}
if (this.hasDebug) {
console.log(`Pdo Pool Resource Destroyed: ${connection.__lupdo_uuid}`);
}
}
},
log: (message) => {
this.emit('log', 'warning', message);
},
};
}
return this.processedPoolOptions;
}
get attributes() {
if (this.processedAttributes === null) {
this.processedAttributes = Object.assign({}, { ...this.defaultAttributes }, { ...this.driverAttributes });
for (const key in this.userAttributes) {
if (key in this.processedAttributes && key !== constants_1.ATTR_DRIVER_NAME) {
this.processedAttributes[key] = this.userAttributes[key];
}
}
}
return this.processedAttributes;
}
get pool() {
if (this.initializedPool === null) {
this.hasDebug = this.getAttribute(constants_1.ATTR_DEBUG) === constants_1.DEBUG_ENABLED;
this.initializedPool = new pdo_pool_1.default(this.poolOptions);
this.assignPoolEvents();
}
return this.initializedPool;
}
async beginTransaction() {
this.throwIfDisconnected();
const connection = this.getRawConnection();
connection.setAttributes(this.attributes);
await connection.beginTransaction();
return new this.instances.transaction(connection);
}
async prepare(sql) {
this.throwIfDisconnected();
const connection = this.getRawConnection();
connection.setAttributes(this.attributes);
return new this.instances.preparedStatement(connection, sql, await connection.prepare(sql));
}
async exec(sql) {
this.throwIfDisconnected();
const connection = this.getRawConnection();
connection.setAttributes(this.attributes);
return await connection.exec(sql);
}
async query(sql) {
this.throwIfDisconnected();
const connection = this.getRawConnection();
connection.setAttributes(this.attributes);
return new this.instances.statement(connection, sql, ...(await connection.query(sql)));
}
getAttribute(attribute) {
return this.attributes[attribute];
}
setAttribute(attribute, value) {
if (attribute in this.attributes) {
this.attributes[attribute] = value;
return true;
}
return false;
}
async getVersion() {
if (this.version === undefined) {
const connection = await this.createConnection();
this.version = await this.getVersionFromConnection(connection);
await this.closeConnection(connection);
}
return this.version;
}
async getRawPoolConnection() {
this.throwIfDisconnected();
const connection = await this.pool.acquire().promise;
return {
connection,
release: async () => {
await this.pool.release(connection);
},
};
}
async getRawDriverConnection() {
return (await this.createConnection(true));
}
assignPoolEvents() {
this.pool.on('acquireSuccess', (eventId, connection) => {
if (typeof this.poolEvents.acquired === 'function') {
this.poolEvents.acquired(connection.__lupdo_uuid, eventId);
}
if (this.hasDebug) {
console.log(`Pdo Pool Resource Acquired: ${connection.__lupdo_uuid}`);
}
});
this.pool.on('release', (connection) => {
if (typeof this.poolEvents.released === 'function') {
this.poolEvents.released(connection.__lupdo_uuid);
}
if (this.hasDebug) {
console.log(`Pdo Pool Resource Released: ${connection.__lupdo_uuid}`);
}
});
}
throwIfDisconnected() {
if (this.disconnected) {
throw new pdo_error_1.default('Pdo is Disconnected from pool, please reconnect.');
}
}
}
exports.PdoDriver = PdoDriver;
exports.default = PdoDriver;