@memberjunction/core-entities-server 6.2.0-edge.5 → 6.2.0-edge.7
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 +155 -100
- package/dist/custom/MJAIAgentExampleEntityServer.server.d.ts +2 -0
- package/dist/custom/MJAIAgentExampleEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJAIAgentExampleEntityServer.server.js +8 -5
- package/dist/custom/MJAIAgentExampleEntityServer.server.js.map +1 -1
- package/dist/custom/MJAIAgentNoteEntityServer.server.d.ts +2 -0
- package/dist/custom/MJAIAgentNoteEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJAIAgentNoteEntityServer.server.js +8 -5
- package/dist/custom/MJAIAgentNoteEntityServer.server.js.map +1 -1
- package/dist/custom/MJAIAgentRelationshipEntityServer.server.d.ts +17 -0
- package/dist/custom/MJAIAgentRelationshipEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJAIAgentRelationshipEntityServer.server.js +71 -0
- package/dist/custom/MJAIAgentRelationshipEntityServer.server.js.map +1 -0
- package/dist/custom/MJAIAgentSessionEntityServer.server.d.ts +8 -39
- package/dist/custom/MJAIAgentSessionEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJAIAgentSessionEntityServer.server.js +44 -44
- package/dist/custom/MJAIAgentSessionEntityServer.server.js.map +1 -1
- package/dist/custom/MJAIAgentUserPolicyEntityServer.server.d.ts +23 -0
- package/dist/custom/MJAIAgentUserPolicyEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJAIAgentUserPolicyEntityServer.server.js +53 -0
- package/dist/custom/MJAIAgentUserPolicyEntityServer.server.js.map +1 -0
- package/dist/custom/MJAIPromptEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJAIPromptEntityServer.server.js +2 -1
- package/dist/custom/MJAIPromptEntityServer.server.js.map +1 -1
- package/dist/custom/MJBrandKitEntityServer.server.d.ts +14 -0
- package/dist/custom/MJBrandKitEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJBrandKitEntityServer.server.js +75 -0
- package/dist/custom/MJBrandKitEntityServer.server.js.map +1 -0
- package/dist/custom/MJCompanyIntegrationEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJCompanyIntegrationEntityServer.server.js +1 -0
- package/dist/custom/MJCompanyIntegrationEntityServer.server.js.map +1 -1
- package/dist/custom/MJComponentEntityServer.server.d.ts +11 -0
- package/dist/custom/MJComponentEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJComponentEntityServer.server.js +30 -2
- package/dist/custom/MJComponentEntityServer.server.js.map +1 -1
- package/dist/custom/MJConversationEntityServer.server.d.ts +13 -0
- package/dist/custom/MJConversationEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJConversationEntityServer.server.js +33 -0
- package/dist/custom/MJConversationEntityServer.server.js.map +1 -0
- package/dist/custom/MJDashboardEntityServer.server.d.ts +14 -0
- package/dist/custom/MJDashboardEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJDashboardEntityServer.server.js +38 -0
- package/dist/custom/MJDashboardEntityServer.server.js.map +1 -0
- package/dist/custom/MJDuplicateRunEntityServer.server.d.ts +34 -2
- package/dist/custom/MJDuplicateRunEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJDuplicateRunEntityServer.server.js +103 -23
- package/dist/custom/MJDuplicateRunEntityServer.server.js.map +1 -1
- package/dist/custom/MJEntityAlternateBaseViewEntityServer.server.d.ts +73 -0
- package/dist/custom/MJEntityAlternateBaseViewEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJEntityAlternateBaseViewEntityServer.server.js +391 -0
- package/dist/custom/MJEntityAlternateBaseViewEntityServer.server.js.map +1 -0
- package/dist/custom/MJEntityDocumentEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJEntityDocumentEntityServer.server.js +1 -0
- package/dist/custom/MJEntityDocumentEntityServer.server.js.map +1 -1
- package/dist/custom/MJEntityFieldPermissionEntityServer.server.d.ts +96 -22
- package/dist/custom/MJEntityFieldPermissionEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJEntityFieldPermissionEntityServer.server.js +239 -55
- package/dist/custom/MJEntityFieldPermissionEntityServer.server.js.map +1 -1
- package/dist/custom/MJListDetailEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJListDetailEntityServer.server.js +1 -0
- package/dist/custom/MJListDetailEntityServer.server.js.map +1 -1
- package/dist/custom/MJQueryEntityServer.server.d.ts +184 -46
- package/dist/custom/MJQueryEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJQueryEntityServer.server.js +505 -159
- package/dist/custom/MJQueryEntityServer.server.js.map +1 -1
- package/dist/custom/MJQuerySQLEntityServer.server.d.ts +15 -18
- package/dist/custom/MJQuerySQLEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJQuerySQLEntityServer.server.js +34 -42
- package/dist/custom/MJQuerySQLEntityServer.server.js.map +1 -1
- package/dist/custom/MJTagEntityServer.server.d.ts +2 -0
- package/dist/custom/MJTagEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJTagEntityServer.server.js +13 -7
- package/dist/custom/MJTagEntityServer.server.js.map +1 -1
- package/dist/custom/MJUserRoleEntityServer.server.d.ts +74 -7
- package/dist/custom/MJUserRoleEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJUserRoleEntityServer.server.js +206 -20
- package/dist/custom/MJUserRoleEntityServer.server.js.map +1 -1
- package/dist/custom/MJUserRoutineEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJUserRoutineEntityServer.server.js +8 -1
- package/dist/custom/MJUserRoutineEntityServer.server.js.map +1 -1
- package/dist/custom/MJUserViewEntityServer.server.d.ts +17 -1
- package/dist/custom/MJUserViewEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJUserViewEntityServer.server.js +95 -7
- package/dist/custom/MJUserViewEntityServer.server.js.map +1 -1
- package/dist/custom/MJVectorIndexEntityServer.server.d.ts +2 -0
- package/dist/custom/MJVectorIndexEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJVectorIndexEntityServer.server.js +33 -0
- package/dist/custom/MJVectorIndexEntityServer.server.js.map +1 -1
- package/dist/custom/anonymousOwnershipKeyGuard.d.ts +42 -0
- package/dist/custom/anonymousOwnershipKeyGuard.d.ts.map +1 -0
- package/dist/custom/anonymousOwnershipKeyGuard.js +36 -0
- package/dist/custom/anonymousOwnershipKeyGuard.js.map +1 -0
- package/dist/custom/approvalStamp.d.ts +37 -0
- package/dist/custom/approvalStamp.d.ts.map +1 -0
- package/dist/custom/approvalStamp.js +67 -0
- package/dist/custom/approvalStamp.js.map +1 -0
- package/dist/custom/fieldPermissionAccess.d.ts +31 -0
- package/dist/custom/fieldPermissionAccess.d.ts.map +1 -0
- package/dist/custom/fieldPermissionAccess.js +38 -0
- package/dist/custom/fieldPermissionAccess.js.map +1 -0
- package/dist/custom/fieldPermissionReconciler.d.ts.map +1 -1
- package/dist/custom/fieldPermissionReconciler.js +12 -2
- package/dist/custom/fieldPermissionReconciler.js.map +1 -1
- package/dist/custom/query-extraction/childRowWriter.d.ts +77 -0
- package/dist/custom/query-extraction/childRowWriter.d.ts.map +1 -0
- package/dist/custom/query-extraction/childRowWriter.js +277 -0
- package/dist/custom/query-extraction/childRowWriter.js.map +1 -0
- package/dist/custom/query-extraction/compositionTargets.d.ts +40 -0
- package/dist/custom/query-extraction/compositionTargets.d.ts.map +1 -0
- package/dist/custom/query-extraction/compositionTargets.js +99 -0
- package/dist/custom/query-extraction/compositionTargets.js.map +1 -0
- package/dist/custom/query-extraction/declared.d.ts +79 -0
- package/dist/custom/query-extraction/declared.d.ts.map +1 -0
- package/dist/custom/query-extraction/declared.js +91 -0
- package/dist/custom/query-extraction/declared.js.map +1 -0
- package/dist/custom/query-extraction/describeFacts.d.ts +40 -0
- package/dist/custom/query-extraction/describeFacts.d.ts.map +1 -0
- package/dist/custom/query-extraction/describeFacts.js +225 -0
- package/dist/custom/query-extraction/describeFacts.js.map +1 -0
- package/dist/custom/query-extraction/descriptionPass.d.ts +23 -0
- package/dist/custom/query-extraction/descriptionPass.d.ts.map +1 -0
- package/dist/custom/query-extraction/descriptionPass.js +95 -0
- package/dist/custom/query-extraction/descriptionPass.js.map +1 -0
- package/dist/custom/query-extraction/extractQuery.d.ts +25 -0
- package/dist/custom/query-extraction/extractQuery.d.ts.map +1 -0
- package/dist/custom/query-extraction/extractQuery.js +146 -0
- package/dist/custom/query-extraction/extractQuery.js.map +1 -0
- package/dist/custom/query-extraction/extractionTypes.d.ts +133 -0
- package/dist/custom/query-extraction/extractionTypes.d.ts.map +1 -0
- package/dist/custom/query-extraction/extractionTypes.js +2 -0
- package/dist/custom/query-extraction/extractionTypes.js.map +1 -0
- package/dist/custom/query-extraction/index.d.ts +16 -0
- package/dist/custom/query-extraction/index.d.ts.map +1 -1
- package/dist/custom/query-extraction/index.js +11 -1
- package/dist/custom/query-extraction/index.js.map +1 -1
- package/dist/custom/query-extraction/pipeline.d.ts +6 -2
- package/dist/custom/query-extraction/pipeline.d.ts.map +1 -1
- package/dist/custom/query-extraction/pipeline.js +21 -14
- package/dist/custom/query-extraction/pipeline.js.map +1 -1
- package/dist/custom/query-extraction/resolve.d.ts +7 -2
- package/dist/custom/query-extraction/resolve.d.ts.map +1 -1
- package/dist/custom/query-extraction/resolve.js +41 -20
- package/dist/custom/query-extraction/resolve.js.map +1 -1
- package/dist/custom/query-extraction/sourceBinding.d.ts +57 -0
- package/dist/custom/query-extraction/sourceBinding.d.ts.map +1 -0
- package/dist/custom/query-extraction/sourceBinding.js +104 -0
- package/dist/custom/query-extraction/sourceBinding.js.map +1 -0
- package/dist/custom/query-extraction/sync.d.ts +28 -4
- package/dist/custom/query-extraction/sync.d.ts.map +1 -1
- package/dist/custom/query-extraction/sync.js +147 -59
- package/dist/custom/query-extraction/sync.js.map +1 -1
- package/dist/custom/query-extraction/templateFacts.d.ts +62 -0
- package/dist/custom/query-extraction/templateFacts.d.ts.map +1 -0
- package/dist/custom/query-extraction/templateFacts.js +229 -0
- package/dist/custom/query-extraction/templateFacts.js.map +1 -0
- package/dist/custom/query-extraction/types.d.ts +8 -0
- package/dist/custom/query-extraction/types.d.ts.map +1 -1
- package/dist/custom/query-refresh/QueryExtractionService.d.ts +54 -0
- package/dist/custom/query-refresh/QueryExtractionService.d.ts.map +1 -0
- package/dist/custom/query-refresh/QueryExtractionService.js +207 -0
- package/dist/custom/query-refresh/QueryExtractionService.js.map +1 -0
- package/dist/custom/query-refresh/QueryRefreshExtractionServerOperation.d.ts +28 -0
- package/dist/custom/query-refresh/QueryRefreshExtractionServerOperation.d.ts.map +1 -0
- package/dist/custom/query-refresh/QueryRefreshExtractionServerOperation.js +106 -0
- package/dist/custom/query-refresh/QueryRefreshExtractionServerOperation.js.map +1 -0
- package/dist/custom/query-refresh/index.d.ts +14 -0
- package/dist/custom/query-refresh/index.d.ts.map +1 -0
- package/dist/custom/query-refresh/index.js +10 -0
- package/dist/custom/query-refresh/index.js.map +1 -0
- package/dist/custom/query-refresh/queryRebind.d.ts +33 -0
- package/dist/custom/query-refresh/queryRebind.d.ts.map +1 -0
- package/dist/custom/query-refresh/queryRebind.js +85 -0
- package/dist/custom/query-refresh/queryRebind.js.map +1 -0
- package/dist/custom/query-refresh/refreshAuthorization.d.ts +29 -0
- package/dist/custom/query-refresh/refreshAuthorization.d.ts.map +1 -0
- package/dist/custom/query-refresh/refreshAuthorization.js +66 -0
- package/dist/custom/query-refresh/refreshAuthorization.js.map +1 -0
- package/dist/custom/query-refresh/refreshFormat.d.ts +16 -0
- package/dist/custom/query-refresh/refreshFormat.d.ts.map +1 -0
- package/dist/custom/query-refresh/refreshFormat.js +67 -0
- package/dist/custom/query-refresh/refreshFormat.js.map +1 -0
- package/dist/custom/query-refresh/refreshOrder.d.ts +25 -0
- package/dist/custom/query-refresh/refreshOrder.d.ts.map +1 -0
- package/dist/custom/query-refresh/refreshOrder.js +95 -0
- package/dist/custom/query-refresh/refreshOrder.js.map +1 -0
- package/dist/custom/query-refresh/refreshSelection.d.ts +15 -0
- package/dist/custom/query-refresh/refreshSelection.d.ts.map +1 -0
- package/dist/custom/query-refresh/refreshSelection.js +99 -0
- package/dist/custom/query-refresh/refreshSelection.js.map +1 -0
- package/dist/custom/query-refresh/refreshTypes.d.ts +81 -0
- package/dist/custom/query-refresh/refreshTypes.d.ts.map +1 -0
- package/dist/custom/query-refresh/refreshTypes.js +5 -0
- package/dist/custom/query-refresh/refreshTypes.js.map +1 -0
- package/dist/custom/systemUserGuardState.d.ts +73 -0
- package/dist/custom/systemUserGuardState.d.ts.map +1 -0
- package/dist/custom/systemUserGuardState.js +161 -0
- package/dist/custom/systemUserGuardState.js.map +1 -0
- package/dist/custom/template-extraction/parser.js +5 -2
- package/dist/custom/template-extraction/parser.js.map +1 -1
- package/dist/custom/template-extraction/types.d.ts +1 -1
- package/dist/custom/template-extraction/types.d.ts.map +1 -1
- package/dist/custom/util.d.ts +8 -0
- package/dist/custom/util.d.ts.map +1 -1
- package/dist/custom/util.js +18 -1
- package/dist/custom/util.js.map +1 -1
- package/dist/engines/QueryEngineServer.d.ts +4 -1
- package/dist/engines/QueryEngineServer.d.ts.map +1 -1
- package/dist/engines/QueryEngineServer.js +10 -7
- package/dist/engines/QueryEngineServer.js.map +1 -1
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/package.json +30 -30
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"declared.js","sourceRoot":"","sources":["../../../src/custom/query-extraction/declared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { DescribedColumn } from "@memberjunction/generic-database-provider";
|
|
2
|
+
import type { QueryTemplate } from "@memberjunction/sql-parser";
|
|
3
|
+
import type { QueryExtractionInput, QueryParameterFact, QueryParameterType } from "./extractionTypes.js";
|
|
4
|
+
/** The output of every render of the query, as the database server described it. */
|
|
5
|
+
export interface DescribedOutput {
|
|
6
|
+
/** The union of the renders' columns by name (case-insensitive): the base render's first, in order. */
|
|
7
|
+
readonly Columns: readonly DescribedColumn[];
|
|
8
|
+
/** Columns only some renders produce: the render that first produced each, or one that did not return it. */
|
|
9
|
+
readonly BranchOnlyColumns: readonly string[];
|
|
10
|
+
/** Output names a single render returns more than once (case-insensitive). */
|
|
11
|
+
readonly DuplicateNames: readonly string[];
|
|
12
|
+
/** Why the output could not be described (a render or the server failed); `null` on success. */
|
|
13
|
+
readonly Failure: string | null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Renders the query with sample values, once for the base assignment and once per `{% if %}`
|
|
17
|
+
* toggled on its own (`QueryTemplate.BranchVariants`), and describes each render on the database
|
|
18
|
+
* server. Renders whose SQL repeats an earlier one are not described again. Plain SQL is
|
|
19
|
+
* described once, as written.
|
|
20
|
+
*/
|
|
21
|
+
export declare function DescribeQueryOutput(input: QueryExtractionInput, template: QueryTemplate, parameters: readonly QueryParameterFact[]): Promise<DescribedOutput>;
|
|
22
|
+
/**
|
|
23
|
+
* The statement without the semicolons before and after it (`;SELECT …;`): a statement described on
|
|
24
|
+
* its own (PostgreSQL prepares it) cannot carry them, though the query runs with them.
|
|
25
|
+
*/
|
|
26
|
+
export declare function WithoutStatementSemicolons(sql: string, input: Pick<QueryExtractionInput, 'Platform'>): string;
|
|
27
|
+
/**
|
|
28
|
+
* Why a render of the query may not run, as the run would refuse it: the first render (the base,
|
|
29
|
+
* then each `{% if %}` toggled) that is not a single read query or calls a function a query may not
|
|
30
|
+
* call. `null` when every render passes; a render that fails for another reason is left to
|
|
31
|
+
* {@link DescribeQueryOutput}, which reports it.
|
|
32
|
+
*/
|
|
33
|
+
export declare function FindUnsafeRender(input: QueryExtractionInput, template: QueryTemplate, parameters: readonly QueryParameterFact[]): string | null;
|
|
34
|
+
/**
|
|
35
|
+
* A truthy sample value of `type`, as a render takes it: the row's sample when it fits the type,
|
|
36
|
+
* otherwise a fixed value (`Sample`, `1`, `2024-01-01`, `true`, `["1"]`). An array's fixed element is
|
|
37
|
+
* a numeric string, so a loop over it can feed a string hole or a number argument alike.
|
|
38
|
+
*/
|
|
39
|
+
export declare function SampleValueFor(type: QueryParameterType, sample: string | null): string;
|
|
40
|
+
//# sourceMappingURL=describeFacts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describeFacts.d.ts","sourceRoot":"","sources":["../../../src/custom/query-extraction/describeFacts.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,KAAK,EAAe,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE7E,OAAO,KAAK,EAAuB,oBAAoB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE3H,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC5B,uGAAuG;IACvG,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IAC7C,6GAA6G;IAC7G,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,8EAA8E;IAC9E,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,gGAAgG;IAChG,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAYD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,kBAAkB,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAoBnK;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,oBAAoB,EAAE,UAAU,CAAC,GAAG,MAAM,CAS7G;AA6DD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,kBAAkB,EAAE,GAAG,MAAM,GAAG,IAAI,CAQ/I;AAyFD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAStF"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { IsQuerySafetyError, RenderPipeline, SafetyGate } from "@memberjunction/generic-database-provider";
|
|
2
|
+
import { GetDialect } from "@memberjunction/sql-dialect";
|
|
3
|
+
import { BranchVariantValues, LexSQL, SignificantTokens } from "@memberjunction/sql-parser";
|
|
4
|
+
import { NormalizeDefaultForType } from "./enrich.js";
|
|
5
|
+
/** The most branch renders described beyond the base, so a template with many blocks stays bounded. */
|
|
6
|
+
const MAX_VARIANT_RENDERS = 32;
|
|
7
|
+
/**
|
|
8
|
+
* Renders the query with sample values, once for the base assignment and once per `{% if %}`
|
|
9
|
+
* toggled on its own (`QueryTemplate.BranchVariants`), and describes each render on the database
|
|
10
|
+
* server. Renders whose SQL repeats an earlier one are not described again. Plain SQL is
|
|
11
|
+
* described once, as written.
|
|
12
|
+
*/
|
|
13
|
+
export async function DescribeQueryOutput(input, template, parameters) {
|
|
14
|
+
if (!input.Describe)
|
|
15
|
+
return failure('The database provider cannot describe a statement, so the output fields were not checked.');
|
|
16
|
+
const definitions = renderDefinitions(parameters, input.KnownParameters);
|
|
17
|
+
const renders = template.Tokens.HasTemplate ? renderAssignments(template) : [null];
|
|
18
|
+
const columns = [];
|
|
19
|
+
const branchOnly = [];
|
|
20
|
+
const duplicates = new Set();
|
|
21
|
+
const seenSQL = new Set();
|
|
22
|
+
for (const [index, values] of renders.entries()) {
|
|
23
|
+
const rendered = renderVariant(input, definitions, values);
|
|
24
|
+
if (rendered.Error !== null)
|
|
25
|
+
return failure(`Render ${index} could not be made: ${rendered.Error}`);
|
|
26
|
+
if (seenSQL.has(rendered.SQL))
|
|
27
|
+
continue;
|
|
28
|
+
seenSQL.add(rendered.SQL);
|
|
29
|
+
const described = await input.Describe(WithoutStatementSemicolons(rendered.SQL, input));
|
|
30
|
+
if (!described.Success)
|
|
31
|
+
return failure(`The database server could not describe the query: ${described.Diagnostics.join('; ') || 'no reason given'}`);
|
|
32
|
+
for (const name of duplicateNames(described.Columns))
|
|
33
|
+
duplicates.add(name);
|
|
34
|
+
if (index > 0)
|
|
35
|
+
noteMissingColumns(columns, described.Columns, index, branchOnly);
|
|
36
|
+
mergeColumns(columns, described.Columns, index, branchOnly);
|
|
37
|
+
}
|
|
38
|
+
return { Columns: columns, BranchOnlyColumns: branchOnly, DuplicateNames: [...duplicates], Failure: null };
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The statement without the semicolons before and after it (`;SELECT …;`): a statement described on
|
|
42
|
+
* its own (PostgreSQL prepares it) cannot carry them, though the query runs with them.
|
|
43
|
+
*/
|
|
44
|
+
export function WithoutStatementSemicolons(sql, input) {
|
|
45
|
+
const tokens = SignificantTokens(LexSQL(sql, GetDialect(input.Platform)));
|
|
46
|
+
let first = 0;
|
|
47
|
+
while (first < tokens.length && tokens[first].Kind === 'semicolon')
|
|
48
|
+
first++;
|
|
49
|
+
let last = tokens.length - 1;
|
|
50
|
+
while (last >= first && tokens[last].Kind === 'semicolon')
|
|
51
|
+
last--;
|
|
52
|
+
if (first > last)
|
|
53
|
+
return sql;
|
|
54
|
+
if (first === 0 && last === tokens.length - 1)
|
|
55
|
+
return sql;
|
|
56
|
+
return sql.substring(0, tokens[0].Start) + sql.substring(tokens[first].Start, tokens[last].End);
|
|
57
|
+
}
|
|
58
|
+
function failure(message) {
|
|
59
|
+
return { Columns: [], BranchOnlyColumns: [], DuplicateNames: [], Failure: message };
|
|
60
|
+
}
|
|
61
|
+
/** Appends the columns of render `index` not yet in the union. */
|
|
62
|
+
function mergeColumns(union, columns, index, branchOnly) {
|
|
63
|
+
const known = new Set(union.map(c => c.Name.toLowerCase()));
|
|
64
|
+
for (const column of columns) {
|
|
65
|
+
if (known.has(column.Name.toLowerCase()))
|
|
66
|
+
continue;
|
|
67
|
+
known.add(column.Name.toLowerCase());
|
|
68
|
+
union.push(column);
|
|
69
|
+
if (index > 0)
|
|
70
|
+
branchOnly.push(`${column.Name} (render ${index})`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** Notes the columns of the union so far that render `index` does not return (a column only the base branch returns). */
|
|
74
|
+
function noteMissingColumns(union, columns, index, branchOnly) {
|
|
75
|
+
const returned = new Set(columns.map(c => c.Name.toLowerCase()));
|
|
76
|
+
for (const column of union) {
|
|
77
|
+
if (!returned.has(column.Name.toLowerCase()))
|
|
78
|
+
branchOnly.push(`${column.Name} (not in render ${index})`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function duplicateNames(columns) {
|
|
82
|
+
const seen = new Set();
|
|
83
|
+
const repeated = new Set();
|
|
84
|
+
for (const column of columns) {
|
|
85
|
+
const key = column.Name.toLowerCase();
|
|
86
|
+
if (seen.has(key))
|
|
87
|
+
repeated.add(column.Name);
|
|
88
|
+
seen.add(key);
|
|
89
|
+
}
|
|
90
|
+
return [...repeated];
|
|
91
|
+
}
|
|
92
|
+
/** The base assignment, then one per `{% if %}` that parameter values can move to another branch. */
|
|
93
|
+
function renderAssignments(template) {
|
|
94
|
+
const set = template.BranchVariants().Value;
|
|
95
|
+
const toggles = set.Variants.filter(v => v.Toggle !== null && v.Satisfiable && v.Toggle.ToBranch !== null);
|
|
96
|
+
return [set.Base, ...toggles.slice(0, MAX_VARIANT_RENDERS).map(v => BranchVariantValues(set, v))];
|
|
97
|
+
}
|
|
98
|
+
/** Every parameter a render may be given: the template's, typed from the known rows where they say more. */
|
|
99
|
+
function renderDefinitions(parameters, known) {
|
|
100
|
+
const byName = new Map(known.map(k => [k.Name.toLowerCase(), k]));
|
|
101
|
+
const definitions = parameters.map(p => {
|
|
102
|
+
const row = byName.get(p.Name.toLowerCase());
|
|
103
|
+
return {
|
|
104
|
+
Name: p.Name,
|
|
105
|
+
Type: row?.Type ?? p.Type ?? 'string',
|
|
106
|
+
TypeKnown: row?.Type !== undefined || p.Type !== null,
|
|
107
|
+
IsRequired: p.IsRequired,
|
|
108
|
+
IsServerSet: row?.IsServerSet ?? false,
|
|
109
|
+
ValidationFilters: row?.ValidationFilters ?? null,
|
|
110
|
+
SampleValue: p.SampleValue ?? row?.SampleValue ?? null,
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
return definitions;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Why a render of the query may not run, as the run would refuse it: the first render (the base,
|
|
117
|
+
* then each `{% if %}` toggled) that is not a single read query or calls a function a query may not
|
|
118
|
+
* call. `null` when every render passes; a render that fails for another reason is left to
|
|
119
|
+
* {@link DescribeQueryOutput}, which reports it.
|
|
120
|
+
*/
|
|
121
|
+
export function FindUnsafeRender(input, template, parameters) {
|
|
122
|
+
const definitions = renderDefinitions(parameters, input.KnownParameters);
|
|
123
|
+
const renders = template.Tokens.HasTemplate ? renderAssignments(template) : [null];
|
|
124
|
+
for (const values of renders) {
|
|
125
|
+
const rendered = renderVariant(input, definitions, values);
|
|
126
|
+
if (rendered.Unsafe)
|
|
127
|
+
return rendered.Error;
|
|
128
|
+
}
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* A failed render. It is unsafe when the safety stage found a write or a forbidden call; SQL it
|
|
133
|
+
* refused only because it could not read it (a WITH clause written for another platform, whose own
|
|
134
|
+
* variant is saved later) is left to the describe and to the run-time gate, which fails closed.
|
|
135
|
+
*/
|
|
136
|
+
function renderFailure(e) {
|
|
137
|
+
return { SQL: '', Error: e instanceof Error ? e.message : String(e), Unsafe: IsQuerySafetyError(e) && !e.Unreadable };
|
|
138
|
+
}
|
|
139
|
+
/** Plain SQL, as written, once it passes the safety stage every rendered statement passes. */
|
|
140
|
+
function plainVariant(input) {
|
|
141
|
+
try {
|
|
142
|
+
SafetyGate.AssertSafeToExecute(input.SQL, GetDialect(input.Platform), false);
|
|
143
|
+
return { SQL: input.SQL, Error: null, Unsafe: false };
|
|
144
|
+
}
|
|
145
|
+
catch (e) {
|
|
146
|
+
return renderFailure(e);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/** One render's SQL for `values` (`null`: plain SQL, rendered as written), or why it failed. */
|
|
150
|
+
function renderVariant(input, definitions, values) {
|
|
151
|
+
if (values === null)
|
|
152
|
+
return plainVariant(input);
|
|
153
|
+
const callerValues = {};
|
|
154
|
+
const serverValues = {};
|
|
155
|
+
for (const definition of definitions) {
|
|
156
|
+
const value = renderValue(values[definition.Name], definition);
|
|
157
|
+
if (value === undefined)
|
|
158
|
+
continue;
|
|
159
|
+
(definition.IsServerSet ? serverValues : callerValues)[definition.Name] = value;
|
|
160
|
+
}
|
|
161
|
+
try {
|
|
162
|
+
const result = RenderPipeline.Run(input.SQL, {
|
|
163
|
+
Platform: input.Platform,
|
|
164
|
+
QueryID: input.QueryID ?? undefined,
|
|
165
|
+
ContextUser: input.ContextUser,
|
|
166
|
+
Parameters: callerValues,
|
|
167
|
+
ServerParameters: serverValues,
|
|
168
|
+
QueryInfo: { SQL: input.SQL, UsesTemplate: true, Parameters: definitions },
|
|
169
|
+
UsesTemplate: true,
|
|
170
|
+
OriginalSQL: input.SQL,
|
|
171
|
+
Dependencies: input.CompositionDependencies && input.CompositionDependencies.length > 0 ? [...input.CompositionDependencies] : undefined,
|
|
172
|
+
});
|
|
173
|
+
return { SQL: result.FinalSQL, Error: null, Unsafe: false };
|
|
174
|
+
}
|
|
175
|
+
catch (e) {
|
|
176
|
+
return renderFailure(e);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* The value a branch value gives a parameter in a render; `undefined` leaves it out. A compared
|
|
181
|
+
* literal that is not a value of the parameter's known type (text compared with a date) would fail
|
|
182
|
+
* the parameter's validation, so the type's sample stands in for it.
|
|
183
|
+
*/
|
|
184
|
+
function renderValue(branch, definition) {
|
|
185
|
+
if (!branch || branch.Kind === 'Absent')
|
|
186
|
+
return undefined;
|
|
187
|
+
if (branch.Kind === 'Literal') {
|
|
188
|
+
if (branch.Value === null)
|
|
189
|
+
return undefined;
|
|
190
|
+
const text = String(branch.Value);
|
|
191
|
+
if (!definition.TypeKnown || literalFitsType(text, definition.Type))
|
|
192
|
+
return text;
|
|
193
|
+
}
|
|
194
|
+
return definition.TypeKnown ? SampleValueFor(definition.Type, definition.SampleValue) : definition.SampleValue?.trim() || UNTYPED_SAMPLE;
|
|
195
|
+
}
|
|
196
|
+
/** Whether a compared literal, as text, is a value of `type`: a number, a date or a boolean; any text for the other types. */
|
|
197
|
+
function literalFitsType(text, type) {
|
|
198
|
+
switch (type) {
|
|
199
|
+
case 'number': return text.trim() !== '' && Number.isFinite(Number(text));
|
|
200
|
+
case 'date': return !isNaN(new Date(text).getTime());
|
|
201
|
+
case 'boolean': return text === 'true' || text === 'false';
|
|
202
|
+
default: return true;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* The sample of a parameter whose type nothing establishes: a numeric string, valid wherever such
|
|
207
|
+
* a value can go (a string, a number in arithmetic or a comparison, a composed number argument).
|
|
208
|
+
*/
|
|
209
|
+
const UNTYPED_SAMPLE = '1';
|
|
210
|
+
/**
|
|
211
|
+
* A truthy sample value of `type`, as a render takes it: the row's sample when it fits the type,
|
|
212
|
+
* otherwise a fixed value (`Sample`, `1`, `2024-01-01`, `true`, `["1"]`). An array's fixed element is
|
|
213
|
+
* a numeric string, so a loop over it can feed a string hole or a number argument alike.
|
|
214
|
+
*/
|
|
215
|
+
export function SampleValueFor(type, sample) {
|
|
216
|
+
const given = sample?.trim() ? sample : null;
|
|
217
|
+
switch (type) {
|
|
218
|
+
case 'number': return given !== null && !isNaN(Number(given)) && Number(given) !== 0 ? given : '1';
|
|
219
|
+
case 'date': return given !== null && !isNaN(new Date(given).getTime()) ? given : '2024-01-01';
|
|
220
|
+
case 'boolean': return 'true';
|
|
221
|
+
case 'array': return given !== null ? NormalizeDefaultForType(given, 'array') : '["1"]';
|
|
222
|
+
default: return given ?? 'Sample';
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=describeFacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describeFacts.js","sourceRoot":"","sources":["../../../src/custom/query-extraction/describeFacts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { IMetadataProvider, IRunViewProvider, UserInfo } from "@memberjunction/core";
|
|
2
|
+
/** What the description pass works on. */
|
|
3
|
+
export interface DescriptionPassRequest {
|
|
4
|
+
readonly QueryID: string;
|
|
5
|
+
readonly QueryName: string;
|
|
6
|
+
/** The query's SQL, as the prompt reads it. */
|
|
7
|
+
readonly SQL: string;
|
|
8
|
+
readonly Provider: IMetadataProvider & IRunViewProvider;
|
|
9
|
+
/** The user the rows are written as. */
|
|
10
|
+
readonly User: UserInfo;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Asks the LLM for descriptions of the query's fields and parameters whose description is still
|
|
14
|
+
* empty, and writes only those descriptions. It never sets a name, type, source or any other fact,
|
|
15
|
+
* and never replaces a description that is already there (authored, from a doc comment, or
|
|
16
|
+
* written earlier).
|
|
17
|
+
*
|
|
18
|
+
* Meant to run after the save's transaction commits (`RunAfterCommit`), so no LLM call is made
|
|
19
|
+
* while a transaction is open. A failure is recorded on the query: `ExtractionMessage` gets the
|
|
20
|
+
* reason and an `OK` status becomes `Warning`. Never throws.
|
|
21
|
+
*/
|
|
22
|
+
export declare function RunDescriptionPass(request: DescriptionPassRequest): Promise<void>;
|
|
23
|
+
//# sourceMappingURL=descriptionPass.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"descriptionPass.d.ts","sourceRoot":"","sources":["../../../src/custom/query-extraction/descriptionPass.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAc,iBAAiB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAmBtG,0CAA0C;AAC1C,MAAM,WAAW,sBAAsB;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,+CAA+C;IAC/C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,GAAG,gBAAgB,CAAC;IACxD,wCAAwC;IACxC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAWvF"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { AIEngine } from "@memberjunction/aiengine";
|
|
2
|
+
import { AIPromptRunner } from "@memberjunction/ai-prompts";
|
|
3
|
+
import { AIPromptParams } from "@memberjunction/ai-core-plus";
|
|
4
|
+
import { LogError, RunMaybeSerial } from "@memberjunction/core";
|
|
5
|
+
import { EscapeSQLString } from "@memberjunction/global";
|
|
6
|
+
const PROMPT_NAME = 'SQL Query Parameter Extraction';
|
|
7
|
+
const PROMPT_CATEGORY = 'MJ: System';
|
|
8
|
+
/**
|
|
9
|
+
* Asks the LLM for descriptions of the query's fields and parameters whose description is still
|
|
10
|
+
* empty, and writes only those descriptions. It never sets a name, type, source or any other fact,
|
|
11
|
+
* and never replaces a description that is already there (authored, from a doc comment, or
|
|
12
|
+
* written earlier).
|
|
13
|
+
*
|
|
14
|
+
* Meant to run after the save's transaction commits (`RunAfterCommit`), so no LLM call is made
|
|
15
|
+
* while a transaction is open. A failure is recorded on the query: `ExtractionMessage` gets the
|
|
16
|
+
* reason and an `OK` status becomes `Warning`. Never throws.
|
|
17
|
+
*/
|
|
18
|
+
export async function RunDescriptionPass(request) {
|
|
19
|
+
try {
|
|
20
|
+
const [fields, parameters] = await loadUndescribedRows(request);
|
|
21
|
+
if (fields.length === 0 && parameters.length === 0)
|
|
22
|
+
return;
|
|
23
|
+
const described = await askForDescriptions(request, fields, parameters);
|
|
24
|
+
const writes = [...applyDescriptions(fields, described.fields), ...applyDescriptions(parameters, described.parameters)];
|
|
25
|
+
const outcomes = await RunMaybeSerial(request.Provider, writes);
|
|
26
|
+
if (outcomes.some(ok => !ok))
|
|
27
|
+
throw new Error('some descriptions could not be saved');
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
await recordFailure(request, e instanceof Error ? e.message : String(e));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** The field and parameter rows whose description is empty, read from the database. */
|
|
34
|
+
async function loadUndescribedRows(request) {
|
|
35
|
+
const filter = `QueryID='${EscapeSQLString(request.QueryID)}' AND (Description IS NULL OR Description = '')`;
|
|
36
|
+
const load = async (entityName) => {
|
|
37
|
+
const result = await request.Provider.RunView({ EntityName: entityName, ExtraFilter: filter, ResultType: 'entity_object', BypassCache: true, IgnoreMaxRows: true }, request.User);
|
|
38
|
+
if (!result.Success)
|
|
39
|
+
throw new Error(`could not read the ${entityName}: ${result.ErrorMessage}`);
|
|
40
|
+
return result.Results ?? [];
|
|
41
|
+
};
|
|
42
|
+
return Promise.all([load('MJ: Query Fields'), load('MJ: Query Parameters')]);
|
|
43
|
+
}
|
|
44
|
+
async function askForDescriptions(request, fields, parameters) {
|
|
45
|
+
await AIEngine.Instance.Config(false, request.User, request.Provider);
|
|
46
|
+
const prompt = AIEngine.Instance.Prompts.find(p => p.Name === PROMPT_NAME && p.Category === PROMPT_CATEGORY);
|
|
47
|
+
if (!prompt)
|
|
48
|
+
throw new Error(`the prompt "${PROMPT_NAME}" was not found`);
|
|
49
|
+
const params = new AIPromptParams();
|
|
50
|
+
params.prompt = prompt;
|
|
51
|
+
params.contextUser = request.User;
|
|
52
|
+
params.data = {
|
|
53
|
+
templateText: request.SQL,
|
|
54
|
+
fields: fields.map(f => ({ name: f.Name, type: f.SQLFullType, source: f.SourceEntityField ?? f.SourceObjectName ?? null, isComputed: f.IsComputed })),
|
|
55
|
+
parameters: parameters.map(p => ({ name: p.Name, type: p.Type, isRequired: p.IsRequired === true })),
|
|
56
|
+
};
|
|
57
|
+
const result = await new AIPromptRunner().ExecutePrompt(params);
|
|
58
|
+
if (!result.success || !result.result)
|
|
59
|
+
throw new Error(result.errorMessage || 'the prompt returned no result');
|
|
60
|
+
return result.result;
|
|
61
|
+
}
|
|
62
|
+
/** Writes for the rows the result describes; a row whose description was filled meanwhile is left alone. */
|
|
63
|
+
function applyDescriptions(rows, described) {
|
|
64
|
+
const byName = new Map((described ?? []).filter(d => typeof d?.description === 'string' && d.description.trim()).map(d => [String(d.name).toLowerCase(), d.description.trim()]));
|
|
65
|
+
const writes = [];
|
|
66
|
+
for (const row of rows) {
|
|
67
|
+
const description = byName.get(row.Name.toLowerCase());
|
|
68
|
+
if (!description)
|
|
69
|
+
continue;
|
|
70
|
+
row.Description = description;
|
|
71
|
+
if ('SQLFullType' in row && row.DetectionMethod === 'Database')
|
|
72
|
+
row.DetectionMethod = 'AI';
|
|
73
|
+
writes.push(() => row.Save());
|
|
74
|
+
}
|
|
75
|
+
return writes;
|
|
76
|
+
}
|
|
77
|
+
/** Records a failed pass on the query: the reason in `ExtractionMessage`, and `OK` raised to `Warning`. */
|
|
78
|
+
async function recordFailure(request, reason) {
|
|
79
|
+
try {
|
|
80
|
+
const query = await request.Provider.GetEntityObject('MJ: Queries', request.User);
|
|
81
|
+
if (!await query.Load(request.QueryID))
|
|
82
|
+
return;
|
|
83
|
+
const line = `The LLM description pass failed: ${reason.trim().replace(/\.+$/, '')}. Empty descriptions were left empty.`;
|
|
84
|
+
query.ExtractionMessage = query.ExtractionMessage ? `${query.ExtractionMessage}\n${line}` : line;
|
|
85
|
+
if (query.ExtractionStatus === 'OK' || query.ExtractionStatus === null)
|
|
86
|
+
query.ExtractionStatus = 'Warning';
|
|
87
|
+
if (!await query.Save({ SkipEntityAIActions: true })) {
|
|
88
|
+
LogError(`[QueryExtraction] Could not record the description-pass failure on query "${request.QueryName}": ${query.LatestResult?.CompleteMessage}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
LogError(`[QueryExtraction] Could not record the description-pass failure on query "${request.QueryName}": ${e instanceof Error ? e.message : String(e)}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=descriptionPass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"descriptionPass.js","sourceRoot":"","sources":["../../../src/custom/query-extraction/descriptionPass.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DatabasePlatform } from "@memberjunction/core";
|
|
2
|
+
import type { QueryExtractionInput, QueryExtractionResult } from "./extractionTypes.js";
|
|
3
|
+
/**
|
|
4
|
+
* Establishes a query's facts from its SQL and the database server, without writing anything:
|
|
5
|
+
*
|
|
6
|
+
* - from MJ's parser: whether it is a template, its parameters (with composition pass-throughs),
|
|
7
|
+
* its compositions, the entities it reads, its doc comments and the save-time rules;
|
|
8
|
+
* - from the server: its output columns (name, order, exact type, nullability, source), for the
|
|
9
|
+
* base render and every branch render, mapped through MJ metadata.
|
|
10
|
+
*
|
|
11
|
+
* In `Save` mode a save-time rule error or a repeated output name refuses the save
|
|
12
|
+
* (`Refusal`); in `Refresh` mode they are recorded with status `Error`. An external-data-source
|
|
13
|
+
* query is not described (`Skipped`); a describe failure keeps the stored fields (`Error`). A
|
|
14
|
+
* query that reads a table named by a template parameter is not described either: its output
|
|
15
|
+
* depends on the arguments, so its stored (declared) fields are kept and a note says why.
|
|
16
|
+
*/
|
|
17
|
+
export declare function ComputeQueryExtraction(input: QueryExtractionInput): Promise<QueryExtractionResult>;
|
|
18
|
+
/** Why the fields of a query that reads a parameter-named table are not taken from a describe. */
|
|
19
|
+
export declare const PARAMETER_NAMED_SOURCE_NOTE: string;
|
|
20
|
+
/**
|
|
21
|
+
* The hash of the SQL the child rows are extracted from: SHA-256 (hex) of the dialect key and
|
|
22
|
+
* the platform SQL, so the same text on another platform hashes differently.
|
|
23
|
+
*/
|
|
24
|
+
export declare function ExtractionSQLHash(sql: string, platform: DatabasePlatform): string;
|
|
25
|
+
//# sourceMappingURL=extractQuery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractQuery.d.ts","sourceRoot":"","sources":["../../../src/custom/query-extraction/extractQuery.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAO7D,OAAO,KAAK,EACR,oBAAoB,EACpB,qBAAqB,EAGxB,MAAM,mBAAmB,CAAC;AAS3B;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAsBxG;AAED,kGAAkG;AAClG,eAAO,MAAM,2BAA2B,QAC4E,CAAC;AAErH;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAEjF"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { AnalyzeQueryTemplate, DescribeDiagnostic } from "./templateFacts.js";
|
|
3
|
+
import { DescribeQueryOutput, FindUnsafeRender } from "./describeFacts.js";
|
|
4
|
+
import { BindColumnSource, EntityObjectIndex } from "./sourceBinding.js";
|
|
5
|
+
/**
|
|
6
|
+
* Establishes a query's facts from its SQL and the database server, without writing anything:
|
|
7
|
+
*
|
|
8
|
+
* - from MJ's parser: whether it is a template, its parameters (with composition pass-throughs),
|
|
9
|
+
* its compositions, the entities it reads, its doc comments and the save-time rules;
|
|
10
|
+
* - from the server: its output columns (name, order, exact type, nullability, source), for the
|
|
11
|
+
* base render and every branch render, mapped through MJ metadata.
|
|
12
|
+
*
|
|
13
|
+
* In `Save` mode a save-time rule error or a repeated output name refuses the save
|
|
14
|
+
* (`Refusal`); in `Refresh` mode they are recorded with status `Error`. An external-data-source
|
|
15
|
+
* query is not described (`Skipped`); a describe failure keeps the stored fields (`Error`). A
|
|
16
|
+
* query that reads a table named by a template parameter is not described either: its output
|
|
17
|
+
* depends on the arguments, so its stored (declared) fields are kept and a note says why.
|
|
18
|
+
*/
|
|
19
|
+
export async function ComputeQueryExtraction(input) {
|
|
20
|
+
const analysis = AnalyzeQueryTemplate(input);
|
|
21
|
+
const findings = { Errors: [], Warnings: [], Notes: [] };
|
|
22
|
+
const refusal = saveRefusal(input, analysis.Errors.map(d => DescribeDiagnostic(d, input.SQL)), analysis.DuplicateOutputNames);
|
|
23
|
+
if (refusal)
|
|
24
|
+
return resultOf(input, analysis, null, findings, refusal);
|
|
25
|
+
recordAnalysis(input, analysis, findings);
|
|
26
|
+
const unsafe = input.IsExternal ? null : FindUnsafeRender(input, analysis.Template, analysis.Parameters);
|
|
27
|
+
if (unsafe !== null)
|
|
28
|
+
return unsafeResult(input, analysis, findings, unsafe);
|
|
29
|
+
if (input.IsExternal) {
|
|
30
|
+
return { ...resultOf(input, analysis, null, findings, null), Entities: null, Status: 'Skipped',
|
|
31
|
+
Messages: ['The query reads an external data source, which the database server cannot describe; its fields and entities were left as they are.', ...messagesOf(findings)] };
|
|
32
|
+
}
|
|
33
|
+
if (analysis.ReadsParameterNamedSource) {
|
|
34
|
+
findings.Notes.push(PARAMETER_NAMED_SOURCE_NOTE);
|
|
35
|
+
return resultOf(input, analysis, null, findings, null);
|
|
36
|
+
}
|
|
37
|
+
const output = await DescribeQueryOutput(input, analysis.Template, analysis.Parameters);
|
|
38
|
+
const outputRefusal = saveRefusal(input, [], output.DuplicateNames);
|
|
39
|
+
if (outputRefusal)
|
|
40
|
+
return resultOf(input, analysis, null, findings, outputRefusal);
|
|
41
|
+
recordOutput(output, analysis, findings);
|
|
42
|
+
const fields = output.Failure === null ? fieldFacts(output.Columns, analysis, input, findings) : null;
|
|
43
|
+
return resultOf(input, analysis, fields, findings, null);
|
|
44
|
+
}
|
|
45
|
+
/** Why the fields of a query that reads a parameter-named table are not taken from a describe. */
|
|
46
|
+
export const PARAMETER_NAMED_SOURCE_NOTE = 'The query reads a table or view named by a template parameter, so its output columns depend on the arguments ' +
|
|
47
|
+
'and no sample render describes them; its fields were left as they are (declare them in the query\'s metadata).';
|
|
48
|
+
/**
|
|
49
|
+
* The hash of the SQL the child rows are extracted from: SHA-256 (hex) of the dialect key and
|
|
50
|
+
* the platform SQL, so the same text on another platform hashes differently.
|
|
51
|
+
*/
|
|
52
|
+
export function ExtractionSQLHash(sql, platform) {
|
|
53
|
+
return createHash('sha256').update(`${platform}\n${sql}`).digest('hex');
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* A query a render of which may not run: a new or edited one is refused; a refresh records the
|
|
57
|
+
* reason as an error and keeps the stored fields. Nothing is described, so the database server is
|
|
58
|
+
* never handed the statement.
|
|
59
|
+
*/
|
|
60
|
+
function unsafeResult(input, analysis, findings, reason) {
|
|
61
|
+
const refusal = saveRefusal(input, [reason], []);
|
|
62
|
+
if (refusal)
|
|
63
|
+
return resultOf(input, analysis, null, findings, refusal);
|
|
64
|
+
findings.Errors.push(`${reason} The stored fields were left as they are.`);
|
|
65
|
+
return resultOf(input, analysis, null, findings, null);
|
|
66
|
+
}
|
|
67
|
+
/** Why a new or edited query must be refused; `null` when it may be saved or this is a refresh. */
|
|
68
|
+
function saveRefusal(input, errors, duplicates) {
|
|
69
|
+
const reasons = [...errors];
|
|
70
|
+
if (duplicates.length > 0)
|
|
71
|
+
reasons.push(duplicateMessage(duplicates));
|
|
72
|
+
if (input.Mode !== 'Save' || reasons.length === 0)
|
|
73
|
+
return null;
|
|
74
|
+
return `Query "${input.QueryName}" was not saved:\n${reasons.join('\n')}`;
|
|
75
|
+
}
|
|
76
|
+
function duplicateMessage(duplicates) {
|
|
77
|
+
return `The query returns more than one column named ${duplicates.map(d => `"${d}"`).join(', ')} (names compare without case). ` +
|
|
78
|
+
'Give each output column its own name, for example with an alias.';
|
|
79
|
+
}
|
|
80
|
+
/** Records what the template analysis found: refresh-mode rule errors, warnings, unread facts, orphaned authored parameters. */
|
|
81
|
+
function recordAnalysis(input, analysis, findings) {
|
|
82
|
+
findings.Errors.push(...analysis.Errors.map(d => DescribeDiagnostic(d, input.SQL)));
|
|
83
|
+
if (analysis.DuplicateOutputNames.length > 0)
|
|
84
|
+
findings.Errors.push(duplicateMessage(analysis.DuplicateOutputNames));
|
|
85
|
+
findings.Warnings.push(...analysis.Warnings.map(d => DescribeDiagnostic(d, input.SQL)), ...analysis.Notes);
|
|
86
|
+
const used = new Set(analysis.Parameters.map(p => p.Name.toLowerCase()));
|
|
87
|
+
for (const known of input.KnownParameters) {
|
|
88
|
+
if (known.IsAuthored && !used.has(known.Name.toLowerCase())) {
|
|
89
|
+
findings.Warnings.push(`The authored parameter "${known.Name}" is not used by the SQL. It is kept, and a value passed for it is accepted and ignored.`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/** Records the describe outcome: a failure, refresh-mode duplicates the parser did not already report, branch-only columns. */
|
|
94
|
+
function recordOutput(output, analysis, findings) {
|
|
95
|
+
if (output.Failure !== null)
|
|
96
|
+
findings.Errors.push(`${output.Failure.trim().replace(/[.;]?$/, '.')} The stored fields were left as they are.`);
|
|
97
|
+
const reported = new Set(analysis.DuplicateOutputNames.map(n => n.toLowerCase()));
|
|
98
|
+
const duplicates = output.DuplicateNames.filter(n => !reported.has(n.toLowerCase()));
|
|
99
|
+
if (duplicates.length > 0)
|
|
100
|
+
findings.Errors.push(duplicateMessage(duplicates));
|
|
101
|
+
if (output.BranchOnlyColumns.length > 0) {
|
|
102
|
+
findings.Notes.push(`Columns only some branches of the template return: ${output.BranchOnlyColumns.join(', ')}.`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** The field facts of the described output, in order; unnamed columns are skipped and reported. */
|
|
106
|
+
function fieldFacts(columns, analysis, input, findings) {
|
|
107
|
+
const index = new EntityObjectIndex(input.Entities);
|
|
108
|
+
const facts = [];
|
|
109
|
+
for (const column of columns) {
|
|
110
|
+
if (column.Name.trim().length === 0) {
|
|
111
|
+
findings.Warnings.push(`Output column ${column.Ordinal} has no name, so it has no field row. Give it an alias.`);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const source = BindColumnSource(column.Source, index);
|
|
115
|
+
facts.push({
|
|
116
|
+
Name: column.Name, Sequence: facts.length + 1, SQLBaseType: column.SQLBaseType, SQLFullType: column.SQLFullType,
|
|
117
|
+
IsNullable: column.IsNullable, IsComputed: column.IsComputed,
|
|
118
|
+
SourceEntityID: source.SourceEntityID, SourceEntityFieldID: source.SourceEntityFieldID,
|
|
119
|
+
SourceFieldName: source.SourceFieldName, SourceObjectName: source.SourceObjectName,
|
|
120
|
+
DocDescription: analysis.FieldDocs.get(column.Name.toLowerCase()) ?? null, SourceDescription: source.SourceDescription,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return facts;
|
|
124
|
+
}
|
|
125
|
+
function resultOf(input, analysis, fields, findings, refusal) {
|
|
126
|
+
return {
|
|
127
|
+
UsesTemplate: analysis.UsesTemplate,
|
|
128
|
+
Refusal: refusal,
|
|
129
|
+
Status: statusOf(findings),
|
|
130
|
+
Messages: messagesOf(findings),
|
|
131
|
+
Hash: ExtractionSQLHash(input.SQL, input.Platform),
|
|
132
|
+
Fields: fields,
|
|
133
|
+
Parameters: analysis.Parameters,
|
|
134
|
+
Entities: analysis.Entities,
|
|
135
|
+
Dependencies: analysis.Dependencies,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function statusOf(findings) {
|
|
139
|
+
if (findings.Errors.length > 0)
|
|
140
|
+
return 'Error';
|
|
141
|
+
return findings.Warnings.length > 0 ? 'Warning' : 'OK';
|
|
142
|
+
}
|
|
143
|
+
function messagesOf(findings) {
|
|
144
|
+
return [...findings.Errors, ...findings.Warnings, ...findings.Notes];
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=extractQuery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractQuery.js","sourceRoot":"","sources":["../../../src/custom/query-extraction/extractQuery.ts"],"names":[],"mappings":"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"}
|