providerrefactor part1

This commit is contained in:
seb
2026-09-21 03:33:55 +02:00
parent 53a20c4353
commit 4ed6260e91
57 changed files with 1662 additions and 145 deletions

49
src/store/runner.js Normal file
View File

@@ -0,0 +1,49 @@
/**
* Resolves the object a store method should query through.
*
* Converted store modules call `runner.query(sql, params)`. During the
* incremental migration (see TODO.md §1) they may still be constructed with a
* raw `mssql` pool, or called with a raw `mssql` Transaction as `tx`. This
* adapter exposes the provider 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 {import('../providers/provider.js').DatabaseProvider}
*/
/** Wraps a raw mssql pool/transaction in the provider query contract. */
function wrapMssql(target) {
return {
dialect: 'mssql',
async query(sql, params = {}) {
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 };
},
};
}
function normalize(target) {
if (!target) return null;
// Provider instances expose `dialect`; legacy mssql pools also have a
// `query()` method, so check for the marker before trusting `query`.
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) {
return normalize(tx) ?? normalize(provider) ?? provider;
}
return normalize(provider) ?? provider;
}