UNPKG

forge-sql-orm

Version:

Drizzle ORM integration for Atlassian @forge/sql. Provides a custom driver, schema migration, two levels of caching (local and global via @forge/kvs), optimistic locking, and query analysis.

70 lines 3.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createForgeDriverProxy = createForgeDriverProxy; const forgeDriver_1 = require("./forgeDriver"); const sqlHints_1 = require("./sqlHints"); const sqlUtils_1 = require("./sqlUtils"); /** * Error codes and constants for query analysis */ const QUERY_ERROR_CODES = { TIMEOUT: "SQL_QUERY_TIMEOUT", OUT_OF_MEMORY_ERRNO: 8175, }; /** * Delay to wait for CLUSTER_STATEMENTS_SUMMARY to be populated */ const STATEMENTS_SUMMARY_DELAY_MS = 200; /** * Creates a proxy for the forgeDriver that injects SQL hints and handles query analysis * @param forgeSqlOperation - The ForgeSQL operation instance * @param options - SQL hints to inject * @param logRawSqlQuery - Whether to log raw SQL queries * @returns A proxied version of the forgeDriver */ function createForgeDriverProxy(forgeSqlOperation, options, logRawSqlQuery) { return async (query, params, method) => { // Inject SQL hints into the query const modifiedQuery = (0, sqlHints_1.injectSqlHints)(query, options); if (options && logRawSqlQuery && modifiedQuery !== query) { // eslint-disable-next-line no-console console.debug(`SQL Hints injected: ${modifiedQuery}`); } const queryStartTime = Date.now(); try { // Execute the query with injected hints return await (0, forgeDriver_1.forgeDriver)(modifiedQuery, params, method); } catch (error) { // Check if this is a timeout or out-of-memory error that we want to analyze const isTimeoutError = error.code === QUERY_ERROR_CODES.TIMEOUT; const isOutOfMemoryError = error?.context?.debug?.errno === QUERY_ERROR_CODES.OUT_OF_MEMORY_ERRNO; if (isTimeoutError || isOutOfMemoryError) { // Wait for CLUSTER_STATEMENTS_SUMMARY to be populated with our failed query data await new Promise((resolve) => setTimeout(resolve, STATEMENTS_SUMMARY_DELAY_MS)); const queryEndTime = Date.now(); const queryDuration = queryEndTime - queryStartTime; let errorType = "TIMEOUT"; if (isTimeoutError) { // eslint-disable-next-line no-console console.error(` TIMEOUT detected - Query exceeded time limit`); } else { // eslint-disable-next-line no-console console.error(`OUT OF MEMORY detected - Query exceeded memory limit`); errorType = "OOM"; } // Analyze the failed query using CLUSTER_STATEMENTS_SUMMARY await (0, sqlUtils_1.handleErrorsWithPlan)(forgeSqlOperation, queryDuration, errorType); } // Log SQL error details if requested if (logRawSqlQuery) { // eslint-disable-next-line no-console console.debug(`SQL Error Details:`, JSON.stringify(error, null, 2)); } // Re-throw the original error throw error; } }; } //# sourceMappingURL=forgeDriverProxy.js.map