providerrefactor part1
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
* { rows, rowsAffected, insertId }
|
||||
*/
|
||||
|
||||
import sql from 'mssql';
|
||||
|
||||
function normalizeRows(result) {
|
||||
const recordset = result?.recordset ?? [];
|
||||
const affected = Array.isArray(result?.rowsAffected)
|
||||
@@ -55,24 +57,67 @@ export class MssqlExecutor {
|
||||
}
|
||||
|
||||
export class MssqlProvider {
|
||||
/** @param {import('mssql').ConnectionPool} pool */
|
||||
constructor(pool) {
|
||||
if (!pool || typeof pool.request !== 'function') {
|
||||
throw new TypeError('MssqlProvider requires an mssql ConnectionPool');
|
||||
/**
|
||||
* @param {import('mssql').ConnectionPool | import('mssql').config} poolOrConfig
|
||||
* Either an already-connected mssql ConnectionPool, or a plain mssql
|
||||
* config object — in which case the pool is created lazily on first use
|
||||
* (and closed by {@link MssqlProvider#close}).
|
||||
*/
|
||||
constructor(poolOrConfig) {
|
||||
const isPool =
|
||||
poolOrConfig && typeof poolOrConfig.request === 'function';
|
||||
if (!poolOrConfig || (!isPool && !poolOrConfig.server)) {
|
||||
throw new TypeError(
|
||||
'MssqlProvider requires an mssql ConnectionPool or a config object with `server`',
|
||||
);
|
||||
}
|
||||
this.pool = pool;
|
||||
// Keep a stable pool object available immediately. Transitional store
|
||||
// modules capture `provider.pool` in their factory closures, so assigning
|
||||
// a different object after a lazy connection would leave them with null.
|
||||
this.pool = isPool ? poolOrConfig : new sql.ConnectionPool(poolOrConfig);
|
||||
this.#config = isPool ? null : poolOrConfig;
|
||||
this.dialect = 'mssql';
|
||||
}
|
||||
|
||||
#config;
|
||||
#connecting;
|
||||
|
||||
/**
|
||||
* Returns the underlying pool, creating and connecting it on first use
|
||||
* when the provider was constructed from a config object.
|
||||
* @returns {Promise<import('mssql').ConnectionPool>}
|
||||
*/
|
||||
ensurePool() {
|
||||
if (this.pool.connected) return Promise.resolve(this.pool);
|
||||
if (!this.#connecting) {
|
||||
this.#connecting = this.pool
|
||||
.connect()
|
||||
.then((pool) => {
|
||||
return pool;
|
||||
})
|
||||
.catch((err) => {
|
||||
this.#connecting = undefined;
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
return this.#connecting;
|
||||
}
|
||||
|
||||
makeExecutor(requestFactory = () => this.pool.request()) {
|
||||
return new MssqlExecutor(requestFactory);
|
||||
}
|
||||
|
||||
async #withPool(fn) {
|
||||
const pool = await this.ensurePool();
|
||||
return fn(new MssqlExecutor(() => pool.request()));
|
||||
}
|
||||
|
||||
async query(sql, params = {}) {
|
||||
return this.makeExecutor().query(sql, params);
|
||||
return this.#withPool((executor) => executor.query(sql, params));
|
||||
}
|
||||
|
||||
async exec(procName, options) {
|
||||
return this.makeExecutor().exec(procName, options);
|
||||
return this.#withPool((executor) => executor.exec(procName, options));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,7 +129,8 @@ export class MssqlProvider {
|
||||
* @returns {Promise<T>}
|
||||
*/
|
||||
async transaction(fn) {
|
||||
const tx = this.pool.transaction();
|
||||
const pool = await this.ensurePool();
|
||||
const tx = pool.transaction();
|
||||
await tx.begin();
|
||||
try {
|
||||
const runner = this.makeExecutor(() => tx.request());
|
||||
@@ -111,7 +157,7 @@ export class MssqlProvider {
|
||||
}
|
||||
|
||||
close() {
|
||||
return this.pool.close();
|
||||
return this.pool ? this.pool.close() : Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user