forge-sql-orm 2.1.23 → 2.1.25
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/README.md +46 -23
- package/dist/core/ForgeSQLAnalyseOperations.d.ts +4 -0
- package/dist/core/ForgeSQLAnalyseOperations.d.ts.map +1 -1
- package/dist/core/ForgeSQLAnalyseOperations.js +17 -21
- package/dist/core/ForgeSQLAnalyseOperations.js.map +1 -1
- package/dist/core/ForgeSQLCrudOperations.d.ts +16 -0
- package/dist/core/ForgeSQLCrudOperations.d.ts.map +1 -1
- package/dist/core/ForgeSQLCrudOperations.js +60 -28
- package/dist/core/ForgeSQLCrudOperations.js.map +1 -1
- package/dist/core/ForgeSQLQueryBuilder.d.ts +15 -28
- package/dist/core/ForgeSQLQueryBuilder.d.ts.map +1 -1
- package/dist/core/ForgeSQLQueryBuilder.js +20 -47
- package/dist/core/ForgeSQLQueryBuilder.js.map +1 -1
- package/dist/core/Rovo.d.ts +32 -0
- package/dist/core/Rovo.d.ts.map +1 -1
- package/dist/core/Rovo.js +116 -67
- package/dist/core/Rovo.js.map +1 -1
- package/dist/lib/drizzle/extensions/additionalActions.d.ts.map +1 -1
- package/dist/lib/drizzle/extensions/additionalActions.js +168 -118
- package/dist/lib/drizzle/extensions/additionalActions.js.map +1 -1
- package/dist/utils/cacheTableUtils.d.ts +0 -8
- package/dist/utils/cacheTableUtils.d.ts.map +1 -1
- package/dist/utils/cacheTableUtils.js +183 -126
- package/dist/utils/cacheTableUtils.js.map +1 -1
- package/dist/utils/cacheUtils.d.ts +13 -1
- package/dist/utils/cacheUtils.d.ts.map +1 -1
- package/dist/utils/cacheUtils.js +60 -47
- package/dist/utils/cacheUtils.js.map +1 -1
- package/dist/utils/forgeDriverProxy.d.ts.map +1 -1
- package/dist/utils/forgeDriverProxy.js +31 -20
- package/dist/utils/forgeDriverProxy.js.map +1 -1
- package/dist/utils/sqlHints.d.ts.map +1 -1
- package/dist/utils/sqlHints.js +19 -29
- package/dist/utils/sqlHints.js.map +1 -1
- package/dist/utils/sqlUtils.d.ts +0 -29
- package/dist/utils/sqlUtils.d.ts.map +1 -1
- package/dist/utils/sqlUtils.js +107 -78
- package/dist/utils/sqlUtils.js.map +1 -1
- package/dist/webtriggers/clearCacheSchedulerTrigger.d.ts +24 -4
- package/dist/webtriggers/clearCacheSchedulerTrigger.d.ts.map +1 -1
- package/dist/webtriggers/clearCacheSchedulerTrigger.js +24 -4
- package/dist/webtriggers/clearCacheSchedulerTrigger.js.map +1 -1
- package/package.json +9 -9
- package/src/core/ForgeSQLAnalyseOperations.ts +18 -21
- package/src/core/ForgeSQLCrudOperations.ts +83 -33
- package/src/core/ForgeSQLQueryBuilder.ts +59 -154
- package/src/core/Rovo.ts +158 -98
- package/src/lib/drizzle/extensions/additionalActions.ts +287 -382
- package/src/utils/cacheTableUtils.ts +202 -144
- package/src/utils/cacheUtils.ts +70 -47
- package/src/utils/forgeDriverProxy.ts +39 -21
- package/src/utils/sqlHints.ts +21 -26
- package/src/utils/sqlUtils.ts +151 -101
- package/src/webtriggers/clearCacheSchedulerTrigger.ts +24 -4
package/dist/utils/cacheUtils.js
CHANGED
|
@@ -77,6 +77,29 @@ function nowPlusSeconds(secondsToAdd) {
|
|
|
77
77
|
const dt = luxon_1.DateTime.now().plus({ seconds: secondsToAdd });
|
|
78
78
|
return Math.floor(dt.toSeconds());
|
|
79
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Logs a message to console.debug when options.logCache is enabled.
|
|
82
|
+
*
|
|
83
|
+
* @param message - Message to log
|
|
84
|
+
* @param options - ForgeSQL ORM options (optional)
|
|
85
|
+
*/
|
|
86
|
+
function debugLog(message, options) {
|
|
87
|
+
if (options?.logCache) {
|
|
88
|
+
// eslint-disable-next-line no-console
|
|
89
|
+
console.debug(message);
|
|
90
|
+
}
|
|
91
|
+
} /**
|
|
92
|
+
* Logs a message to console.debug when options.logCache is enabled.
|
|
93
|
+
*
|
|
94
|
+
* @param message - Message to log
|
|
95
|
+
* @param options - ForgeSQL ORM options (optional)
|
|
96
|
+
*/
|
|
97
|
+
function warnLog(message, options) {
|
|
98
|
+
if (options?.logCache) {
|
|
99
|
+
// eslint-disable-next-line no-console
|
|
100
|
+
console.warn(message);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
80
103
|
/**
|
|
81
104
|
* Generates a hash key for a query based on its SQL and parameters.
|
|
82
105
|
*
|
|
@@ -94,16 +117,14 @@ function hashKey(query) {
|
|
|
94
117
|
*
|
|
95
118
|
* @param results - Array of cache entries to delete
|
|
96
119
|
* @param cacheEntityName - Name of the cache entity
|
|
120
|
+
* @param options - Forge SQL ORM properties
|
|
97
121
|
* @returns Promise that resolves when all deletions are complete
|
|
98
122
|
*/
|
|
99
|
-
async function deleteCacheEntriesInBatches(results, cacheEntityName) {
|
|
123
|
+
async function deleteCacheEntriesInBatches(results, cacheEntityName, options) {
|
|
100
124
|
for (let i = 0; i < results.length; i += CACHE_CONSTANTS.BATCH_SIZE) {
|
|
101
125
|
const batch = results.slice(i, i + CACHE_CONSTANTS.BATCH_SIZE);
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
transactionBuilder = transactionBuilder.delete(result.key, { entityName: cacheEntityName });
|
|
105
|
-
}
|
|
106
|
-
await transactionBuilder.execute();
|
|
126
|
+
const batchResult = await kvs_1.kvs.batchDelete(batch.map((result) => ({ key: result.key, entityName: cacheEntityName })));
|
|
127
|
+
batchResult.failedKeys.forEach((failedKey) => warnLog(JSON.stringify(failedKey), options));
|
|
107
128
|
}
|
|
108
129
|
}
|
|
109
130
|
/**
|
|
@@ -134,11 +155,8 @@ async function clearCursorCache(tables, cursor, options) {
|
|
|
134
155
|
entityQueryBuilder = entityQueryBuilder.cursor(cursor);
|
|
135
156
|
}
|
|
136
157
|
const listResult = await entityQueryBuilder.limit(100).getMany();
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
console.warn(`clear cache Records: ${JSON.stringify(listResult.results.map((r) => r.key))}`);
|
|
140
|
-
}
|
|
141
|
-
await deleteCacheEntriesInBatches(listResult.results, cacheEntityName);
|
|
158
|
+
debugLog(`clear cache Records: ${JSON.stringify(listResult.results.map((r) => r.key))}`, options);
|
|
159
|
+
await deleteCacheEntriesInBatches(listResult.results, cacheEntityName, options);
|
|
142
160
|
if (listResult.nextCursor) {
|
|
143
161
|
return (listResult.results.length + (await clearCursorCache(tables, listResult.nextCursor, options)));
|
|
144
162
|
}
|
|
@@ -168,10 +186,7 @@ async function clearExpirationCursorCache(cursor, options) {
|
|
|
168
186
|
entityQueryBuilder = entityQueryBuilder.cursor(cursor);
|
|
169
187
|
}
|
|
170
188
|
const listResult = await entityQueryBuilder.limit(100).getMany();
|
|
171
|
-
|
|
172
|
-
// eslint-disable-next-line no-console
|
|
173
|
-
console.warn(`clear expired Records: ${JSON.stringify(listResult.results.map((r) => r.key))}`);
|
|
174
|
-
}
|
|
189
|
+
debugLog(`clear expired Records: ${JSON.stringify(listResult.results.map((r) => r.key))}`, options);
|
|
175
190
|
await deleteCacheEntriesInBatches(listResult.results, cacheEntityName);
|
|
176
191
|
if (listResult.nextCursor) {
|
|
177
192
|
return (listResult.results.length + (await clearExpirationCursorCache(listResult.nextCursor, options)));
|
|
@@ -243,14 +258,12 @@ async function clearTablesCache(tables, options) {
|
|
|
243
258
|
totalRecords = await executeWithRetry(() => clearCursorCache(tables, "", options), "clearing cache");
|
|
244
259
|
}
|
|
245
260
|
finally {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
// eslint-disable-next-line no-console
|
|
249
|
-
console.info(`Cleared ${totalRecords} cache records in ${duration} seconds`);
|
|
250
|
-
}
|
|
261
|
+
const duration = luxon_1.DateTime.now().toSeconds() - startTime.toSeconds();
|
|
262
|
+
debugLog(`Cleared ${totalRecords} cache records in ${duration} seconds`, options);
|
|
251
263
|
}
|
|
252
264
|
}
|
|
253
265
|
/**
|
|
266
|
+
* since https://developer.atlassian.com/platform/forge/changelog/#CHANGE-3038
|
|
254
267
|
* Clears expired cache entries with retry logic and performance logging.
|
|
255
268
|
*
|
|
256
269
|
* @param options - ForgeSQL ORM options
|
|
@@ -267,15 +280,16 @@ async function clearExpiredCache(options) {
|
|
|
267
280
|
}
|
|
268
281
|
finally {
|
|
269
282
|
const duration = luxon_1.DateTime.now().toSeconds() - startTime.toSeconds();
|
|
270
|
-
|
|
271
|
-
// eslint-disable-next-line no-console
|
|
272
|
-
console.debug(`Cleared ${totalRecords} expired cache records in ${duration} seconds`);
|
|
273
|
-
}
|
|
283
|
+
debugLog(`Cleared ${totalRecords} expired cache records in ${duration} seconds`, options);
|
|
274
284
|
}
|
|
275
285
|
}
|
|
276
286
|
/**
|
|
277
287
|
* Retrieves data from cache if it exists and is not expired.
|
|
278
288
|
*
|
|
289
|
+
* Note: Due to Forge KVS asynchronous deletion (up to 48 hours), expired entries may still
|
|
290
|
+
* be returned. This function checks the expiration timestamp to filter out expired entries.
|
|
291
|
+
* If cache growth impacts performance, use the Clear Cache Scheduler Trigger.
|
|
292
|
+
*
|
|
279
293
|
* @param query - Query object with toSQL method
|
|
280
294
|
* @param options - ForgeSQL ORM options
|
|
281
295
|
* @returns Cached data if found and valid, undefined otherwise
|
|
@@ -291,23 +305,21 @@ async function getFromCache(query, options) {
|
|
|
291
305
|
const key = hashKey(sqlQuery);
|
|
292
306
|
// Skip cache if table is in cache context (will be cleared)
|
|
293
307
|
if (await (0, cacheContextUtils_1.isTableContainsTableInCacheContext)(sqlQuery.sql, options)) {
|
|
294
|
-
|
|
295
|
-
// eslint-disable-next-line no-console
|
|
296
|
-
console.warn(`Context contains value to clear. Skip getting from cache`);
|
|
297
|
-
}
|
|
308
|
+
debugLog("Context contains value to clear. Skip getting from cache", options);
|
|
298
309
|
return undefined;
|
|
299
310
|
}
|
|
300
311
|
try {
|
|
301
312
|
const cacheResult = await kvs_1.kvs.entity(options.cacheEntityName).get(key);
|
|
302
|
-
if (cacheResult
|
|
303
|
-
cacheResult[expirationName] >= getCurrentTime() &&
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
313
|
+
if (cacheResult) {
|
|
314
|
+
if (cacheResult[expirationName] >= getCurrentTime() &&
|
|
315
|
+
(0, cacheTableUtils_1.extractBacktickedValues)(sqlQuery.sql, options) === cacheResult[entityQueryName]) {
|
|
316
|
+
debugLog(`Get value from cache, cacheKey: ${key}`, options);
|
|
317
|
+
const results = cacheResult[dataName];
|
|
318
|
+
return JSON.parse(results);
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
debugLog(`Expired cache entry still exists (will be automatically removed within 48 hours per Forge KVS TTL documentation), cacheKey: ${key}`, options);
|
|
308
322
|
}
|
|
309
|
-
const results = cacheResult[dataName];
|
|
310
|
-
return JSON.parse(results);
|
|
311
323
|
}
|
|
312
324
|
}
|
|
313
325
|
catch (error) {
|
|
@@ -319,11 +331,18 @@ async function getFromCache(query, options) {
|
|
|
319
331
|
/**
|
|
320
332
|
* Stores query results in cache with specified TTL.
|
|
321
333
|
*
|
|
334
|
+
* Uses Forge KVS TTL feature to set expiration. Note that expired data deletion is asynchronous:
|
|
335
|
+
* expired data is not removed immediately upon expiry. Deletion may take up to 48 hours.
|
|
336
|
+
* During this window, read operations may still return expired results. If your app requires
|
|
337
|
+
* strict expiry semantics, consider using the Clear Cache Scheduler Trigger to proactively
|
|
338
|
+
* clean up expired entries, especially if cache growth impacts INSERT/UPDATE performance.
|
|
339
|
+
*
|
|
322
340
|
* @param query - Query object with toSQL method
|
|
323
341
|
* @param options - ForgeSQL ORM options
|
|
324
342
|
* @param results - Data to cache
|
|
325
|
-
* @param cacheTtl - Time to live in seconds
|
|
343
|
+
* @param cacheTtl - Time to live in seconds (maximum TTL is 1 year from write time)
|
|
326
344
|
* @returns Promise that resolves when data is stored in cache
|
|
345
|
+
* @see https://developer.atlassian.com/platform/forge/runtime-reference/storage-api-basic-api/#ttl
|
|
327
346
|
*/
|
|
328
347
|
async function setCacheResult(query, options, results, cacheTtl) {
|
|
329
348
|
if (!options.cacheEntityName) {
|
|
@@ -336,10 +355,7 @@ async function setCacheResult(query, options, results, cacheTtl) {
|
|
|
336
355
|
const sqlQuery = query.toSQL();
|
|
337
356
|
// Skip cache if table is in cache context (will be cleared)
|
|
338
357
|
if (await (0, cacheContextUtils_1.isTableContainsTableInCacheContext)(sqlQuery.sql, options)) {
|
|
339
|
-
|
|
340
|
-
// eslint-disable-next-line no-console
|
|
341
|
-
console.warn(`Context contains value to clear. Skip setting from cache`);
|
|
342
|
-
}
|
|
358
|
+
debugLog("Context contains value to clear. Skip setting from cache", options);
|
|
343
359
|
return;
|
|
344
360
|
}
|
|
345
361
|
const key = hashKey(sqlQuery);
|
|
@@ -347,14 +363,11 @@ async function setCacheResult(query, options, results, cacheTtl) {
|
|
|
347
363
|
.transact()
|
|
348
364
|
.set(key, {
|
|
349
365
|
[entityQueryName]: (0, cacheTableUtils_1.extractBacktickedValues)(sqlQuery.sql, options),
|
|
350
|
-
[expirationName]: nowPlusSeconds(cacheTtl),
|
|
366
|
+
[expirationName]: nowPlusSeconds(cacheTtl + 2),
|
|
351
367
|
[dataName]: JSON.stringify(results),
|
|
352
|
-
}, { entityName: options.cacheEntityName })
|
|
368
|
+
}, { entityName: options.cacheEntityName }, { ttl: { value: cacheTtl, unit: "SECONDS" } })
|
|
353
369
|
.execute();
|
|
354
|
-
|
|
355
|
-
// eslint-disable-next-line no-console
|
|
356
|
-
console.warn(`Store value to cache, cacheKey: ${key}`);
|
|
357
|
-
}
|
|
370
|
+
debugLog(`Store value to cache, cacheKey: ${key}`, options);
|
|
358
371
|
}
|
|
359
372
|
catch (error) {
|
|
360
373
|
// eslint-disable-next-line no-console
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cacheUtils.js","sourceRoot":"","sources":["../../src/utils/cacheUtils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"cacheUtils.js","sourceRoot":"","sources":["../../src/utils/cacheUtils.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forgeDriverProxy.d.ts","sourceRoot":"","sources":["../../src/utils/forgeDriverProxy.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"forgeDriverProxy.d.ts","sourceRoot":"","sources":["../../src/utils/forgeDriverProxy.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAoDjE;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,CAAC,EAAE,QAAQ,EAClB,cAAc,CAAC,EAAE,OAAO,IAGtB,OAAO,MAAM,EACb,QAAQ,GAAG,EAAE,EACb,QAAQ,KAAK,GAAG,SAAS,KACxB,OAAO,CAAC;IACT,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC,CA+BH"}
|
|
@@ -15,6 +15,34 @@ const QUERY_ERROR_CODES = {
|
|
|
15
15
|
* Delay to wait for CLUSTER_STATEMENTS_SUMMARY to be populated
|
|
16
16
|
*/
|
|
17
17
|
const STATEMENTS_SUMMARY_DELAY_MS = 200;
|
|
18
|
+
/**
|
|
19
|
+
* Checks if error is a timeout or out-of-memory error.
|
|
20
|
+
*/
|
|
21
|
+
function isQueryError(error) {
|
|
22
|
+
const isTimeout = error?.code === QUERY_ERROR_CODES.TIMEOUT;
|
|
23
|
+
const isOutOfMemory = error?.context?.debug?.errno === QUERY_ERROR_CODES.OUT_OF_MEMORY_ERRNO;
|
|
24
|
+
return { isTimeout, isOutOfMemory };
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Handles timeout or out-of-memory errors by analyzing the query.
|
|
28
|
+
*/
|
|
29
|
+
async function handleQueryError(queryStartTime, forgeSqlOperation, isTimeout) {
|
|
30
|
+
// Wait for CLUSTER_STATEMENTS_SUMMARY to be populated with our failed query data
|
|
31
|
+
await new Promise((resolve) => setTimeout(resolve, STATEMENTS_SUMMARY_DELAY_MS));
|
|
32
|
+
const queryEndTime = Date.now();
|
|
33
|
+
const queryDuration = queryEndTime - queryStartTime;
|
|
34
|
+
const errorType = isTimeout ? "TIMEOUT" : "OOM";
|
|
35
|
+
if (isTimeout) {
|
|
36
|
+
// eslint-disable-next-line no-console
|
|
37
|
+
console.error(` TIMEOUT detected - Query exceeded time limit`);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// eslint-disable-next-line no-console
|
|
41
|
+
console.error(`OUT OF MEMORY detected - Query exceeded memory limit`);
|
|
42
|
+
}
|
|
43
|
+
// Analyze the failed query using CLUSTER_STATEMENTS_SUMMARY
|
|
44
|
+
await (0, sqlUtils_1.handleErrorsWithPlan)(forgeSqlOperation, queryDuration, errorType);
|
|
45
|
+
}
|
|
18
46
|
/**
|
|
19
47
|
* Creates a proxy for the forgeDriver that injects SQL hints and handles query analysis
|
|
20
48
|
* @param forgeSqlOperation - The ForgeSQL operation instance
|
|
@@ -36,26 +64,9 @@ function createForgeDriverProxy(forgeSqlOperation, options, logRawSqlQuery) {
|
|
|
36
64
|
return await (0, forgeDriver_1.forgeDriver)(modifiedQuery, params, method);
|
|
37
65
|
}
|
|
38
66
|
catch (error) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (isTimeoutError || isOutOfMemoryError) {
|
|
43
|
-
// Wait for CLUSTER_STATEMENTS_SUMMARY to be populated with our failed query data
|
|
44
|
-
await new Promise((resolve) => setTimeout(resolve, STATEMENTS_SUMMARY_DELAY_MS));
|
|
45
|
-
const queryEndTime = Date.now();
|
|
46
|
-
const queryDuration = queryEndTime - queryStartTime;
|
|
47
|
-
let errorType = "TIMEOUT";
|
|
48
|
-
if (isTimeoutError) {
|
|
49
|
-
// eslint-disable-next-line no-console
|
|
50
|
-
console.error(` TIMEOUT detected - Query exceeded time limit`);
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
// eslint-disable-next-line no-console
|
|
54
|
-
console.error(`OUT OF MEMORY detected - Query exceeded memory limit`);
|
|
55
|
-
errorType = "OOM";
|
|
56
|
-
}
|
|
57
|
-
// Analyze the failed query using CLUSTER_STATEMENTS_SUMMARY
|
|
58
|
-
await (0, sqlUtils_1.handleErrorsWithPlan)(forgeSqlOperation, queryDuration, errorType);
|
|
67
|
+
const { isTimeout, isOutOfMemory } = isQueryError(error);
|
|
68
|
+
if (isTimeout || isOutOfMemory) {
|
|
69
|
+
await handleQueryError(queryStartTime, forgeSqlOperation, isTimeout);
|
|
59
70
|
}
|
|
60
71
|
// Log SQL error details if requested
|
|
61
72
|
if (logRawSqlQuery) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forgeDriverProxy.js","sourceRoot":"","sources":["../../src/utils/forgeDriverProxy.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"forgeDriverProxy.js","sourceRoot":"","sources":["../../src/utils/forgeDriverProxy.ts"],"names":[],"mappings":";;AA6DA,wDA4CC;AAzGD,+CAA4C;AAC5C,yCAAsD;AAEtD,yCAAkD;AAElD;;GAEG;AACH,MAAM,iBAAiB,GAAG;IACxB,OAAO,EAAE,mBAAmB;IAC5B,mBAAmB,EAAE,IAAI;CACjB,CAAC;AAEX;;GAEG;AACH,MAAM,2BAA2B,GAAG,GAAG,CAAC;AAExC;;GAEG;AACH,SAAS,YAAY,CAAC,KAAU;IAC9B,MAAM,SAAS,GAAG,KAAK,EAAE,IAAI,KAAK,iBAAiB,CAAC,OAAO,CAAC;IAC5D,MAAM,aAAa,GAAG,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,KAAK,iBAAiB,CAAC,mBAAmB,CAAC;IAC7F,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,gBAAgB,CAC7B,cAAsB,EACtB,iBAAoC,EACpC,SAAkB;IAElB,iFAAiF;IACjF,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,2BAA2B,CAAC,CAAC,CAAC;IAEjF,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAChC,MAAM,aAAa,GAAG,YAAY,GAAG,cAAc,CAAC;IACpD,MAAM,SAAS,GAAsB,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;IAEnE,IAAI,SAAS,EAAE,CAAC;QACd,sCAAsC;QACtC,OAAO,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACjE,CAAC;SAAM,CAAC;QACN,sCAAsC;QACtC,OAAO,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;IACxE,CAAC;IAED,4DAA4D;IAC5D,MAAM,IAAA,+BAAoB,EAAC,iBAAiB,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,sBAAsB,CACpC,iBAAoC,EACpC,OAAkB,EAClB,cAAwB;IAExB,OAAO,KAAK,EACV,KAAa,EACb,MAAa,EACb,MAAyB,EAKxB,EAAE;QACH,kCAAkC;QAClC,MAAM,aAAa,GAAG,IAAA,yBAAc,EAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAErD,IAAI,OAAO,IAAI,cAAc,IAAI,aAAa,KAAK,KAAK,EAAE,CAAC;YACzD,sCAAsC;YACtC,OAAO,CAAC,KAAK,CAAC,uBAAuB,aAAa,EAAE,CAAC,CAAC;QACxD,CAAC;QAED,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAElC,IAAI,CAAC;YACH,wCAAwC;YACxC,OAAO,MAAM,IAAA,yBAAW,EAAC,aAAa,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEzD,IAAI,SAAS,IAAI,aAAa,EAAE,CAAC;gBAC/B,MAAM,gBAAgB,CAAC,cAAc,EAAE,iBAAiB,EAAE,SAAS,CAAC,CAAC;YACvE,CAAC;YAED,qCAAqC;YACrC,IAAI,cAAc,EAAE,CAAC;gBACnB,sCAAsC;gBACtC,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACtE,CAAC;YAED,8BAA8B;YAC9B,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlHints.d.ts","sourceRoot":"","sources":["../../src/utils/sqlHints.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,QAAQ,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"sqlHints.d.ts","sourceRoot":"","sources":["../../src/utils/sqlHints.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,QAAQ,GAAG,MAAM,CAqCtE"}
|
package/dist/utils/sqlHints.js
CHANGED
|
@@ -13,40 +13,30 @@ function injectSqlHints(query, hints) {
|
|
|
13
13
|
}
|
|
14
14
|
// Normalize the query for easier matching
|
|
15
15
|
const normalizedQuery = query.trim().toUpperCase();
|
|
16
|
-
//
|
|
16
|
+
// Map query types to their hints
|
|
17
|
+
const queryTypeMap = {
|
|
18
|
+
SELECT: hints.select,
|
|
19
|
+
INSERT: hints.insert,
|
|
20
|
+
UPDATE: hints.update,
|
|
21
|
+
DELETE: hints.delete,
|
|
22
|
+
};
|
|
23
|
+
// Find matching query type and get hints
|
|
17
24
|
let queryHints;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
queryHints = hints.update;
|
|
26
|
-
}
|
|
27
|
-
else if (normalizedQuery.startsWith("DELETE")) {
|
|
28
|
-
queryHints = hints.delete;
|
|
25
|
+
let queryPrefix = null;
|
|
26
|
+
for (const [type, typeHints] of Object.entries(queryTypeMap)) {
|
|
27
|
+
if (normalizedQuery.startsWith(type)) {
|
|
28
|
+
queryPrefix = type;
|
|
29
|
+
queryHints = typeHints;
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
29
32
|
}
|
|
30
33
|
// If no hints for this query type, return original query
|
|
31
|
-
if (!queryHints || queryHints.length === 0) {
|
|
34
|
+
if (!queryHints || queryHints.length === 0 || !queryPrefix) {
|
|
32
35
|
return query;
|
|
33
36
|
}
|
|
34
|
-
// Join all hints with spaces
|
|
37
|
+
// Join all hints with spaces and inject into query
|
|
35
38
|
const hintsString = queryHints.join(" ");
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return `SELECT /*+ ${hintsString} */ ${query.substring(6)}`;
|
|
39
|
-
}
|
|
40
|
-
else if (normalizedQuery.startsWith("INSERT")) {
|
|
41
|
-
return `INSERT /*+ ${hintsString} */ ${query.substring(6)}`;
|
|
42
|
-
}
|
|
43
|
-
else if (normalizedQuery.startsWith("UPDATE")) {
|
|
44
|
-
return `UPDATE /*+ ${hintsString} */ ${query.substring(6)}`;
|
|
45
|
-
}
|
|
46
|
-
else if (normalizedQuery.startsWith("DELETE")) {
|
|
47
|
-
return `DELETE /*+ ${hintsString} */ ${query.substring(6)}`;
|
|
48
|
-
}
|
|
49
|
-
// If no match found, return original query
|
|
50
|
-
return query;
|
|
39
|
+
const prefixLength = queryPrefix.length;
|
|
40
|
+
return `${queryPrefix} /*+ ${hintsString} */ ${query.substring(prefixLength)}`;
|
|
51
41
|
}
|
|
52
42
|
//# sourceMappingURL=sqlHints.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlHints.js","sourceRoot":"","sources":["../../src/utils/sqlHints.ts"],"names":[],"mappings":";;AAoBA,
|
|
1
|
+
{"version":3,"file":"sqlHints.js","sourceRoot":"","sources":["../../src/utils/sqlHints.ts"],"names":[],"mappings":";;AAoBA,wCAqCC;AA3CD;;;;;GAKG;AACH,SAAgB,cAAc,CAAC,KAAa,EAAE,KAAgB;IAC5D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,KAAK,CAAC;IACf,CAAC;IAED,0CAA0C;IAC1C,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAEnD,iCAAiC;IACjC,MAAM,YAAY,GAAyC;QACzD,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC;IAEF,yCAAyC;IACzC,IAAI,UAAgC,CAAC;IACrC,IAAI,WAAW,GAAkB,IAAI,CAAC;IAEtC,KAAK,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7D,IAAI,eAAe,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,WAAW,GAAG,IAAI,CAAC;YACnB,UAAU,GAAG,SAAS,CAAC;YACvB,MAAM;QACR,CAAC;IACH,CAAC;IAED,yDAAyD;IACzD,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAC3D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,mDAAmD;IACnD,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzC,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC;IACxC,OAAO,GAAG,WAAW,QAAQ,WAAW,OAAO,KAAK,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC;AACjF,CAAC"}
|
package/dist/utils/sqlUtils.d.ts
CHANGED
|
@@ -111,35 +111,6 @@ export declare function nextVal(sequenceName: string): number;
|
|
|
111
111
|
*/
|
|
112
112
|
export declare function printQueriesWithPlan(forgeSQLORM: ForgeSqlOperation, timeDiffMs: number, timeout?: number): Promise<void>;
|
|
113
113
|
export declare function handleErrorsWithPlan(forgeSQLORM: ForgeSqlOperation, timeDiffMs: number, type: "OOM" | "TIMEOUT"): Promise<void>;
|
|
114
|
-
/**
|
|
115
|
-
* Analyzes and logs slow queries from the last specified number of hours.
|
|
116
|
-
*
|
|
117
|
-
* This function queries the slow query system table to find queries that were executed
|
|
118
|
-
* within the specified time window and logs detailed performance information including:
|
|
119
|
-
* - SQL query text
|
|
120
|
-
* - Maximum memory usage (in MB)
|
|
121
|
-
* - Query execution time (in ms)
|
|
122
|
-
* - Execution count
|
|
123
|
-
* - Execution plan
|
|
124
|
-
*
|
|
125
|
-
* @param forgeSQLORM - The ForgeSQL operation instance for database access
|
|
126
|
-
* @param hours - Number of hours to look back for slow queries (e.g., 1 for last hour, 24 for last day)
|
|
127
|
-
* @param timeout - Optional timeout in milliseconds for the query execution (defaults to 1500ms)
|
|
128
|
-
*
|
|
129
|
-
* @example
|
|
130
|
-
* ```typescript
|
|
131
|
-
* // Analyze slow queries from the last hour
|
|
132
|
-
* await slowQueryPerHours(forgeSQLORM, 1);
|
|
133
|
-
*
|
|
134
|
-
* // Analyze slow queries from the last 24 hours with custom timeout
|
|
135
|
-
* await slowQueryPerHours(forgeSQLORM, 24, 3000);
|
|
136
|
-
*
|
|
137
|
-
* // Analyze slow queries from the last 6 hours
|
|
138
|
-
* await slowQueryPerHours(forgeSQLORM, 6);
|
|
139
|
-
* ```
|
|
140
|
-
*
|
|
141
|
-
* @throws Does not throw - errors are logged to console.debug instead
|
|
142
|
-
*/
|
|
143
114
|
export declare function slowQueryPerHours(forgeSQLORM: ForgeSqlOperation, hours: number, timeout?: number): Promise<string[]>;
|
|
144
115
|
/**
|
|
145
116
|
* Executes a promise with a timeout.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlUtils.d.ts","sourceRoot":"","sources":["../../src/utils/sqlUtils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sqlUtils.d.ts","sourceRoot":"","sources":["../../src/utils/sqlUtils.ts"],"names":[],"mappings":"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"}
|