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
JavaScript
;
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