forge-sql-orm 2.1.15 → 2.1.17
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 +194 -1
- package/dist/async/PrintQueryConsumer.d.ts +98 -0
- package/dist/async/PrintQueryConsumer.d.ts.map +1 -0
- package/dist/async/PrintQueryConsumer.js +89 -0
- package/dist/async/PrintQueryConsumer.js.map +1 -0
- package/dist/core/ForgeSQLQueryBuilder.d.ts +2 -3
- package/dist/core/ForgeSQLQueryBuilder.d.ts.map +1 -1
- package/dist/core/ForgeSQLQueryBuilder.js.map +1 -1
- package/dist/core/ForgeSQLSelectOperations.d.ts +2 -1
- package/dist/core/ForgeSQLSelectOperations.d.ts.map +1 -1
- package/dist/core/ForgeSQLSelectOperations.js.map +1 -1
- package/dist/core/Rovo.d.ts +40 -0
- package/dist/core/Rovo.d.ts.map +1 -1
- package/dist/core/Rovo.js +164 -138
- package/dist/core/Rovo.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/drizzle/extensions/additionalActions.d.ts.map +1 -1
- package/dist/lib/drizzle/extensions/additionalActions.js +72 -22
- package/dist/lib/drizzle/extensions/additionalActions.js.map +1 -1
- package/dist/utils/cacheTableUtils.d.ts +11 -0
- package/dist/utils/cacheTableUtils.d.ts.map +1 -0
- package/dist/utils/cacheTableUtils.js +450 -0
- package/dist/utils/cacheTableUtils.js.map +1 -0
- package/dist/utils/cacheUtils.d.ts.map +1 -1
- package/dist/utils/cacheUtils.js +3 -22
- package/dist/utils/cacheUtils.js.map +1 -1
- package/dist/utils/forgeDriver.d.ts.map +1 -1
- package/dist/utils/forgeDriver.js +5 -12
- package/dist/utils/forgeDriver.js.map +1 -1
- package/dist/utils/forgeDriverProxy.js +7 -5
- package/dist/utils/forgeDriverProxy.js.map +1 -1
- package/dist/utils/metadataContextUtils.d.ts +44 -4
- package/dist/utils/metadataContextUtils.d.ts.map +1 -1
- package/dist/utils/metadataContextUtils.js +155 -50
- package/dist/utils/metadataContextUtils.js.map +1 -1
- package/dist/utils/sqlUtils.d.ts +3 -1
- package/dist/utils/sqlUtils.d.ts.map +1 -1
- package/dist/utils/sqlUtils.js +264 -144
- package/dist/utils/sqlUtils.js.map +1 -1
- package/dist/webtriggers/applyMigrationsWebTrigger.js +1 -1
- package/package.json +14 -13
- package/src/async/PrintQueryConsumer.ts +114 -0
- package/src/core/ForgeSQLQueryBuilder.ts +2 -2
- package/src/core/ForgeSQLSelectOperations.ts +2 -1
- package/src/core/Rovo.ts +209 -167
- package/src/index.ts +2 -3
- package/src/lib/drizzle/extensions/additionalActions.ts +98 -42
- package/src/utils/cacheTableUtils.ts +511 -0
- package/src/utils/cacheUtils.ts +3 -25
- package/src/utils/forgeDriver.ts +5 -11
- package/src/utils/forgeDriverProxy.ts +9 -9
- package/src/utils/metadataContextUtils.ts +169 -52
- package/src/utils/sqlUtils.ts +372 -177
- package/src/webtriggers/applyMigrationsWebTrigger.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "forge-sql-orm",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.17",
|
|
4
4
|
"description": "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.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"homepage": "https://github.com/vzakharchenko/forge-sql-orm#readme",
|
|
@@ -25,25 +25,25 @@
|
|
|
25
25
|
"database"
|
|
26
26
|
],
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@eslint/js": "^9.39.
|
|
28
|
+
"@eslint/js": "^9.39.2",
|
|
29
29
|
"@types/luxon": "^3.7.1",
|
|
30
|
-
"@types/node": "^
|
|
31
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
32
|
-
"@typescript-eslint/parser": "^8.
|
|
33
|
-
"@vitest/coverage-v8": "^4.0.
|
|
34
|
-
"@vitest/ui": "^4.0.
|
|
35
|
-
"eslint": "^9.39.
|
|
30
|
+
"@types/node": "^25.0.3",
|
|
31
|
+
"@typescript-eslint/eslint-plugin": "^8.50.0",
|
|
32
|
+
"@typescript-eslint/parser": "^8.50.0",
|
|
33
|
+
"@vitest/coverage-v8": "^4.0.16",
|
|
34
|
+
"@vitest/ui": "^4.0.16",
|
|
35
|
+
"eslint": "^9.39.2",
|
|
36
36
|
"eslint-config-prettier": "^10.1.8",
|
|
37
37
|
"eslint-plugin-import": "^2.32.0",
|
|
38
38
|
"eslint-plugin-vitest": "^0.5.4",
|
|
39
39
|
"husky": "^9.1.7",
|
|
40
|
-
"knip": "^5.
|
|
40
|
+
"knip": "^5.74.0",
|
|
41
41
|
"patch-package": "^8.0.1",
|
|
42
|
-
"prettier": "^3.7.
|
|
42
|
+
"prettier": "^3.7.4",
|
|
43
43
|
"ts-node": "^10.9.2",
|
|
44
44
|
"typescript": "^5.9.3",
|
|
45
45
|
"uuid": "^13.0.0",
|
|
46
|
-
"vitest": "^4.0.
|
|
46
|
+
"vitest": "^4.0.16"
|
|
47
47
|
},
|
|
48
48
|
"license": "MIT",
|
|
49
49
|
"author": "Vasyl Zakharchenko",
|
|
@@ -71,13 +71,14 @@
|
|
|
71
71
|
"README.md"
|
|
72
72
|
],
|
|
73
73
|
"peerDependencies": {
|
|
74
|
-
"@forge/sql": "^3.0.
|
|
75
|
-
"drizzle-orm": "^0.
|
|
74
|
+
"@forge/sql": "^3.0.14",
|
|
75
|
+
"drizzle-orm": "^0.45.1"
|
|
76
76
|
},
|
|
77
77
|
"optionalDependencies": {
|
|
78
78
|
"@forge/kvs": "^1.2.0"
|
|
79
79
|
},
|
|
80
80
|
"dependencies": {
|
|
81
|
+
"@forge/events": "^2.0.14",
|
|
81
82
|
"luxon": "^3.7.2",
|
|
82
83
|
"node-sql-parser": "^5.3.13"
|
|
83
84
|
},
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { AsyncEvent } from "@forge/events";
|
|
2
|
+
import {
|
|
3
|
+
MetadataQueryOptions,
|
|
4
|
+
printDegradationQueries,
|
|
5
|
+
Statistic,
|
|
6
|
+
} from "../utils/metadataContextUtils";
|
|
7
|
+
import { ForgeSqlOperation } from "../core/ForgeSQLQueryBuilder";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Event payload for async query degradation analysis.
|
|
11
|
+
* Contains query performance statistics and metadata for analysis.
|
|
12
|
+
*/
|
|
13
|
+
export type AsyncEventPrintQuery = {
|
|
14
|
+
/** Total database execution time across all queries in milliseconds */
|
|
15
|
+
totalDbExecutionTime: number;
|
|
16
|
+
/** Total response size across all queries in bytes */
|
|
17
|
+
totalResponseSize: number;
|
|
18
|
+
/** Timestamp when the query execution started */
|
|
19
|
+
beginTime: Date;
|
|
20
|
+
/** Query analysis options with all fields set to defaults if not provided */
|
|
21
|
+
options: Required<MetadataQueryOptions>;
|
|
22
|
+
/** Array of query statistics including SQL, parameters, and execution metadata */
|
|
23
|
+
statistics: Statistic[];
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Consumer function for processing async query degradation events.
|
|
28
|
+
*
|
|
29
|
+
* This function is called by the Forge event system when a query degradation event
|
|
30
|
+
* is received from the queue. It processes the event and prints query performance
|
|
31
|
+
* analysis including execution plans for slow queries.
|
|
32
|
+
*
|
|
33
|
+
* The function logs a warning message with job ID, total DB time, query count, and
|
|
34
|
+
* start time to help correlate with the original resolver/service logs.
|
|
35
|
+
*
|
|
36
|
+
* @param forgeSQLORM - The ForgeSQL operation instance for database access
|
|
37
|
+
* @param event - The async event containing query degradation data
|
|
38
|
+
* @returns Promise that resolves when query analysis is complete
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```yaml
|
|
42
|
+
* # manifest.yml - Configure consumer for async query degradation analysis
|
|
43
|
+
* modules:
|
|
44
|
+
* consumer:
|
|
45
|
+
* - key: print-degradation-queries
|
|
46
|
+
* queue: degradationQueue
|
|
47
|
+
* function: handlerAsyncDegradation
|
|
48
|
+
* function:
|
|
49
|
+
* - key: handlerAsyncDegradation
|
|
50
|
+
* handler: index.handlerAsyncDegradation
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* // index.ts - Handler function that processes async events
|
|
56
|
+
* import { AsyncEvent } from "@forge/events";
|
|
57
|
+
* import { printDegradationQueriesConsumer } from "forge-sql-orm";
|
|
58
|
+
* import { FORGE_SQL_ORM } from "./utils/forgeSqlOrmUtils";
|
|
59
|
+
*
|
|
60
|
+
* export const handlerAsyncDegradation = (event: AsyncEvent) => {
|
|
61
|
+
* return printDegradationQueriesConsumer(FORGE_SQL_ORM, event);
|
|
62
|
+
* };
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* // Using async queue in resolver - Enable async processing
|
|
68
|
+
* resolver.define("fetch", async (req: Request) => {
|
|
69
|
+
* return await FORGE_SQL_ORM.executeWithMetadata(
|
|
70
|
+
* async () => {
|
|
71
|
+
* // ... your queries ...
|
|
72
|
+
* return await SQL_QUERY;
|
|
73
|
+
* },
|
|
74
|
+
* async (totalDbExecutionTime, totalResponseSize, printQueries) => {
|
|
75
|
+
* if (totalDbExecutionTime > 800) {
|
|
76
|
+
* await printQueries(); // Will queue for async processing
|
|
77
|
+
* }
|
|
78
|
+
* },
|
|
79
|
+
* { asyncQueueName: "degradationQueue" } // Enable async processing
|
|
80
|
+
* );
|
|
81
|
+
* });
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* // Log correlation - How to find related logs
|
|
87
|
+
* //
|
|
88
|
+
* // 1. In resolver/service log, you'll see:
|
|
89
|
+
* // [Performance Analysis] Query degradation event queued for async processing | Job ID: abc-123 | ...
|
|
90
|
+
* //
|
|
91
|
+
* // 2. In consumer log (handlerAsyncDegradation), search for the same Job ID:
|
|
92
|
+
* // [Performance Analysis] Processing query degradation event | Job ID: abc-123 | ...
|
|
93
|
+
* //
|
|
94
|
+
* // 3. To find all related logs, search logs for: "Job ID: abc-123"
|
|
95
|
+
* // This will show both the queuing event and the processing event
|
|
96
|
+
* //
|
|
97
|
+
* // Example log flow:
|
|
98
|
+
* // WARN resolver: [Performance Analysis] Query degradation event queued... | Job ID: abc-123
|
|
99
|
+
* // WARN handlerAsyncDegradation: [Performance Analysis] Processing query degradation event | Job ID: abc-123
|
|
100
|
+
* // WARN handlerAsyncDegradation: SQL: SELECT ... | Time: 3514 ms
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export async function printDegradationQueriesConsumer(
|
|
104
|
+
forgeSQLORM: ForgeSqlOperation,
|
|
105
|
+
event: AsyncEvent,
|
|
106
|
+
): Promise<void> {
|
|
107
|
+
const body: AsyncEventPrintQuery = event.body as AsyncEventPrintQuery;
|
|
108
|
+
body.beginTime = new Date(body.beginTime);
|
|
109
|
+
// eslint-disable-next-line no-console
|
|
110
|
+
console.warn(
|
|
111
|
+
`[Performance Analysis] Processing query degradation event | Job ID: ${event.jobId} | Total DB time: ${body.totalDbExecutionTime}ms | Queries: ${body.statistics.length} | Started: ${body.beginTime.toISOString()}`,
|
|
112
|
+
);
|
|
113
|
+
await printDegradationQueries(forgeSQLORM, body);
|
|
114
|
+
}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
customType,
|
|
7
7
|
MySqlSelectBuilder,
|
|
8
8
|
MySqlTable,
|
|
9
|
+
MySqlColumn,
|
|
9
10
|
} from "drizzle-orm/mysql-core";
|
|
10
11
|
import {
|
|
11
12
|
MySqlSelectDynamic,
|
|
@@ -56,7 +57,6 @@ import { SQLWrapper } from "drizzle-orm/sql/sql";
|
|
|
56
57
|
import type { MySqlQueryResultKind } from "drizzle-orm/mysql-core/session";
|
|
57
58
|
import type { WithBuilder } from "drizzle-orm/mysql-core/subquery";
|
|
58
59
|
import { WithSubquery } from "drizzle-orm/subquery";
|
|
59
|
-
import { MySqlColumn } from "drizzle-orm/mysql-core";
|
|
60
60
|
import { MetadataQueryOptions } from "../utils/metadataContextUtils";
|
|
61
61
|
|
|
62
62
|
/**
|
|
@@ -1025,7 +1025,7 @@ export interface SchemaSqlForgeSql {
|
|
|
1025
1025
|
* @returns {Promise<T[]>} A list of results as objects
|
|
1026
1026
|
* @throws {Error} If the query execution fails
|
|
1027
1027
|
*/
|
|
1028
|
-
executeRawSQL<T
|
|
1028
|
+
executeRawSQL<T>(query: string, params?: SqlParameters[]): Promise<T[]>;
|
|
1029
1029
|
|
|
1030
1030
|
/**
|
|
1031
1031
|
* Executes a raw SQL update query.
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
AnyMySqlSelectQueryBuilder,
|
|
5
5
|
MySqlSelectDynamic,
|
|
6
6
|
} from "drizzle-orm/mysql-core/query-builders/select.types";
|
|
7
|
+
import { SqlParameters } from "@forge/sql/out/sql-statement";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Class implementing SQL select operations for ForgeSQL ORM.
|
|
@@ -55,7 +56,7 @@ export class ForgeSQLSelectOperations implements SchemaSqlForgeSql {
|
|
|
55
56
|
* @param {SqlParameters[]} [params] - Optional SQL parameters
|
|
56
57
|
* @returns {Promise<T[]>} A list of results as objects
|
|
57
58
|
*/
|
|
58
|
-
async executeRawSQL<T
|
|
59
|
+
async executeRawSQL<T>(query: string, params?: SqlParameters[]): Promise<T[]> {
|
|
59
60
|
if (this.options.logRawSqlQuery) {
|
|
60
61
|
const paramsStr = params ? `, with params: ${JSON.stringify(params)}` : "";
|
|
61
62
|
// eslint-disable-next-line no-console
|