forge-sql-orm 2.1.1 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ForgeSQLORM.js +64 -50
- package/dist/ForgeSQLORM.js.map +1 -1
- package/dist/ForgeSQLORM.mjs +64 -50
- package/dist/ForgeSQLORM.mjs.map +1 -1
- package/dist/core/ForgeSQLORM.d.ts.map +1 -1
- package/dist/core/ForgeSQLQueryBuilder.d.ts +23 -23
- package/dist/core/ForgeSQLQueryBuilder.d.ts.map +1 -1
- package/dist/lib/drizzle/extensions/additionalActions.d.ts.map +1 -1
- package/dist/utils/cacheContextUtils.d.ts +4 -2
- package/dist/utils/cacheContextUtils.d.ts.map +1 -1
- package/dist/utils/sqlUtils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/ForgeSQLORM.ts +29 -23
- package/src/core/ForgeSQLQueryBuilder.ts +172 -119
- package/src/lib/drizzle/extensions/additionalActions.ts +123 -74
- package/src/lib/drizzle/extensions/types.d.ts +16 -11
- package/src/utils/cacheContextUtils.ts +16 -4
- package/src/utils/sqlUtils.ts +27 -28
package/dist/ForgeSQLORM.mjs
CHANGED
|
@@ -534,7 +534,7 @@ async function saveTableIfInsideCacheContext(table) {
|
|
|
534
534
|
context.tables.add(tableName);
|
|
535
535
|
}
|
|
536
536
|
}
|
|
537
|
-
async function saveQueryLocalCacheQuery(query, rows) {
|
|
537
|
+
async function saveQueryLocalCacheQuery(query, rows, options) {
|
|
538
538
|
const context = localCacheApplicationContext.getStore();
|
|
539
539
|
if (context) {
|
|
540
540
|
if (!context.cache) {
|
|
@@ -546,9 +546,15 @@ async function saveQueryLocalCacheQuery(query, rows) {
|
|
|
546
546
|
sql: sql2.toSQL().sql.toLowerCase(),
|
|
547
547
|
data: rows
|
|
548
548
|
};
|
|
549
|
+
if (options.logRawSqlQuery) {
|
|
550
|
+
const q = sql2.toSQL();
|
|
551
|
+
console.log(
|
|
552
|
+
`[forge-sql-orm][local-cache][SAVE] Stored result in cache. sql="${q.sql}", params=${JSON.stringify(q.params)}`
|
|
553
|
+
);
|
|
554
|
+
}
|
|
549
555
|
}
|
|
550
556
|
}
|
|
551
|
-
async function getQueryLocalCacheQuery(query) {
|
|
557
|
+
async function getQueryLocalCacheQuery(query, options) {
|
|
552
558
|
const context = localCacheApplicationContext.getStore();
|
|
553
559
|
if (context) {
|
|
554
560
|
if (!context.cache) {
|
|
@@ -557,6 +563,12 @@ async function getQueryLocalCacheQuery(query) {
|
|
|
557
563
|
const sql2 = query;
|
|
558
564
|
const key = hashKey(sql2.toSQL());
|
|
559
565
|
if (context.cache[key] && context.cache[key].sql === sql2.toSQL().sql.toLowerCase()) {
|
|
566
|
+
if (options.logRawSqlQuery) {
|
|
567
|
+
const q = sql2.toSQL();
|
|
568
|
+
console.log(
|
|
569
|
+
`[forge-sql-orm][local-cache][HIT] Returned cached result. sql="${q.sql}", params=${JSON.stringify(q.params)}`
|
|
570
|
+
);
|
|
571
|
+
}
|
|
560
572
|
return context.cache[key].data;
|
|
561
573
|
}
|
|
562
574
|
}
|
|
@@ -1046,23 +1058,10 @@ function createForgeDriverProxy(options, logRawSqlQuery) {
|
|
|
1046
1058
|
return forgeDriver(modifiedQuery, params, method);
|
|
1047
1059
|
};
|
|
1048
1060
|
}
|
|
1049
|
-
const NON_CACHE_CLEARING_ERROR_CODES = [
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
];
|
|
1053
|
-
const CACHE_CLEARING_ERROR_CODES = [
|
|
1054
|
-
"DEADLOCK",
|
|
1055
|
-
"LOCK_WAIT_TIMEOUT",
|
|
1056
|
-
"CONNECTION_ERROR"
|
|
1057
|
-
];
|
|
1058
|
-
const NON_CACHE_CLEARING_PATTERNS = [
|
|
1059
|
-
/validation/i,
|
|
1060
|
-
/constraint/i
|
|
1061
|
-
];
|
|
1062
|
-
const CACHE_CLEARING_PATTERNS = [
|
|
1063
|
-
/timeout/i,
|
|
1064
|
-
/connection/i
|
|
1065
|
-
];
|
|
1061
|
+
const NON_CACHE_CLEARING_ERROR_CODES = ["VALIDATION_ERROR", "CONSTRAINT_ERROR"];
|
|
1062
|
+
const CACHE_CLEARING_ERROR_CODES = ["DEADLOCK", "LOCK_WAIT_TIMEOUT", "CONNECTION_ERROR"];
|
|
1063
|
+
const NON_CACHE_CLEARING_PATTERNS = [/validation/i, /constraint/i];
|
|
1064
|
+
const CACHE_CLEARING_PATTERNS = [/timeout/i, /connection/i];
|
|
1066
1065
|
function shouldClearCacheOnError(error) {
|
|
1067
1066
|
if (error?.code && NON_CACHE_CLEARING_ERROR_CODES.includes(error.code)) {
|
|
1068
1067
|
return false;
|
|
@@ -1154,7 +1153,7 @@ function deleteAndEvictCacheBuilder(db, table, options, isCached) {
|
|
|
1154
1153
|
}
|
|
1155
1154
|
async function handleCachedQuery(target, options, cacheTtl, selections, aliasMap, onfulfilled, onrejected) {
|
|
1156
1155
|
try {
|
|
1157
|
-
const localCached = await getQueryLocalCacheQuery(target);
|
|
1156
|
+
const localCached = await getQueryLocalCacheQuery(target, options);
|
|
1158
1157
|
if (localCached) {
|
|
1159
1158
|
return onfulfilled?.(localCached);
|
|
1160
1159
|
}
|
|
@@ -1164,7 +1163,7 @@ async function handleCachedQuery(target, options, cacheTtl, selections, aliasMap
|
|
|
1164
1163
|
}
|
|
1165
1164
|
const rows = await target.execute();
|
|
1166
1165
|
const transformed = applyFromDriverTransform(rows, selections, aliasMap);
|
|
1167
|
-
await saveQueryLocalCacheQuery(target, transformed);
|
|
1166
|
+
await saveQueryLocalCacheQuery(target, transformed, options);
|
|
1168
1167
|
await setCacheResult(target, options, transformed, cacheTtl).catch((cacheError) => {
|
|
1169
1168
|
console.warn("Cache set error:", cacheError);
|
|
1170
1169
|
});
|
|
@@ -1173,15 +1172,15 @@ async function handleCachedQuery(target, options, cacheTtl, selections, aliasMap
|
|
|
1173
1172
|
return onrejected?.(error);
|
|
1174
1173
|
}
|
|
1175
1174
|
}
|
|
1176
|
-
async function handleNonCachedQuery(target, selections, aliasMap, onfulfilled, onrejected) {
|
|
1175
|
+
async function handleNonCachedQuery(target, options, selections, aliasMap, onfulfilled, onrejected) {
|
|
1177
1176
|
try {
|
|
1178
|
-
const localCached = await getQueryLocalCacheQuery(target);
|
|
1177
|
+
const localCached = await getQueryLocalCacheQuery(target, options);
|
|
1179
1178
|
if (localCached) {
|
|
1180
1179
|
return onfulfilled?.(localCached);
|
|
1181
1180
|
}
|
|
1182
1181
|
const rows = await target.execute();
|
|
1183
1182
|
const transformed = applyFromDriverTransform(rows, selections, aliasMap);
|
|
1184
|
-
await saveQueryLocalCacheQuery(target, transformed);
|
|
1183
|
+
await saveQueryLocalCacheQuery(target, transformed, options);
|
|
1185
1184
|
return onfulfilled?.(transformed);
|
|
1186
1185
|
} catch (error) {
|
|
1187
1186
|
return onrejected?.(error);
|
|
@@ -1213,7 +1212,14 @@ function createAliasedSelectBuilder(db, fields, selectFn, useCache, options, cac
|
|
|
1213
1212
|
onrejected
|
|
1214
1213
|
);
|
|
1215
1214
|
} else {
|
|
1216
|
-
return handleNonCachedQuery(
|
|
1215
|
+
return handleNonCachedQuery(
|
|
1216
|
+
target,
|
|
1217
|
+
options,
|
|
1218
|
+
selections,
|
|
1219
|
+
aliasMap,
|
|
1220
|
+
onfulfilled,
|
|
1221
|
+
onrejected
|
|
1222
|
+
);
|
|
1217
1223
|
}
|
|
1218
1224
|
};
|
|
1219
1225
|
}
|
|
@@ -1247,14 +1253,16 @@ function createRawQueryExecutor(db, options, useGlobalCache = false) {
|
|
|
1247
1253
|
let sql2;
|
|
1248
1254
|
if (isSQLWrapper(query)) {
|
|
1249
1255
|
const sqlWrapper = query;
|
|
1250
|
-
sql2 = sqlWrapper.getSQL().toQuery(
|
|
1256
|
+
sql2 = sqlWrapper.getSQL().toQuery(
|
|
1257
|
+
db.dialect
|
|
1258
|
+
);
|
|
1251
1259
|
} else {
|
|
1252
1260
|
sql2 = {
|
|
1253
1261
|
sql: query,
|
|
1254
1262
|
params: []
|
|
1255
1263
|
};
|
|
1256
1264
|
}
|
|
1257
|
-
const localCacheResult = await getQueryLocalCacheQuery(sql2);
|
|
1265
|
+
const localCacheResult = await getQueryLocalCacheQuery(sql2, options);
|
|
1258
1266
|
if (localCacheResult) {
|
|
1259
1267
|
return localCacheResult;
|
|
1260
1268
|
}
|
|
@@ -1265,7 +1273,7 @@ function createRawQueryExecutor(db, options, useGlobalCache = false) {
|
|
|
1265
1273
|
}
|
|
1266
1274
|
}
|
|
1267
1275
|
const results = await db.execute(query);
|
|
1268
|
-
await saveQueryLocalCacheQuery(sql2, results);
|
|
1276
|
+
await saveQueryLocalCacheQuery(sql2, results, options);
|
|
1269
1277
|
if (useGlobalCache) {
|
|
1270
1278
|
await setCacheResult(
|
|
1271
1279
|
{ toSQL: () => sql2 },
|
|
@@ -1816,34 +1824,40 @@ class ForgeSQLORMImpl {
|
|
|
1816
1824
|
*/
|
|
1817
1825
|
async executeWithCacheContextAndReturnValue(cacheContext) {
|
|
1818
1826
|
return await this.executeWithLocalCacheContextAndReturnValue(
|
|
1819
|
-
async () => await cacheApplicationContext.run(
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
+
async () => await cacheApplicationContext.run(
|
|
1828
|
+
cacheApplicationContext.getStore() ?? { tables: /* @__PURE__ */ new Set() },
|
|
1829
|
+
async () => {
|
|
1830
|
+
try {
|
|
1831
|
+
return await cacheContext();
|
|
1832
|
+
} finally {
|
|
1833
|
+
await clearTablesCache(
|
|
1834
|
+
Array.from(cacheApplicationContext.getStore()?.tables ?? []),
|
|
1835
|
+
this.options
|
|
1836
|
+
);
|
|
1837
|
+
}
|
|
1827
1838
|
}
|
|
1828
|
-
|
|
1839
|
+
)
|
|
1829
1840
|
);
|
|
1830
1841
|
}
|
|
1831
1842
|
/**
|
|
1832
1843
|
* Executes operations within a local cache context and returns a value.
|
|
1833
1844
|
* This provides in-memory caching for select queries within a single request scope.
|
|
1834
|
-
*
|
|
1845
|
+
*
|
|
1835
1846
|
* @param cacheContext - Function containing operations that will benefit from local caching
|
|
1836
1847
|
* @returns Promise that resolves to the return value of the cacheContext function
|
|
1837
1848
|
*/
|
|
1838
1849
|
async executeWithLocalCacheContextAndReturnValue(cacheContext) {
|
|
1839
|
-
return await localCacheApplicationContext.run(
|
|
1840
|
-
|
|
1841
|
-
|
|
1850
|
+
return await localCacheApplicationContext.run(
|
|
1851
|
+
localCacheApplicationContext.getStore() ?? { cache: {} },
|
|
1852
|
+
async () => {
|
|
1853
|
+
return await cacheContext();
|
|
1854
|
+
}
|
|
1855
|
+
);
|
|
1842
1856
|
}
|
|
1843
1857
|
/**
|
|
1844
1858
|
* Executes operations within a local cache context.
|
|
1845
1859
|
* This provides in-memory caching for select queries within a single request scope.
|
|
1846
|
-
*
|
|
1860
|
+
*
|
|
1847
1861
|
* @param cacheContext - Function containing operations that will benefit from local caching
|
|
1848
1862
|
* @returns Promise that resolves when all operations are complete
|
|
1849
1863
|
*/
|
|
@@ -2140,7 +2154,7 @@ class ForgeSQLORMImpl {
|
|
|
2140
2154
|
* ```typescript
|
|
2141
2155
|
* // Using SQLWrapper
|
|
2142
2156
|
* const result = await forgeSQL.execute(sql`SELECT * FROM users WHERE id = ${userId}`);
|
|
2143
|
-
*
|
|
2157
|
+
*
|
|
2144
2158
|
* // Using string
|
|
2145
2159
|
* const result = await forgeSQL.execute("SELECT * FROM users WHERE status = 'active'");
|
|
2146
2160
|
* ```
|
|
@@ -2161,7 +2175,7 @@ class ForgeSQLORMImpl {
|
|
|
2161
2175
|
* ```typescript
|
|
2162
2176
|
* // Using SQLWrapper with custom TTL
|
|
2163
2177
|
* const result = await forgeSQL.executeCacheable(sql`SELECT * FROM users WHERE id = ${userId}`, 300);
|
|
2164
|
-
*
|
|
2178
|
+
*
|
|
2165
2179
|
* // Using string with default TTL
|
|
2166
2180
|
* const result = await forgeSQL.executeCacheable("SELECT * FROM users WHERE status = 'active'");
|
|
2167
2181
|
* ```
|
|
@@ -2199,7 +2213,7 @@ class ForgeSQLORMImpl {
|
|
|
2199
2213
|
* .from(users)
|
|
2200
2214
|
* .groupBy(users.id)
|
|
2201
2215
|
* );
|
|
2202
|
-
*
|
|
2216
|
+
*
|
|
2203
2217
|
* const result = await forgeSQL.with(withQuery)
|
|
2204
2218
|
* .select({ userId: withQuery.userId, count: withQuery.count })
|
|
2205
2219
|
* .from(withQuery);
|
|
@@ -2291,7 +2305,7 @@ class ForgeSQLORM {
|
|
|
2291
2305
|
/**
|
|
2292
2306
|
* Executes operations within a local cache context.
|
|
2293
2307
|
* This provides in-memory caching for select queries within a single request scope.
|
|
2294
|
-
*
|
|
2308
|
+
*
|
|
2295
2309
|
* @param cacheContext - Function containing operations that will benefit from local caching
|
|
2296
2310
|
* @returns Promise that resolves when all operations are complete
|
|
2297
2311
|
*/
|
|
@@ -2301,7 +2315,7 @@ class ForgeSQLORM {
|
|
|
2301
2315
|
/**
|
|
2302
2316
|
* Executes operations within a local cache context and returns a value.
|
|
2303
2317
|
* This provides in-memory caching for select queries within a single request scope.
|
|
2304
|
-
*
|
|
2318
|
+
*
|
|
2305
2319
|
* @param cacheContext - Function containing operations that will benefit from local caching
|
|
2306
2320
|
* @returns Promise that resolves to the return value of the cacheContext function
|
|
2307
2321
|
*/
|
|
@@ -2465,7 +2479,7 @@ class ForgeSQLORM {
|
|
|
2465
2479
|
* ```typescript
|
|
2466
2480
|
* // Using SQLWrapper
|
|
2467
2481
|
* const result = await forgeSQL.execute(sql`SELECT * FROM users WHERE id = ${userId}`);
|
|
2468
|
-
*
|
|
2482
|
+
*
|
|
2469
2483
|
* // Using string
|
|
2470
2484
|
* const result = await forgeSQL.execute("SELECT * FROM users WHERE status = 'active'");
|
|
2471
2485
|
* ```
|
|
@@ -2486,7 +2500,7 @@ class ForgeSQLORM {
|
|
|
2486
2500
|
* ```typescript
|
|
2487
2501
|
* // Using SQLWrapper with custom TTL
|
|
2488
2502
|
* const result = await forgeSQL.executeCacheable(sql`SELECT * FROM users WHERE id = ${userId}`, 300);
|
|
2489
|
-
*
|
|
2503
|
+
*
|
|
2490
2504
|
* // Using string with default TTL
|
|
2491
2505
|
* const result = await forgeSQL.executeCacheable("SELECT * FROM users WHERE status = 'active'");
|
|
2492
2506
|
* ```
|
|
@@ -2524,7 +2538,7 @@ class ForgeSQLORM {
|
|
|
2524
2538
|
* .from(users)
|
|
2525
2539
|
* .groupBy(users.id)
|
|
2526
2540
|
* );
|
|
2527
|
-
*
|
|
2541
|
+
*
|
|
2528
2542
|
* const result = await forgeSQL.with(withQuery)
|
|
2529
2543
|
* .select({ userId: withQuery.userId, count: withQuery.count })
|
|
2530
2544
|
* .from(withQuery);
|