UNPKG

lupdo

Version:

Database Abstraction Layer for Node js

217 lines (216 loc) 8.91 kB
"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;