@narrative.io/data-collaboration-sdk-ts 0.0.51 → 0.0.52
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/build/index.d.ts +4 -2
- package/build/index.js +2 -1
- package/build/nql/NQLParser.d.ts +87 -0
- package/build/nql/NQLParser.js +335 -0
- package/build/nql/SubstraitParser.d.ts +771 -0
- package/build/nql/SubstraitParser.js +788 -0
- package/build/nql/index.d.ts +12 -4
- package/build/nql/index.js +10 -0
- package/build/nql/types.d.ts +1229 -3
- package/build/nql/types.js +81 -1
- package/package.json +3 -2
package/build/index.d.ts
CHANGED
|
@@ -16,12 +16,14 @@ import { type PingStatus } from './ping/types';
|
|
|
16
16
|
import { type Product, ProductsApi } from './products';
|
|
17
17
|
import { CompanyInfoApi, type CompanyInfo } from './company-info';
|
|
18
18
|
import { InstallationsApi, type Installation } from './installations';
|
|
19
|
-
import { NqlApi, type NqlCompileResult, type
|
|
19
|
+
import { NqlApi, type NqlCompileResult, type NqlResult } from './nql';
|
|
20
20
|
import { DataStreamsApi, type DataStream } from './data-streams';
|
|
21
21
|
import { ForecastApi, type ForecastRequest, type ForecastResponse, type CostForecastRequest, type CostForecastResponse, type JobState } from './forecast';
|
|
22
22
|
import { ContractsApi, type ContractDetails, type CustomerContract, type PaymentMethod, type ContractRateView } from './contracts';
|
|
23
|
+
import { getNqlObject, buildNql } from './nql/NQLParser';
|
|
24
|
+
import type { Nql, NqlQueryInput } from './nql/types';
|
|
23
25
|
declare class NarrativeApi extends BaseApi {
|
|
24
26
|
}
|
|
25
27
|
interface NarrativeApi extends BaseApi, HealthCheckApi, DatasetApi, RosettaStoneApi, AttributeApi, PingApi, CompanyInfoApi, InstallationsApi, UploadsApi, ResourceApi, NqlApi, DataStreamsApi, ForecastApi, ContractsApi {
|
|
26
28
|
}
|
|
27
|
-
export { NarrativeApi, AttributeApi, HealthCheckApi, DatasetApi, PingApi, ProductsApi, CompanyInfoApi, InstallationsApi, UploadsApi, ResourceApi, NqlApi, DataStreamsApi, ForecastApi, ContractsApi, type Resource, type UploadsResponse, type PingStatus, type Attribute, type Environment, type Config, type ApiRecords, type Dataset, type HealthCheckResult, type SampleRecords, type DatasetTableSummary, type DatasetTableSummaryAPIResponse, type Product, type MonetaryAmount, type CompanyInfo, type Installation, type FilePerSnapshotResponse, type BucketCreationRequest, type UpdateAccessTypeRequest, type
|
|
29
|
+
export { NarrativeApi, AttributeApi, HealthCheckApi, DatasetApi, PingApi, ProductsApi, CompanyInfoApi, InstallationsApi, UploadsApi, ResourceApi, NqlApi, DataStreamsApi, ForecastApi, ContractsApi, type Resource, type UploadsResponse, type PingStatus, type Attribute, type Environment, type Config, type ApiRecords, type Dataset, type HealthCheckResult, type SampleRecords, type DatasetTableSummary, type DatasetTableSummaryAPIResponse, type Product, type MonetaryAmount, type CompanyInfo, type Installation, type FilePerSnapshotResponse, type BucketCreationRequest, type UpdateAccessTypeRequest, type NqlQueryInput, type NqlResult, type NqlCompileResult, type DataStream, type ForecastRequest, type ForecastResponse, type CostForecastRequest, type CostForecastResponse, type JobState, type ContractDetails, type CustomerContract, type PaymentMethod, type ContractRateView, type Nql, getNqlObject, buildNql };
|
package/build/index.js
CHANGED
|
@@ -14,7 +14,8 @@ import { NqlApi } from './nql';
|
|
|
14
14
|
import { DataStreamsApi } from './data-streams';
|
|
15
15
|
import { ForecastApi } from './forecast';
|
|
16
16
|
import { ContractsApi } from './contracts';
|
|
17
|
+
import { getNqlObject, buildNql } from './nql/NQLParser';
|
|
17
18
|
class NarrativeApi extends BaseApi {
|
|
18
19
|
}
|
|
19
20
|
applyMixins(NarrativeApi, [BaseApi, HealthCheckApi, DatasetApi, RosettaStoneApi, AttributeApi, PingApi, CompanyInfoApi, InstallationsApi, UploadsApi, ResourceApi, NqlApi, DataStreamsApi, ForecastApi, ContractsApi]);
|
|
20
|
-
export { NarrativeApi, AttributeApi, HealthCheckApi, DatasetApi, PingApi, ProductsApi, CompanyInfoApi, InstallationsApi, UploadsApi, ResourceApi, NqlApi, DataStreamsApi, ForecastApi, ContractsApi };
|
|
21
|
+
export { NarrativeApi, AttributeApi, HealthCheckApi, DatasetApi, PingApi, ProductsApi, CompanyInfoApi, InstallationsApi, UploadsApi, ResourceApi, NqlApi, DataStreamsApi, ForecastApi, ContractsApi, getNqlObject, buildNql };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { type Nql, type NqlBudget, type NqlField, type NqlPreSelectExpression, type NqlTable, type NqlWhere } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Retrieves the WHERE clause from the given NQL (Nested Query Language) string and returns a parsed NqlWhereClause object.
|
|
4
|
+
*
|
|
5
|
+
* @param {string} nql - The NQL string to extract the WHERE clause from.
|
|
6
|
+
* @returns {NqlWhereClause} - The parsed NqlWhereClause object representing the WHERE clause.
|
|
7
|
+
* @throws {Error} - Throws an error if no WHERE clause is found in the NQL string.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getWhere(nql: string): NqlWhere;
|
|
10
|
+
/**
|
|
11
|
+
* Retrieves the tables from the given NQL (Nested Query Language) string and returns an array of parsed NqlTable objects.
|
|
12
|
+
*
|
|
13
|
+
* @param {string} nql - The NQL string to extract the tables from.
|
|
14
|
+
* @returns {NqlTable[]} - An array of parsed NqlTable objects representing the tables.
|
|
15
|
+
* @throws {Error} - Throws an error if no FROM clause is found in the NQL string.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getFrom(nql: string): NqlTable[];
|
|
18
|
+
/**
|
|
19
|
+
* Parses the pre-select expression from the given NQL (Natural Query Language) string.
|
|
20
|
+
*
|
|
21
|
+
* @function getPreSelect
|
|
22
|
+
* @param {string} nql - The NQL string to parse.
|
|
23
|
+
* @returns {NqlPreSelectExpression | undefined} - The parsed pre-select expression object, or `undefined` if no valid pre-select expression is found.
|
|
24
|
+
* @throws {Error} If the NQL string is invalid.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getPreSelect(nql: string): NqlPreSelectExpression;
|
|
27
|
+
/**
|
|
28
|
+
* Builds a pre-select expression for an NQL (Natural Query Language) query based on the provided pre-select expression.
|
|
29
|
+
*
|
|
30
|
+
* @param {NqlPreSelectExpression} preSelect - The pre-select expression.
|
|
31
|
+
* @returns {string} - The built pre-select expression string.
|
|
32
|
+
* @throws {Error} - If the provided pre-select expression is invalid.
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildPreSelect(preSelect: NqlPreSelectExpression): string;
|
|
35
|
+
/**
|
|
36
|
+
* Extracts and parses the selected fields from the given NQL (Natural Query Language) string.
|
|
37
|
+
*
|
|
38
|
+
* @function getSelect
|
|
39
|
+
* @param {string} nql - The NQL string containing the SELECT statement.
|
|
40
|
+
* @returns {NqlField[]} - An array of parsed NqlField objects representing the selected fields.
|
|
41
|
+
* @throws {Error} - If no selected fields are found or if a field is invalid.
|
|
42
|
+
*/
|
|
43
|
+
export declare function getSelect(nql: string): NqlField[];
|
|
44
|
+
/**
|
|
45
|
+
* Builds a SELECT clause for an NQL (Natural Query Language) query based on the provided fields.
|
|
46
|
+
*
|
|
47
|
+
* @param {NqlField[]} fields - An array of NqlField objects representing the selected fields.
|
|
48
|
+
* @returns {string} - The built SELECT clause string.
|
|
49
|
+
* @throws {Error} - If any of the provided fields are invalid.
|
|
50
|
+
*/
|
|
51
|
+
export declare function buildSelect(fields: NqlField[]): string;
|
|
52
|
+
/**
|
|
53
|
+
* Parses a string in NQL format and returns an NqlBudgetType object.
|
|
54
|
+
*
|
|
55
|
+
* @function getLimit
|
|
56
|
+
* @param {string} nql - The NQL string to parse.
|
|
57
|
+
* @returns {NqlBudget} - The parsed budget object.
|
|
58
|
+
* @throws {Error} If the NQL string is invalid.
|
|
59
|
+
*/
|
|
60
|
+
export declare function getLimit(nql: string): NqlBudget;
|
|
61
|
+
/**
|
|
62
|
+
* Builds a LIMIT clause for an NQL (Narrative Query Language) query based on the provided budget object.
|
|
63
|
+
*
|
|
64
|
+
* @param {NqlBudget} budget - The budget object containing the limit values.
|
|
65
|
+
* @returns {string} - The LIMIT clause string.
|
|
66
|
+
* @throws {Error} - If the provided budget object is invalid.
|
|
67
|
+
*/
|
|
68
|
+
export declare function buildLimit(budget: NqlBudget): string;
|
|
69
|
+
/**
|
|
70
|
+
* Builds an NQL (Nested Query Language) string based on the provided Nql object.
|
|
71
|
+
*
|
|
72
|
+
* @param {Nql} nql - The Nql object containing the clauses for building the NQL string.
|
|
73
|
+
* @returns {string} - The constructed NQL string.
|
|
74
|
+
* @throws {Error} - Throws an error if the provided Nql object is invalid.
|
|
75
|
+
*/
|
|
76
|
+
export declare function buildNql(nql: Nql): string;
|
|
77
|
+
export declare function buildFrom(from: NqlTable): string;
|
|
78
|
+
export declare function buildWhere(where: NqlWhere): string;
|
|
79
|
+
export declare function buildField(field: NqlField | string | number | boolean): string;
|
|
80
|
+
/**
|
|
81
|
+
* Parses the given NQL string and returns an Nql object.
|
|
82
|
+
*
|
|
83
|
+
* @param {string} nql - The NQL string to parse.
|
|
84
|
+
* @returns {Nql} - The parsed Nql object.
|
|
85
|
+
* @throws {Error} - If the provided NQL string is invalid.
|
|
86
|
+
*/
|
|
87
|
+
export declare function getNqlObject(nql: string): Nql;
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { NqlBooleanExpressionObj, NqlBudgetObj, NqlFieldObj, NqlFilterExpressionObj, NqlObj, NqlPreSelectExpressionObj, NqlTableObject, NqlWhereObj } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Retrieves the WHERE clause from the given NQL (Nested Query Language) string and returns a parsed NqlWhereClause object.
|
|
4
|
+
*
|
|
5
|
+
* @param {string} nql - The NQL string to extract the WHERE clause from.
|
|
6
|
+
* @returns {NqlWhereClause} - The parsed NqlWhereClause object representing the WHERE clause.
|
|
7
|
+
* @throws {Error} - Throws an error if no WHERE clause is found in the NQL string.
|
|
8
|
+
*/
|
|
9
|
+
export function getWhere(nql) {
|
|
10
|
+
const regex = /\bWHERE\b(.*?)\bLIMIT\b/i;
|
|
11
|
+
const match = nql.trim().replace(/\n/g, ' ').match(regex);
|
|
12
|
+
if (match != null && match[1] !== '') {
|
|
13
|
+
const booleanExpressions = getBooleanExpressionsFromWhere(match[1]);
|
|
14
|
+
const filterExpressions = getFilterExpressionsFromWhere(match[1]);
|
|
15
|
+
return NqlWhereObj.parse({
|
|
16
|
+
booleanExpressions,
|
|
17
|
+
filterExpressions
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
throw new Error('No WHERE clause found');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Retrieves the tables from the given NQL (Nested Query Language) string and returns an array of parsed NqlTable objects.
|
|
26
|
+
*
|
|
27
|
+
* @param {string} nql - The NQL string to extract the tables from.
|
|
28
|
+
* @returns {NqlTable[]} - An array of parsed NqlTable objects representing the tables.
|
|
29
|
+
* @throws {Error} - Throws an error if no FROM clause is found in the NQL string.
|
|
30
|
+
*/
|
|
31
|
+
export function getFrom(nql) {
|
|
32
|
+
const regex = /\bFROM\b(.*?)\bWHERE\b/i;
|
|
33
|
+
const match = nql.trim().replace(/\n/g, ' ').match(regex);
|
|
34
|
+
if (match != null && match[1] !== '') {
|
|
35
|
+
const tables = match[1].split(',').map((t) => {
|
|
36
|
+
const [database, table] = t.trim().split('.');
|
|
37
|
+
return NqlTableObject.parse({
|
|
38
|
+
database,
|
|
39
|
+
table
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
return tables;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
throw new Error('No FROM clause found');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Extracts boolean expressions from the WHERE clause string and returns an array of parsed NqlBooleanExpression objects.
|
|
50
|
+
*
|
|
51
|
+
* @param {string} where - The WHERE clause string.
|
|
52
|
+
* @returns {NqlBooleanExpression[]} - An array of parsed NqlBooleanExpression objects representing the boolean expressions.
|
|
53
|
+
*/
|
|
54
|
+
function getBooleanExpressionsFromWhere(where) {
|
|
55
|
+
const booleanRegex = /\b(OR|AND)\b/ig;
|
|
56
|
+
const matches = [];
|
|
57
|
+
let boolMatch;
|
|
58
|
+
while ((boolMatch = booleanRegex.exec(where)) !== null) {
|
|
59
|
+
matches.push(boolMatch[1].trim().toUpperCase());
|
|
60
|
+
}
|
|
61
|
+
return NqlBooleanExpressionObj.array().parse(matches);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Extracts filter expressions from the WHERE clause string and returns an array of parsed NqlFilterExpression objects.
|
|
65
|
+
*
|
|
66
|
+
* @param {string} where - The WHERE clause string.
|
|
67
|
+
* @returns {NqlFilterExpression[]} - An array of parsed NqlFilterExpression objects representing the filter expressions.
|
|
68
|
+
*/
|
|
69
|
+
function getFilterExpressionsFromWhere(where) {
|
|
70
|
+
let matches = [];
|
|
71
|
+
const hasBoolean = /\b(?:OR|AND)\b/ig.test(where);
|
|
72
|
+
if (!hasBoolean) {
|
|
73
|
+
matches.push(getFilterExpressionFromString(where));
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const expressions = where.split(/\b(?:OR|AND)\b/ig).map((t) => t.trim());
|
|
77
|
+
matches = matches.concat(expressions.map((e) => getFilterExpressionFromString(e)));
|
|
78
|
+
}
|
|
79
|
+
return NqlFilterExpressionObj.array().parse(matches);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Parses a field string into an NqlField object or returns the original field string if parsing fails.
|
|
83
|
+
*
|
|
84
|
+
* @param {string} fieldStr - The field string to parse.
|
|
85
|
+
* @returns {NqlField | string} - The parsed NqlField object or the original field string if parsing fails.
|
|
86
|
+
*/
|
|
87
|
+
function parseFieldFromString(fieldStr) {
|
|
88
|
+
const [database, table, ...f] = fieldStr.trim().split('.');
|
|
89
|
+
const field = {
|
|
90
|
+
table: {
|
|
91
|
+
database,
|
|
92
|
+
table
|
|
93
|
+
},
|
|
94
|
+
field: f.join('.')
|
|
95
|
+
};
|
|
96
|
+
try {
|
|
97
|
+
return NqlFieldObj.parse(field);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return parseString(fieldStr.trim());
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Parses a string value as a number or boolean if valid, or keeps it as a string.
|
|
105
|
+
* @param {string} value - The string value to parse.
|
|
106
|
+
* @returns {string | number | boolean} - The parsed value, or the original string if parsing fails.
|
|
107
|
+
*/
|
|
108
|
+
function parseString(value) {
|
|
109
|
+
// Attempt to parse as a number
|
|
110
|
+
const parsedNumber = Number(value);
|
|
111
|
+
if (!isNaN(parsedNumber)) {
|
|
112
|
+
return parsedNumber;
|
|
113
|
+
}
|
|
114
|
+
// Attempt to parse as a boolean
|
|
115
|
+
if (value.toLowerCase() === 'true') {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
if (value.toLowerCase() === 'false') {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
// Return as string if it is neither a number nor boolean
|
|
122
|
+
return value;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Parses a field string into an NqlField object or a plain string if parsing fails.
|
|
126
|
+
*
|
|
127
|
+
* @param {string} fieldStr - The field string to parse.
|
|
128
|
+
* @returns {NqlField | string} - The parsed NqlField object or the original field string if parsing fails.
|
|
129
|
+
*/
|
|
130
|
+
function getFilterExpressionFromString(str) {
|
|
131
|
+
const comparison = ['<=', '>=', '!=', '=', '>', '<'];
|
|
132
|
+
const containsComparison = comparison.find((character) => str.includes(character));
|
|
133
|
+
if (containsComparison !== undefined) {
|
|
134
|
+
const result = str.split(containsComparison);
|
|
135
|
+
const left = parseFieldFromString(result[0]);
|
|
136
|
+
const operator = containsComparison.trim().toUpperCase();
|
|
137
|
+
const right = parseFieldFromString(result[1]);
|
|
138
|
+
return NqlFilterExpressionObj.parse({
|
|
139
|
+
left,
|
|
140
|
+
operator,
|
|
141
|
+
right
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
const strComparison = [' IN ', ' NOT IN ', ' LIKE ', ' NOT LIKE '];
|
|
145
|
+
const containsStrComparison = strComparison.find((character) => str.toLowerCase().includes(character.toLowerCase()));
|
|
146
|
+
if (containsStrComparison !== undefined) {
|
|
147
|
+
const result = str.split(containsStrComparison);
|
|
148
|
+
const left = parseFieldFromString(result[0]);
|
|
149
|
+
const operator = containsStrComparison.trim().toUpperCase();
|
|
150
|
+
const right = parseFieldFromString(result[1]);
|
|
151
|
+
return NqlFilterExpressionObj.parse({
|
|
152
|
+
left,
|
|
153
|
+
operator,
|
|
154
|
+
right
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
const unaryOperators = [' IS NULL', ' IS NOT NULL'];
|
|
158
|
+
const containsUnaryOperator = unaryOperators.find((character) => str.toLowerCase().includes(character.toLowerCase()));
|
|
159
|
+
if (containsUnaryOperator !== undefined) {
|
|
160
|
+
const result = str.split(containsUnaryOperator);
|
|
161
|
+
const field = parseFieldFromString(result[0]);
|
|
162
|
+
const operator = containsUnaryOperator.trim().toUpperCase();
|
|
163
|
+
return NqlFilterExpressionObj.parse({
|
|
164
|
+
field,
|
|
165
|
+
operator
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
throw new Error('Invalid filter expression');
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Parses the pre-select expression from the given NQL (Natural Query Language) string.
|
|
172
|
+
*
|
|
173
|
+
* @function getPreSelect
|
|
174
|
+
* @param {string} nql - The NQL string to parse.
|
|
175
|
+
* @returns {NqlPreSelectExpression | undefined} - The parsed pre-select expression object, or `undefined` if no valid pre-select expression is found.
|
|
176
|
+
* @throws {Error} If the NQL string is invalid.
|
|
177
|
+
*/
|
|
178
|
+
export function getPreSelect(nql) {
|
|
179
|
+
/**
|
|
180
|
+
* A regular expression pattern to match the pre-select expression.
|
|
181
|
+
* The expression is located before the first occurrence of the word 'SELECT'.
|
|
182
|
+
* The match is case-insensitive.
|
|
183
|
+
*/
|
|
184
|
+
const regex = /^(.*?)(?=SELECT)/i;
|
|
185
|
+
const match = nql.trim().replace(/\n/g, ' ').match(regex);
|
|
186
|
+
return match != null && match[1] !== '' ? NqlPreSelectExpressionObj.parse(match[1].toUpperCase().trim()) : undefined;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Builds a pre-select expression for an NQL (Natural Query Language) query based on the provided pre-select expression.
|
|
190
|
+
*
|
|
191
|
+
* @param {NqlPreSelectExpression} preSelect - The pre-select expression.
|
|
192
|
+
* @returns {string} - The built pre-select expression string.
|
|
193
|
+
* @throws {Error} - If the provided pre-select expression is invalid.
|
|
194
|
+
*/
|
|
195
|
+
export function buildPreSelect(preSelect) {
|
|
196
|
+
NqlPreSelectExpressionObj.parse(preSelect);
|
|
197
|
+
return preSelect ?? '';
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Extracts and parses the selected fields from the given NQL (Natural Query Language) string.
|
|
201
|
+
*
|
|
202
|
+
* @function getSelect
|
|
203
|
+
* @param {string} nql - The NQL string containing the SELECT statement.
|
|
204
|
+
* @returns {NqlField[]} - An array of parsed NqlField objects representing the selected fields.
|
|
205
|
+
* @throws {Error} - If no selected fields are found or if a field is invalid.
|
|
206
|
+
*/
|
|
207
|
+
export function getSelect(nql) {
|
|
208
|
+
const regex = /SELECT\b(.*?)\bFROM/i;
|
|
209
|
+
const match = nql.trim().replace(/\n/g, ' ').match(regex);
|
|
210
|
+
if (match != null && match[1] !== '') {
|
|
211
|
+
const fields = match[1].trim().split(',');
|
|
212
|
+
return fields.map((f) => {
|
|
213
|
+
const trimmedFields = f.trim().split('.');
|
|
214
|
+
if (trimmedFields.length < 3) {
|
|
215
|
+
throw new Error('Invalid field');
|
|
216
|
+
}
|
|
217
|
+
const [database, table, ...field] = trimmedFields;
|
|
218
|
+
const t = NqlTableObject.parse({ database, table });
|
|
219
|
+
return NqlFieldObj.parse({ table: t, field: field.join('.') });
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
throw new Error('No selected fields found');
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Builds a SELECT clause for an NQL (Natural Query Language) query based on the provided fields.
|
|
228
|
+
*
|
|
229
|
+
* @param {NqlField[]} fields - An array of NqlField objects representing the selected fields.
|
|
230
|
+
* @returns {string} - The built SELECT clause string.
|
|
231
|
+
* @throws {Error} - If any of the provided fields are invalid.
|
|
232
|
+
*/
|
|
233
|
+
export function buildSelect(fields) {
|
|
234
|
+
fields.forEach((f) => NqlFieldObj.parse(f));
|
|
235
|
+
return 'SELECT ' + fields.map((f) => `${f.table.database}.${f.table.table}.${f.field}`).join(', ');
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Parses a string in NQL format and returns an NqlBudgetType object.
|
|
239
|
+
*
|
|
240
|
+
* @function getLimit
|
|
241
|
+
* @param {string} nql - The NQL string to parse.
|
|
242
|
+
* @returns {NqlBudget} - The parsed budget object.
|
|
243
|
+
* @throws {Error} If the NQL string is invalid.
|
|
244
|
+
*/
|
|
245
|
+
export function getLimit(nql) {
|
|
246
|
+
const regex = /LIMIT\s+(\d+)\s+(\w+)\s+PER\s+(\w+)$/i;
|
|
247
|
+
const match = nql.trim().replace(/\n/g, ' ').match(regex);
|
|
248
|
+
if (match != null) {
|
|
249
|
+
const [, value, currency, period] = match;
|
|
250
|
+
const result = {
|
|
251
|
+
value: parseInt(value, 10),
|
|
252
|
+
currency: currency.toUpperCase(),
|
|
253
|
+
period: period.toUpperCase()
|
|
254
|
+
};
|
|
255
|
+
return NqlBudgetObj.parse(result);
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
throw new Error('Invalid budget');
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Builds a LIMIT clause for an NQL (Narrative Query Language) query based on the provided budget object.
|
|
263
|
+
*
|
|
264
|
+
* @param {NqlBudget} budget - The budget object containing the limit values.
|
|
265
|
+
* @returns {string} - The LIMIT clause string.
|
|
266
|
+
* @throws {Error} - If the provided budget object is invalid.
|
|
267
|
+
*/
|
|
268
|
+
export function buildLimit(budget) {
|
|
269
|
+
NqlBudgetObj.parse(budget);
|
|
270
|
+
return `LIMIT ${budget.value} ${budget.currency} PER ${budget.period}`;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Builds an NQL (Nested Query Language) string based on the provided Nql object.
|
|
274
|
+
*
|
|
275
|
+
* @param {Nql} nql - The Nql object containing the clauses for building the NQL string.
|
|
276
|
+
* @returns {string} - The constructed NQL string.
|
|
277
|
+
* @throws {Error} - Throws an error if the provided Nql object is invalid.
|
|
278
|
+
*/
|
|
279
|
+
export function buildNql(nql) {
|
|
280
|
+
// Validate our object
|
|
281
|
+
NqlObj.parse(nql);
|
|
282
|
+
// Build the NQL string from each of the clasues
|
|
283
|
+
const explain = buildPreSelect(nql.explain);
|
|
284
|
+
const limit = buildLimit(nql.limit);
|
|
285
|
+
const select = buildSelect(nql.select);
|
|
286
|
+
const from = buildFrom(nql.from[0]);
|
|
287
|
+
const where = buildWhere(nql.where);
|
|
288
|
+
const clauses = [explain, select, from, where, limit];
|
|
289
|
+
// Remove any empty clausess and join what's left together
|
|
290
|
+
return clauses.filter((c) => c !== '').join(' ');
|
|
291
|
+
}
|
|
292
|
+
export function buildFrom(from) {
|
|
293
|
+
NqlTableObject.parse(from);
|
|
294
|
+
return `FROM ${from.database}.${from.table}`;
|
|
295
|
+
}
|
|
296
|
+
export function buildWhere(where) {
|
|
297
|
+
NqlWhereObj.parse(where);
|
|
298
|
+
let str = 'WHERE';
|
|
299
|
+
where.filterExpressions.forEach((f, i) => {
|
|
300
|
+
if ('field' in f) {
|
|
301
|
+
str += ` ${buildField(f.field)} ${f.operator}`;
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
str += ` ${buildField(f.left)} ${f.operator} ${buildField(f.right)}`;
|
|
305
|
+
}
|
|
306
|
+
if (where.booleanExpressions[i] != null) {
|
|
307
|
+
str += ` ${where.booleanExpressions[i]}`;
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
return str;
|
|
311
|
+
}
|
|
312
|
+
export function buildField(field) {
|
|
313
|
+
try {
|
|
314
|
+
const f = NqlFieldObj.parse(field);
|
|
315
|
+
return `${f.table.database}.${f.table.table}.${f.field}`;
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
return String(field);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Parses the given NQL string and returns an Nql object.
|
|
323
|
+
*
|
|
324
|
+
* @param {string} nql - The NQL string to parse.
|
|
325
|
+
* @returns {Nql} - The parsed Nql object.
|
|
326
|
+
* @throws {Error} - If the provided NQL string is invalid.
|
|
327
|
+
*/
|
|
328
|
+
export function getNqlObject(nql) {
|
|
329
|
+
const explain = getPreSelect(nql);
|
|
330
|
+
const limit = getLimit(nql);
|
|
331
|
+
const where = getWhere(nql);
|
|
332
|
+
const from = getFrom(nql);
|
|
333
|
+
const select = getSelect(nql);
|
|
334
|
+
return NqlObj.parse({ where, from, explain, select, limit });
|
|
335
|
+
}
|