mariadb
Version:
fast mariadb or mysql connector.
260 lines (238 loc) • 6.68 kB
JavaScript
// SPDX-License-Identifier: LGPL-2.1-or-later
// Copyright (c) 2015-2025 MariaDB Corporation Ab
'use strict';
import { EventEmitter } from 'node:events';
import Pool from './pool.js';
import ConnectionPromise, { paramSetter } from './connection-promise.js';
import * as Errors from './misc/errors.js';
const hasAsyncDispose = typeof Symbol.asyncDispose === 'symbol';
class PoolPromise extends EventEmitter {
#pool;
constructor(options) {
super();
this.#pool = new Pool(options);
const poolPromise = this;
this.#pool._onNewConnection = (conn) => {
try {
poolPromise.emit('connection', new ConnectionPromise(conn));
} catch (err) {
// ignore user errors in connection event handler
}
};
this.#pool.on('acquire', this.emit.bind(this, 'acquire'));
this.#pool.on('enqueue', this.emit.bind(this, 'enqueue'));
this.#pool.on('release', this.emit.bind(this, 'release'));
this.#pool.on('error', this.emit.bind(this, 'error'));
}
get closed() {
return this.#pool.closed;
}
/**
* Get the current total connection number.
* @return {number}
*/
totalConnections() {
return this.#pool.totalConnections();
}
/**
* Get current active connections.
* @return {number}
*/
activeConnections() {
return this.#pool.activeConnections();
}
/**
* Get the current idle connection number.
* @return {number}
*/
idleConnections() {
return this.#pool.idleConnections();
}
/**
* Get current stacked connection request.
* @return {number}
*/
taskQueueSize() {
return this.#pool.taskQueueSize();
}
escape(value) {
return this.#pool.escape(value);
}
escapeId(value) {
return this.#pool.escapeId(value);
}
/**
* End pool
*
* @return Promise
**/
end() {
return this.#pool.end();
}
/**
* Retrieve a connection from the pool.
* Create a new one if the limit is not reached.
* wait until acquireTimeout.
*
*/
async getConnection() {
const cmdParam = {};
if (this.#pool.opts.connOptions.trace) Error.captureStackTrace(cmdParam);
return new Promise((resolve, reject) => {
this.#pool.getConnection(cmdParam, (err, baseConn) => {
if (err) {
reject(err);
} else {
const conn = new ConnectionPromise(baseConn);
conn.release = () => new Promise(baseConn.release);
conn.end = conn.release;
conn.close = conn.release;
if (hasAsyncDispose) {
conn[Symbol.asyncDispose] = () => conn.release();
}
resolve(conn);
}
});
});
}
/**
* Execute a query using text protocol with callback emit columns/data/end/error
* events to permit streaming big result-set
*
* @param sql sql parameter Object can be used to supersede the default option.
* Object must then have a `sql` property.
* @param values object / array of placeholder values (not mandatory)
*/
query(sql, values) {
const cmdParam = paramSetter(sql, values);
if (this.#pool.opts.connOptions.trace) Error.captureStackTrace(cmdParam);
return new Promise((resolve, reject) => {
return this.#pool.getConnection(cmdParam, (err, baseConn) => {
if (err) {
reject(err);
} else {
baseConn.query(
cmdParam,
(res) => {
this.#pool.release(baseConn);
resolve(res);
},
(err) => {
this.#pool.release(baseConn);
reject(err);
}
);
}
});
});
}
/**
* Execute a query using binary protocol with callback emit columns/data/end/error
* events to permit streaming big result-set
*
* @param sql sql parameter Object can be used to supersede the default option.
* Object must then have a `sql` property.
* @param values object / array of placeholder values (not mandatory)
*/
execute(sql, values) {
const cmdParam = paramSetter(sql, values);
if (this.#pool.opts.connOptions.trace) Error.captureStackTrace(cmdParam);
return new Promise((resolve, reject) => {
return this.#pool.getConnection(cmdParam, (err, baseConn) => {
if (err) {
reject(err);
} else {
baseConn.prepareExecute(
cmdParam,
(res) => {
this.#pool.release(baseConn);
resolve(res);
},
(err) => {
this.#pool.release(baseConn);
reject(err);
}
);
}
});
});
}
/**
* execute a batch
*
* @param sql sql parameter Object can be used to supersede the default option.
* Object must then have a `sql` property.
* @param values array of placeholder values
*/
batch(sql, values) {
const cmdParam = paramSetter(sql, values);
if (this.#pool.opts.connOptions.trace) Error.captureStackTrace(cmdParam);
return new Promise((resolve, reject) => {
return this.#pool.getConnection(cmdParam, (err, baseConn) => {
if (err) {
reject(err);
} else {
baseConn.batch(
cmdParam,
(res) => {
this.#pool.release(baseConn);
resolve(res);
},
(err) => {
this.#pool.release(baseConn);
reject(err);
}
);
}
});
});
}
/**
* Import SQL file.
*
* @param opts JSON array with 2 possible fields: file and database
*/
importFile(opts) {
if (!opts) {
return Promise.reject(
Errors.createError(
'SQL file parameter is mandatory',
Errors.client.ER_MISSING_SQL_PARAMETER,
null,
'HY000',
null,
false,
null
)
);
}
return new Promise((resolve, reject) => {
return this.#pool.getConnection({}, (err, baseConn) => {
if (err) {
reject(err);
} else {
baseConn.importFile(
{ file: opts.file, database: opts.database },
(res) => {
this.#pool.release(baseConn);
resolve(res);
},
(err) => {
this.#pool.release(baseConn);
reject(err);
}
);
}
});
});
}
toString() {
return 'poolPromise(' + this.#pool.toString() + ')';
}
}
if (hasAsyncDispose) {
PoolPromise.prototype[Symbol.asyncDispose] = function () {
return this.end();
};
}
export default PoolPromise;