86 lines
3.3 KiB
JavaScript
86 lines
3.3 KiB
JavaScript
/**
|
|
* Resolves the object a store method should query through.
|
|
*
|
|
* Converted store modules call `runner(sql, params)` or `runner.query(sql, params)`.
|
|
* During the incremental migration they may still be constructed with a
|
|
* raw `mssql` pool, or called with a raw `mssql` Transaction as `tx`. This
|
|
* adapter exposes the unified runner contract over both so mixed call sites keep
|
|
* working until every module is converted.
|
|
*
|
|
* @param {import('../providers/provider.js').DatabaseProvider} provider
|
|
* @param {object} [tx] Optional provider runner or legacy mssql Transaction.
|
|
* @returns {((sql: string, params?: object) => Promise<import('../providers/provider.js').QueryResult>) & { query: Function, dialect?: string }}
|
|
*/
|
|
|
|
import { logSlowQuery } from '../providers/provider.js';
|
|
|
|
/** Wraps a raw mssql pool/transaction in the provider query contract. */
|
|
function wrapMssql(target) {
|
|
return {
|
|
dialect: 'mssql',
|
|
async query(sql, params = {}) {
|
|
const start = performance.now();
|
|
try {
|
|
const req = target.request();
|
|
for (const [key, value] of Object.entries(params)) {
|
|
req.input(key, value);
|
|
}
|
|
const result = await req.query(sql);
|
|
const rows = result.recordset ?? [];
|
|
const rowsAffected = Array.isArray(result.rowsAffected)
|
|
? result.rowsAffected.reduce((a, b) => a + b, 0)
|
|
: 0;
|
|
return { rows, rowsAffected, insertId: null };
|
|
} finally {
|
|
logSlowQuery(sql, performance.now() - start, params);
|
|
}
|
|
},
|
|
};
|
|
}
|
|
|
|
function normalize(target) {
|
|
if (!target) return null;
|
|
if (typeof target === 'function' && typeof target.query === 'function') return target;
|
|
if (target.dialect) return target;
|
|
if (typeof target.request === 'function') return wrapMssql(target);
|
|
if (typeof target.query === 'function') return target;
|
|
return null;
|
|
}
|
|
|
|
export default function makeRunner(provider, tx) {
|
|
if (tx && tx !== provider) {
|
|
if (typeof tx === 'function' && typeof tx.query === 'function') return tx;
|
|
const normTx = normalize(tx);
|
|
if (normTx) return createCallableRunner(normTx);
|
|
}
|
|
if (typeof provider === 'function' && typeof provider.query === 'function') return provider;
|
|
const normProvider = normalize(provider);
|
|
if (normProvider) return createCallableRunner(normProvider);
|
|
return null;
|
|
}
|
|
|
|
function createCallableRunner(base) {
|
|
if (typeof base === 'function' && typeof base.query === 'function') return base;
|
|
const run = async (sql, params) => {
|
|
return base.query(sql, params);
|
|
};
|
|
run.query = run;
|
|
run.exec = base.exec ? base.exec.bind(base) : undefined;
|
|
run.dialect = base.dialect;
|
|
run.provider = base.provider || base;
|
|
run.writeFileContent = base.writeFileContent?.bind(base);
|
|
run.readFileContent = base.readFileContent?.bind(base);
|
|
run.writeThumbAvif = base.writeThumbAvif?.bind(base);
|
|
run.readThumbAvif = base.readThumbAvif?.bind(base);
|
|
run.writePicFull = base.writePicFull?.bind(base);
|
|
run.readPicFull = base.readPicFull?.bind(base);
|
|
run.writePicThumb = base.writePicThumb?.bind(base);
|
|
run.readPicThumb = base.readPicThumb?.bind(base);
|
|
run.deleteFile = base.deleteFile?.bind(base);
|
|
run.deletePic = base.deletePic?.bind(base);
|
|
run.writeVfsContent = base.writeVfsContent?.bind(base);
|
|
run.readVfsContent = base.readVfsContent?.bind(base);
|
|
run.deleteVfsContent = base.deleteVfsContent?.bind(base);
|
|
return run;
|
|
}
|