@memberjunction/query-gen 5.29.0 → 5.30.1
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +35 -0
- package/dist/core/QueryDatabaseWriter.d.ts +5 -3
- package/dist/core/QueryDatabaseWriter.d.ts.map +1 -1
- package/dist/core/QueryDatabaseWriter.js +24 -24
- package/dist/core/QueryDatabaseWriter.js.map +1 -1
- package/package.json +10 -10
- package/src/core/QueryDatabaseWriter.ts +26 -26
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# @memberjunction/query-gen
|
|
2
2
|
|
|
3
|
+
## 5.30.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- @memberjunction/ai@5.30.1
|
|
8
|
+
- @memberjunction/ai-core-plus@5.30.1
|
|
9
|
+
- @memberjunction/aiengine@5.30.1
|
|
10
|
+
- @memberjunction/ai-prompts@5.30.1
|
|
11
|
+
- @memberjunction/ai-vectors-memory@5.30.1
|
|
12
|
+
- @memberjunction/core@5.30.1
|
|
13
|
+
- @memberjunction/core-entities@5.30.1
|
|
14
|
+
- @memberjunction/global@5.30.1
|
|
15
|
+
- @memberjunction/sqlserver-dataprovider@5.30.1
|
|
16
|
+
|
|
17
|
+
## 5.30.0
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- 216ddc3: Wrap sequential Save/Delete looops in atomic transcatoins (TransactionGroup client-side BeginTransaction/Commit/Rollback server-side)
|
|
22
|
+
- Updated dependencies [c2c5892]
|
|
23
|
+
- Updated dependencies [68bf87f]
|
|
24
|
+
- Updated dependencies [963f2df]
|
|
25
|
+
- Updated dependencies [4729398]
|
|
26
|
+
- Updated dependencies [b1f32a4]
|
|
27
|
+
- Updated dependencies [c199f3b]
|
|
28
|
+
- @memberjunction/aiengine@5.30.0
|
|
29
|
+
- @memberjunction/core-entities@5.30.0
|
|
30
|
+
- @memberjunction/core@5.30.0
|
|
31
|
+
- @memberjunction/ai-core-plus@5.30.0
|
|
32
|
+
- @memberjunction/ai-prompts@5.30.0
|
|
33
|
+
- @memberjunction/sqlserver-dataprovider@5.30.0
|
|
34
|
+
- @memberjunction/ai-vectors-memory@5.30.0
|
|
35
|
+
- @memberjunction/ai@5.30.0
|
|
36
|
+
- @memberjunction/global@5.30.0
|
|
37
|
+
|
|
3
38
|
## 5.29.0
|
|
4
39
|
|
|
5
40
|
### Patch Changes
|
|
@@ -15,13 +15,15 @@ export declare class QueryDatabaseWriter {
|
|
|
15
15
|
private categoryCache;
|
|
16
16
|
constructor();
|
|
17
17
|
/**
|
|
18
|
-
* Write validated queries to the database
|
|
18
|
+
* Write validated queries to the database atomically.
|
|
19
19
|
*
|
|
20
20
|
* Creates Query entities. QueryFields and QueryParameters are automatically
|
|
21
21
|
* extracted by MJQueryEntity.server.ts using AI analysis of the SQL template.
|
|
22
|
-
*
|
|
22
|
+
* That extraction happens asynchronously during the Save() operation.
|
|
23
23
|
*
|
|
24
|
-
*
|
|
24
|
+
* Wraps the whole batch in a single DB transaction — any save failure
|
|
25
|
+
* rolls back every query previously queued in this call, so callers
|
|
26
|
+
* see either all queries persisted or none.
|
|
25
27
|
*
|
|
26
28
|
* @param validatedQueries - Array of validated queries to write
|
|
27
29
|
* @param contextUser - User context for entity operations
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryDatabaseWriter.d.ts","sourceRoot":"","sources":["../../src/core/QueryDatabaseWriter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"QueryDatabaseWriter.d.ts","sourceRoot":"","sources":["../../src/core/QueryDatabaseWriter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAA2C,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAKzF,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7D;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,aAAa,CAAkC;;IAKvD;;;;;;;;;;;;;;OAcG;IACG,sBAAsB,CAC1B,gBAAgB,EAAE,cAAc,EAAE,EAClC,WAAW,EAAE,QAAQ,GACpB,OAAO,CAAC,WAAW,CAAC;IA4CvB;;;;OAIG;YACW,aAAa;IAmC3B;;;;;;;;;;OAUG;YACW,oBAAoB;CA8CnC"}
|
|
@@ -17,33 +17,31 @@ export class QueryDatabaseWriter {
|
|
|
17
17
|
// No config needed - category info comes from ValidatedQuery
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
|
-
* Write validated queries to the database
|
|
20
|
+
* Write validated queries to the database atomically.
|
|
21
21
|
*
|
|
22
22
|
* Creates Query entities. QueryFields and QueryParameters are automatically
|
|
23
23
|
* extracted by MJQueryEntity.server.ts using AI analysis of the SQL template.
|
|
24
|
-
*
|
|
24
|
+
* That extraction happens asynchronously during the Save() operation.
|
|
25
25
|
*
|
|
26
|
-
*
|
|
26
|
+
* Wraps the whole batch in a single DB transaction — any save failure
|
|
27
|
+
* rolls back every query previously queued in this call, so callers
|
|
28
|
+
* see either all queries persisted or none.
|
|
27
29
|
*
|
|
28
30
|
* @param validatedQueries - Array of validated queries to write
|
|
29
31
|
* @param contextUser - User context for entity operations
|
|
30
32
|
* @returns Write result with success status and per-query results
|
|
31
33
|
*/
|
|
32
34
|
async writeQueriesToDatabase(validatedQueries, contextUser) {
|
|
35
|
+
if (validatedQueries.length === 0) {
|
|
36
|
+
return { success: true, results: [] };
|
|
37
|
+
}
|
|
33
38
|
const md = new Metadata();
|
|
34
39
|
const results = [];
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
const provider = Metadata.Provider;
|
|
41
|
+
await provider.BeginTransaction();
|
|
42
|
+
try {
|
|
43
|
+
for (const vq of validatedQueries) {
|
|
39
44
|
const categoryId = await this.getCategoryId(vq.category, contextUser);
|
|
40
|
-
// Create Query entity ONLY (NO manual fields/params creation)
|
|
41
|
-
// MJQueryEntity.server.ts will automatically:
|
|
42
|
-
// - Detect Nunjucks syntax
|
|
43
|
-
// - Extract parameters using AI
|
|
44
|
-
// - Create QueryParameter records
|
|
45
|
-
// - Create QueryField records
|
|
46
|
-
// - Set UsesTemplate flag
|
|
47
45
|
const query = await md.GetEntityObject('MJ: Queries', contextUser);
|
|
48
46
|
query.NewRecord();
|
|
49
47
|
query.Name = vq.query.queryName;
|
|
@@ -54,20 +52,22 @@ export class QueryDatabaseWriter {
|
|
|
54
52
|
query.SQL = vq.query.sql;
|
|
55
53
|
query.OriginalSQL = vq.query.sql;
|
|
56
54
|
query.Status = 'Pending';
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
throw new Error(`Failed to save query: ${query.LatestResult?.Message}`);
|
|
55
|
+
if (!await query.Save()) {
|
|
56
|
+
throw new Error(`Failed to save query '${vq.query.queryName}': ${query.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
60
57
|
}
|
|
61
58
|
results.push(`✓ ${query.Name} (ID: ${query.ID}) - AI extraction queued`);
|
|
62
59
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
await provider.CommitTransaction();
|
|
61
|
+
return { success: true, results };
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
await provider.RollbackTransaction();
|
|
65
|
+
const message = extractErrorMessage(error, 'Database Write');
|
|
66
|
+
return {
|
|
67
|
+
success: false,
|
|
68
|
+
results: [`✗ Batch rolled back: ${message}`, ...results.map(r => r.replace('✓', '~'))]
|
|
69
|
+
};
|
|
66
70
|
}
|
|
67
|
-
return {
|
|
68
|
-
success: true,
|
|
69
|
-
results
|
|
70
|
-
};
|
|
71
71
|
}
|
|
72
72
|
/**
|
|
73
73
|
* Get or create category ID from QueryCategoryInfo
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryDatabaseWriter.js","sourceRoot":"","sources":["../../src/core/QueryDatabaseWriter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"QueryDatabaseWriter.js","sourceRoot":"","sources":["../../src/core/QueryDatabaseWriter.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/query-gen",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.30.1",
|
|
5
5
|
"description": "AI-powered generation of domain-specific SQL query templates with automatic testing, refinement, and metadata export",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -28,15 +28,15 @@
|
|
|
28
28
|
"author": "MemberJunction",
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@memberjunction/ai": "5.
|
|
32
|
-
"@memberjunction/ai-core-plus": "5.
|
|
33
|
-
"@memberjunction/aiengine": "5.
|
|
34
|
-
"@memberjunction/ai-prompts": "5.
|
|
35
|
-
"@memberjunction/ai-vectors-memory": "5.
|
|
36
|
-
"@memberjunction/core": "5.
|
|
37
|
-
"@memberjunction/core-entities": "5.
|
|
38
|
-
"@memberjunction/global": "5.
|
|
39
|
-
"@memberjunction/sqlserver-dataprovider": "5.
|
|
31
|
+
"@memberjunction/ai": "5.30.1",
|
|
32
|
+
"@memberjunction/ai-core-plus": "5.30.1",
|
|
33
|
+
"@memberjunction/aiengine": "5.30.1",
|
|
34
|
+
"@memberjunction/ai-prompts": "5.30.1",
|
|
35
|
+
"@memberjunction/ai-vectors-memory": "5.30.1",
|
|
36
|
+
"@memberjunction/core": "5.30.1",
|
|
37
|
+
"@memberjunction/core-entities": "5.30.1",
|
|
38
|
+
"@memberjunction/global": "5.30.1",
|
|
39
|
+
"@memberjunction/sqlserver-dataprovider": "5.30.1",
|
|
40
40
|
"chalk": "^5.6.2",
|
|
41
41
|
"commander": "^14.0.3",
|
|
42
42
|
"nunjucks": "^3.2.4",
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* of the SQL template during the Save() operation.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { Metadata, RunView, UserInfo } from '@memberjunction/core';
|
|
9
|
+
import { DatabaseProviderBase, Metadata, RunView, UserInfo } from '@memberjunction/core';
|
|
10
10
|
import {
|
|
11
11
|
MJQueryEntity,
|
|
12
12
|
MJQueryCategoryEntity
|
|
@@ -25,13 +25,15 @@ export class QueryDatabaseWriter {
|
|
|
25
25
|
// No config needed - category info comes from ValidatedQuery
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
|
-
* Write validated queries to the database
|
|
28
|
+
* Write validated queries to the database atomically.
|
|
29
29
|
*
|
|
30
30
|
* Creates Query entities. QueryFields and QueryParameters are automatically
|
|
31
31
|
* extracted by MJQueryEntity.server.ts using AI analysis of the SQL template.
|
|
32
|
-
*
|
|
32
|
+
* That extraction happens asynchronously during the Save() operation.
|
|
33
33
|
*
|
|
34
|
-
*
|
|
34
|
+
* Wraps the whole batch in a single DB transaction — any save failure
|
|
35
|
+
* rolls back every query previously queued in this call, so callers
|
|
36
|
+
* see either all queries persisted or none.
|
|
35
37
|
*
|
|
36
38
|
* @param validatedQueries - Array of validated queries to write
|
|
37
39
|
* @param contextUser - User context for entity operations
|
|
@@ -41,22 +43,19 @@ export class QueryDatabaseWriter {
|
|
|
41
43
|
validatedQueries: ValidatedQuery[],
|
|
42
44
|
contextUser: UserInfo
|
|
43
45
|
): Promise<WriteResult> {
|
|
46
|
+
if (validatedQueries.length === 0) {
|
|
47
|
+
return { success: true, results: [] };
|
|
48
|
+
}
|
|
49
|
+
|
|
44
50
|
const md = new Metadata();
|
|
45
51
|
const results: string[] = [];
|
|
52
|
+
const provider = Metadata.Provider as DatabaseProviderBase;
|
|
46
53
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
// Get or create the category for this query (with caching)
|
|
54
|
+
await provider.BeginTransaction();
|
|
55
|
+
try {
|
|
56
|
+
for (const vq of validatedQueries) {
|
|
51
57
|
const categoryId = await this.getCategoryId(vq.category, contextUser);
|
|
52
58
|
|
|
53
|
-
// Create Query entity ONLY (NO manual fields/params creation)
|
|
54
|
-
// MJQueryEntity.server.ts will automatically:
|
|
55
|
-
// - Detect Nunjucks syntax
|
|
56
|
-
// - Extract parameters using AI
|
|
57
|
-
// - Create QueryParameter records
|
|
58
|
-
// - Create QueryField records
|
|
59
|
-
// - Set UsesTemplate flag
|
|
60
59
|
const query = await md.GetEntityObject<MJQueryEntity>('MJ: Queries', contextUser);
|
|
61
60
|
query.NewRecord();
|
|
62
61
|
query.Name = vq.query.queryName;
|
|
@@ -68,22 +67,23 @@ export class QueryDatabaseWriter {
|
|
|
68
67
|
query.OriginalSQL = vq.query.sql;
|
|
69
68
|
query.Status = 'Pending';
|
|
70
69
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
throw new Error(`Failed to save query: ${query.LatestResult?.Message}`);
|
|
70
|
+
if (!await query.Save()) {
|
|
71
|
+
throw new Error(`Failed to save query '${vq.query.queryName}': ${query.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
74
72
|
}
|
|
75
73
|
|
|
76
74
|
results.push(`✓ ${query.Name} (ID: ${query.ID}) - AI extraction queued`);
|
|
77
|
-
|
|
78
|
-
} catch (error: unknown) {
|
|
79
|
-
results.push(`✗ ${vq.businessQuestion.userQuestion}: ${extractErrorMessage(error, 'Database Write')}`);
|
|
80
75
|
}
|
|
81
|
-
}
|
|
82
76
|
|
|
83
|
-
|
|
84
|
-
success: true,
|
|
85
|
-
|
|
86
|
-
|
|
77
|
+
await provider.CommitTransaction();
|
|
78
|
+
return { success: true, results };
|
|
79
|
+
} catch (error: unknown) {
|
|
80
|
+
await provider.RollbackTransaction();
|
|
81
|
+
const message = extractErrorMessage(error, 'Database Write');
|
|
82
|
+
return {
|
|
83
|
+
success: false,
|
|
84
|
+
results: [`✗ Batch rolled back: ${message}`, ...results.map(r => r.replace('✓', '~'))]
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
/**
|