flowerbi 3.8.2 → 3.9.0
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/dist/QueryJson.d.ts +29 -5
- package/dist/QueryValues.d.ts +10 -10
- package/dist/QueryValues.js.map +1 -1
- package/dist/executeQuery.d.ts +8 -8
- package/dist/executeQuery.js +83 -12
- package/dist/executeQuery.js.map +1 -1
- package/dist/executeQuery.test.d.ts +1 -0
- package/dist/executeQuery.test.js +196 -22
- package/dist/executeQuery.test.js.map +1 -1
- package/dist/queryModel.d.ts +28 -8
- package/dist/queryModel.js.map +1 -1
- package/package.json +1 -1
- package/src/QueryJson.ts +32 -5
- package/src/QueryValues.ts +17 -17
- package/src/executeQuery.test.ts +263 -62
- package/src/executeQuery.ts +121 -31
- package/src/queryModel.ts +59 -34
package/src/executeQuery.ts
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
Query,
|
|
3
|
+
QuerySelect,
|
|
4
|
+
ExpandedQueryRecord,
|
|
5
|
+
AggregateValuesOnly,
|
|
6
|
+
getAggregatePropsOnly,
|
|
7
|
+
getColumnPropsOnly,
|
|
8
|
+
Calculation,
|
|
9
|
+
AggregatePropsOnly,
|
|
10
|
+
QueryCalculations,
|
|
11
|
+
Ordering,
|
|
12
|
+
CalculationValues,
|
|
13
|
+
} from "./queryModel";
|
|
14
|
+
import { QueryJson, AggregationJson, CalculationJson, OrderingJson } from "./QueryJson";
|
|
3
15
|
import { QueryColumn } from "./QueryColumn";
|
|
16
|
+
import { keysOf } from "./arrayHelpers";
|
|
4
17
|
|
|
5
18
|
/**
|
|
6
19
|
* The allowed data types for plain columns.
|
|
7
20
|
*/
|
|
8
|
-
export type QuerySelectValue = number|string|Date|boolean;
|
|
21
|
+
export type QuerySelectValue = number | string | Date | boolean;
|
|
9
22
|
|
|
10
23
|
/**
|
|
11
24
|
* The JSON format of a record returned from the API when executing a query.
|
|
@@ -22,7 +35,7 @@ export interface QueryRecordJson {
|
|
|
22
35
|
}
|
|
23
36
|
|
|
24
37
|
/**
|
|
25
|
-
* The JSON format of the whole payload returned from the API when
|
|
38
|
+
* The JSON format of the whole payload returned from the API when
|
|
26
39
|
* executing a query.
|
|
27
40
|
*/
|
|
28
41
|
export interface QueryResultJson {
|
|
@@ -47,24 +60,91 @@ export interface QueryResultJson {
|
|
|
47
60
|
*/
|
|
48
61
|
export type QueryFetch = (queryJson: QueryJson) => Promise<QueryResultJson>;
|
|
49
62
|
|
|
63
|
+
function jsonifyCalculation<S extends QuerySelect>(calculation: Calculation<S>, props: AggregatePropsOnly<S>[]): CalculationJson {
|
|
64
|
+
if (typeof calculation === "string") {
|
|
65
|
+
const aggregation = props.indexOf(calculation);
|
|
66
|
+
if (aggregation === -1) {
|
|
67
|
+
throw new Error(`Not a valid aggregation name: ${calculation}`);
|
|
68
|
+
}
|
|
69
|
+
return { aggregation };
|
|
70
|
+
}
|
|
71
|
+
if (typeof calculation === "number") {
|
|
72
|
+
return {
|
|
73
|
+
value: calculation,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
if (calculation instanceof Array) {
|
|
77
|
+
return {
|
|
78
|
+
first: jsonifyCalculation(calculation[0], props),
|
|
79
|
+
operator: calculation[1],
|
|
80
|
+
second: jsonifyCalculation(calculation[2], props),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
throw new Error("Invalid calculation");
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function jsonifyOrdering<S extends QuerySelect, C extends QueryCalculations<S>>(
|
|
87
|
+
ordering: OrderingJson | Ordering<S, C>,
|
|
88
|
+
selects: string[],
|
|
89
|
+
values: string[],
|
|
90
|
+
calculations: string[]
|
|
91
|
+
): OrderingJson {
|
|
92
|
+
if ("select" in ordering) {
|
|
93
|
+
let index = selects.indexOf(ordering.select as string);
|
|
94
|
+
if (index !== -1) {
|
|
95
|
+
return {
|
|
96
|
+
type: "Select",
|
|
97
|
+
index,
|
|
98
|
+
descending: ordering.descending,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
index = values.indexOf(ordering.select as string);
|
|
102
|
+
if (index !== -1) {
|
|
103
|
+
return {
|
|
104
|
+
type: "Value",
|
|
105
|
+
index,
|
|
106
|
+
descending: ordering.descending,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
throw new Error(`Invalid ordering select key: ${String(ordering.select)}`);
|
|
110
|
+
}
|
|
111
|
+
if ("calculation" in ordering) {
|
|
112
|
+
let index = calculations.indexOf(ordering.calculation as string);
|
|
113
|
+
if (index !== -1) {
|
|
114
|
+
return {
|
|
115
|
+
type: "Calculation",
|
|
116
|
+
index,
|
|
117
|
+
descending: ordering.descending,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
throw new Error(`Invalid ordering calculation key: ${String(ordering.calculation)}`);
|
|
121
|
+
}
|
|
122
|
+
return ordering;
|
|
123
|
+
}
|
|
124
|
+
|
|
50
125
|
/**
|
|
51
126
|
* Converts a statically-typed {@link Query} into the {@link QueryJson}
|
|
52
127
|
* format, ready to be sent to your API.
|
|
53
|
-
* @param query
|
|
128
|
+
* @param query
|
|
54
129
|
*/
|
|
55
|
-
export function jsonifyQuery<S extends QuerySelect
|
|
56
|
-
const { select, filters, orderBy, totals, take, skip, comment, allowDuplicates } = query;
|
|
130
|
+
export function jsonifyQuery<S extends QuerySelect, C extends QueryCalculations<S>>(query: Query<S, C>): QueryJson {
|
|
131
|
+
const { select, filters, calculations, orderBy, totals, take, skip, comment, allowDuplicates } = query;
|
|
132
|
+
|
|
133
|
+
const columnProps = getColumnPropsOnly(select);
|
|
134
|
+
const aggregationProps = getAggregatePropsOnly(select);
|
|
135
|
+
const calculationProps = calculations ? keysOf(calculations) : [];
|
|
57
136
|
|
|
58
|
-
return {
|
|
59
|
-
select:
|
|
60
|
-
aggregations:
|
|
137
|
+
return {
|
|
138
|
+
select: columnProps.map((key) => (select[key] as QueryColumn<never>).name),
|
|
139
|
+
aggregations: aggregationProps.map((key) => select[key] as AggregationJson),
|
|
140
|
+
calculations: calculations ? calculationProps.map((key) => jsonifyCalculation(calculations[key] as Calculation<S>, aggregationProps)) : undefined,
|
|
61
141
|
filters: filters ?? [],
|
|
62
|
-
orderBy: orderBy ?? [],
|
|
142
|
+
orderBy: orderBy?.map((o) => jsonifyOrdering(o, columnProps as string[], aggregationProps as string[], calculationProps as string[])) ?? [],
|
|
63
143
|
totals: totals ?? false,
|
|
64
144
|
skip: skip ?? 0,
|
|
65
145
|
take: take ?? 100,
|
|
66
146
|
comment,
|
|
67
|
-
allowDuplicates
|
|
147
|
+
allowDuplicates,
|
|
68
148
|
};
|
|
69
149
|
}
|
|
70
150
|
|
|
@@ -75,11 +155,11 @@ export function jsonifyQuery<S extends QuerySelect>(query: Query<S>): QueryJson
|
|
|
75
155
|
* @param select The {@link Query.select} property from the query.
|
|
76
156
|
* @param record The record returned from your API.
|
|
77
157
|
*/
|
|
78
|
-
export function expandQueryRecord<S extends QuerySelect
|
|
158
|
+
export function expandQueryRecord<S extends QuerySelect, C extends QueryCalculations<S>>(
|
|
79
159
|
select: S,
|
|
80
|
-
record: QueryRecordJson
|
|
81
|
-
|
|
82
|
-
|
|
160
|
+
record: QueryRecordJson,
|
|
161
|
+
calcs?: C
|
|
162
|
+
): ExpandedQueryRecord<S, C> {
|
|
83
163
|
const result: any = {};
|
|
84
164
|
|
|
85
165
|
let n = 0;
|
|
@@ -87,6 +167,11 @@ export function expandQueryRecord<S extends QuerySelect>(
|
|
|
87
167
|
result[key] = record.aggregated[n++];
|
|
88
168
|
}
|
|
89
169
|
|
|
170
|
+
const calculationProps = calcs ? keysOf(calcs) : [];
|
|
171
|
+
for (const key of calculationProps) {
|
|
172
|
+
result[key] = record.aggregated[n++];
|
|
173
|
+
}
|
|
174
|
+
|
|
90
175
|
n = 0;
|
|
91
176
|
for (const key of getColumnPropsOnly(select)) {
|
|
92
177
|
result[key] = record.selected[n++];
|
|
@@ -96,18 +181,18 @@ export function expandQueryRecord<S extends QuerySelect>(
|
|
|
96
181
|
}
|
|
97
182
|
|
|
98
183
|
/**
|
|
99
|
-
* Converts the `QueryRecordJson` from the `totals` record into a strongly-typed
|
|
184
|
+
* Converts the `QueryRecordJson` from the `totals` record into a strongly-typed
|
|
100
185
|
* record named properties for the aggregated values only, using the
|
|
101
186
|
* {@link Query.select} from the query to perform the necessary mapping.
|
|
102
|
-
*
|
|
187
|
+
*
|
|
103
188
|
* @param select The {@link Query.select} property from the query.
|
|
104
189
|
* @param record The {@link QueryResultJson.totals} record returned from your API.
|
|
105
190
|
*/
|
|
106
|
-
export function getAggregateValuesOnly<S extends QuerySelect
|
|
191
|
+
export function getAggregateValuesOnly<S extends QuerySelect, C extends QueryCalculations<S>>(
|
|
107
192
|
select: S,
|
|
108
|
-
record: QueryRecordJson
|
|
109
|
-
|
|
110
|
-
|
|
193
|
+
record: QueryRecordJson,
|
|
194
|
+
calcs?: C
|
|
195
|
+
): AggregateValuesOnly<S> & CalculationValues<C> {
|
|
111
196
|
const result: any = {};
|
|
112
197
|
|
|
113
198
|
let n = 0;
|
|
@@ -115,25 +200,30 @@ export function getAggregateValuesOnly<S extends QuerySelect>(
|
|
|
115
200
|
result[key] = record.aggregated[n++];
|
|
116
201
|
}
|
|
117
202
|
|
|
203
|
+
const calculationProps = calcs ? keysOf(calcs) : [];
|
|
204
|
+
for (const key of calculationProps) {
|
|
205
|
+
result[key] = record.aggregated[n++];
|
|
206
|
+
}
|
|
207
|
+
|
|
118
208
|
return result;
|
|
119
209
|
}
|
|
120
210
|
|
|
121
211
|
/**
|
|
122
212
|
* The statically-typed result of a {@link Query}.
|
|
123
213
|
*/
|
|
124
|
-
export interface ExpandedQueryResult<S extends QuerySelect
|
|
214
|
+
export interface ExpandedQueryResult<S extends QuerySelect, C extends QueryCalculations<S>> {
|
|
125
215
|
/**
|
|
126
216
|
* The set of records returned, each having named properties
|
|
127
217
|
* corresponding to the plain and aggregated columns selected
|
|
128
218
|
* in the query.
|
|
129
219
|
*/
|
|
130
|
-
records: ExpandedQueryRecord<S>[];
|
|
220
|
+
records: ExpandedQueryRecord<S, C>[];
|
|
131
221
|
/**
|
|
132
222
|
* Optional extra record, only available if {@link QueryJson.totals}
|
|
133
223
|
* was specified as `true` in the query, containing the aggregation
|
|
134
224
|
* totals.
|
|
135
225
|
*/
|
|
136
|
-
totals?: AggregateValuesOnly<S>;
|
|
226
|
+
totals?: AggregateValuesOnly<S> & CalculationValues<C>;
|
|
137
227
|
}
|
|
138
228
|
|
|
139
229
|
/**
|
|
@@ -142,13 +232,13 @@ export interface ExpandedQueryResult<S extends QuerySelect> {
|
|
|
142
232
|
* @param select The {@link Query.select} property from the query.
|
|
143
233
|
* @param result The response payload from the API call.
|
|
144
234
|
*/
|
|
145
|
-
export function expandQueryResult<S extends QuerySelect
|
|
235
|
+
export function expandQueryResult<S extends QuerySelect, C extends QueryCalculations<S>>(
|
|
146
236
|
select: S,
|
|
147
|
-
result: QueryResultJson
|
|
148
|
-
|
|
149
|
-
|
|
237
|
+
result: QueryResultJson,
|
|
238
|
+
calcs?: C
|
|
239
|
+
): ExpandedQueryResult<S, C> {
|
|
150
240
|
return {
|
|
151
|
-
records: result.records.map(r => expandQueryRecord(select, r)),
|
|
152
|
-
totals: result.totals && getAggregateValuesOnly(select, result.totals)
|
|
241
|
+
records: result.records.map((r) => expandQueryRecord(select, r, calcs)),
|
|
242
|
+
totals: result.totals && getAggregateValuesOnly(select, result.totals, calcs),
|
|
153
243
|
};
|
|
154
244
|
}
|
package/src/queryModel.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { QueryColumn } from "./QueryColumn";
|
|
|
3
3
|
import { AggregationJson, FilterJson, OrderingJson } from "./QueryJson";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Defines the kinds of member that can appear in the `select` object of a query.
|
|
6
|
+
* Defines the kinds of member that can appear in the `select` object of a query.
|
|
7
7
|
* Queries can select plain columns, or aggregation functions on columns.
|
|
8
8
|
*/
|
|
9
9
|
export type SelectMember = QueryColumn<any> | AggregationJson;
|
|
@@ -21,19 +21,23 @@ export type QueryColumnType<T> = T extends QueryColumn<infer C> ? C : never;
|
|
|
21
21
|
/**
|
|
22
22
|
* Defines the shape of a record returned from a query, based on its `select` object.
|
|
23
23
|
* Each selected property appears as a property in the record with the same name. For
|
|
24
|
-
* plain columns the data type depends on the column definition, but for
|
|
25
|
-
* the data type is always `number`.
|
|
24
|
+
* plain columns the data type depends on the column definition, but for aggregations
|
|
25
|
+
* and calculations the data type is always `number`.
|
|
26
26
|
*/
|
|
27
|
-
export type ExpandedQueryRecord<S extends QuerySelect
|
|
27
|
+
export type ExpandedQueryRecord<S extends QuerySelect, C extends QueryCalculations<S>> = {
|
|
28
28
|
[P in keyof S]: S[P] extends QueryColumn<any> ? QueryColumnType<S[P]> : number;
|
|
29
|
+
} & {
|
|
30
|
+
[P in keyof C]: number;
|
|
29
31
|
};
|
|
30
32
|
|
|
31
33
|
/**
|
|
32
34
|
* Similar to {@link ExpandedQueryRecord} but the plain columns are optional, so they
|
|
33
|
-
* may be `undefined`. Aggregations are not optional.
|
|
35
|
+
* may be `undefined`. Aggregations/calculations are not optional.
|
|
34
36
|
*/
|
|
35
|
-
export type ExpandedQueryRecordWithOptionalColumns<S extends QuerySelect
|
|
36
|
-
[P in keyof S]: S[P] extends QueryColumn<any> ?
|
|
37
|
+
export type ExpandedQueryRecordWithOptionalColumns<S extends QuerySelect, C extends QueryCalculations<S>> = {
|
|
38
|
+
[P in keyof S]: S[P] extends QueryColumn<any> ? QueryColumnType<S[P]> | undefined : number;
|
|
39
|
+
} & {
|
|
40
|
+
[P in keyof C]: number;
|
|
37
41
|
};
|
|
38
42
|
|
|
39
43
|
/**
|
|
@@ -50,25 +54,25 @@ export type AggregatePropsOnlyHelper<T extends QuerySelect> = {
|
|
|
50
54
|
export type AggregatePropsOnly<T extends QuerySelect> = AggregatePropsOnlyHelper<T>[keyof AggregatePropsOnlyHelper<T>];
|
|
51
55
|
|
|
52
56
|
/**
|
|
53
|
-
* Returns the names of properties in a query that refer to aggregated columns.
|
|
57
|
+
* Returns the names of properties in a query that refer to aggregated columns.
|
|
54
58
|
* The result is an array of strings, but type-constrained to string literal types:
|
|
55
|
-
*
|
|
59
|
+
*
|
|
56
60
|
* ```ts
|
|
57
|
-
* getAggregatePropsOnly({
|
|
61
|
+
* getAggregatePropsOnly({
|
|
58
62
|
* customer: Customer.Name,
|
|
59
63
|
* spend: Invoice.Amount.sum()
|
|
60
64
|
* }) // ["spend"]
|
|
61
65
|
* ```
|
|
62
|
-
*
|
|
66
|
+
*
|
|
63
67
|
* @param select the `select` object from a query
|
|
64
68
|
*/
|
|
65
69
|
export function getAggregatePropsOnly<T extends QuerySelect>(select: T) {
|
|
66
|
-
const keys = keysOf(select).filter(x => !(select[x] instanceof QueryColumn))
|
|
70
|
+
const keys = keysOf(select).filter((x) => !(select[x] instanceof QueryColumn));
|
|
67
71
|
return keys as AggregatePropsOnly<T>[];
|
|
68
72
|
}
|
|
69
73
|
|
|
70
74
|
/**
|
|
71
|
-
* An object that contains a subset of the the named properties from a query's
|
|
75
|
+
* An object that contains a subset of the the named properties from a query's
|
|
72
76
|
* `select` object, those that refer to aggregated values (hence all are of
|
|
73
77
|
* type `number`.)
|
|
74
78
|
*/
|
|
@@ -76,6 +80,10 @@ export type AggregateValuesOnly<T extends QuerySelect> = {
|
|
|
76
80
|
[K in AggregatePropsOnly<T>]: number;
|
|
77
81
|
};
|
|
78
82
|
|
|
83
|
+
export type CalculationValues<C extends QueryCalculations<any>> = {
|
|
84
|
+
[K in keyof C]: number;
|
|
85
|
+
};
|
|
86
|
+
|
|
79
87
|
/**
|
|
80
88
|
* A helper type used in the definition of {@link ColumnPropsOnly}.
|
|
81
89
|
*/
|
|
@@ -92,18 +100,18 @@ export type ColumnPropsOnly<T extends QuerySelect> = ColumnPropsOnlyHelper<T>[ke
|
|
|
92
100
|
/**
|
|
93
101
|
* Returns the names of properties in a query that refer to plain columns. The
|
|
94
102
|
* result is an array of strings, but type-constrained to string literal types:
|
|
95
|
-
*
|
|
103
|
+
*
|
|
96
104
|
* ```ts
|
|
97
|
-
* getColumnPropsOnly({
|
|
105
|
+
* getColumnPropsOnly({
|
|
98
106
|
* customer: Customer.Name,
|
|
99
|
-
* spend: Invoice.Amount.sum()
|
|
107
|
+
* spend: Invoice.Amount.sum()
|
|
100
108
|
* }) // ["customer"]
|
|
101
109
|
* ```
|
|
102
|
-
*
|
|
110
|
+
*
|
|
103
111
|
* @param select the `select` object from a query
|
|
104
112
|
*/
|
|
105
113
|
export function getColumnPropsOnly<T extends QuerySelect>(select: T) {
|
|
106
|
-
const keys = keysOf(select).filter(x => select[x] instanceof QueryColumn)
|
|
114
|
+
const keys = keysOf(select).filter((x) => select[x] instanceof QueryColumn);
|
|
107
115
|
return keys as ColumnPropsOnly<T>[];
|
|
108
116
|
}
|
|
109
117
|
|
|
@@ -114,37 +122,54 @@ export function getColumnPropsOnly<T extends QuerySelect>(select: T) {
|
|
|
114
122
|
*/
|
|
115
123
|
export function getColumnsOnly(select: QuerySelect) {
|
|
116
124
|
return keysOf(select)
|
|
117
|
-
.map(k => select[k])
|
|
118
|
-
.filter(x => x instanceof QueryColumn)
|
|
119
|
-
.map(x =>
|
|
125
|
+
.map((k) => select[k])
|
|
126
|
+
.filter((x) => x instanceof QueryColumn)
|
|
127
|
+
.map((x) => x as QueryColumn<any>);
|
|
120
128
|
}
|
|
121
129
|
|
|
130
|
+
export type Calculation<S extends QuerySelect> = number | AggregatePropsOnly<S> | [Calculation<S>, "+" | "-" | "*" | "/", Calculation<S>];
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* The `select` object of a query has named properties of type {@link SelectMember}.
|
|
134
|
+
*/
|
|
135
|
+
export type QueryCalculations<S extends QuerySelect> = Record<string, Calculation<S>>;
|
|
136
|
+
|
|
137
|
+
export type Ordering<S extends QuerySelect, C extends QueryCalculations<S>> = { descending?: boolean } & (
|
|
138
|
+
| {
|
|
139
|
+
select: keyof S;
|
|
140
|
+
}
|
|
141
|
+
| {
|
|
142
|
+
calculation: keyof C;
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
|
|
122
146
|
/**
|
|
123
|
-
* Strongly-typed query definition: use {@link jsonifyQuery} to convert to the JSON format
|
|
147
|
+
* Strongly-typed query definition: use {@link jsonifyQuery} to convert to the JSON format
|
|
124
148
|
* and {@link expandQueryResult} to generate corresponding output records.
|
|
125
149
|
*/
|
|
126
|
-
export interface Query<S extends QuerySelect
|
|
150
|
+
export interface Query<S extends QuerySelect, C extends QueryCalculations<S>> {
|
|
127
151
|
select: S;
|
|
128
152
|
filters?: FilterJson[];
|
|
153
|
+
calculations?: C;
|
|
129
154
|
/**
|
|
130
155
|
* Ordering criteria to apply.
|
|
131
156
|
*/
|
|
132
|
-
orderBy?: OrderingJson[];
|
|
157
|
+
orderBy?: (OrderingJson | Ordering<S, C>)[];
|
|
133
158
|
/**
|
|
134
|
-
* Specifies whether to return a `totals` property containing the
|
|
159
|
+
* Specifies whether to return a `totals` property containing the
|
|
135
160
|
* aggregation values across the whole dataset, e.g. if the `select`
|
|
136
161
|
* object is:
|
|
137
|
-
*
|
|
162
|
+
*
|
|
138
163
|
* ```ts
|
|
139
|
-
* {
|
|
164
|
+
* {
|
|
140
165
|
* customer: Customer.Name,
|
|
141
166
|
* spend: Invoice.Amount.sum()
|
|
142
167
|
* }
|
|
143
168
|
* ```
|
|
144
|
-
*
|
|
169
|
+
*
|
|
145
170
|
* the returned `records` will have properties `customer` and `spend`,
|
|
146
|
-
* one per customer. Specify `totals: true` to also get a `totals` object
|
|
147
|
-
* with only a `spend` property, containing the total spend across all
|
|
171
|
+
* one per customer. Specify `totals: true` to also get a `totals` object
|
|
172
|
+
* with only a `spend` property, containing the total spend across all
|
|
148
173
|
* customers.
|
|
149
174
|
*/
|
|
150
175
|
totals?: boolean;
|
|
@@ -157,10 +182,10 @@ export interface Query<S extends QuerySelect> {
|
|
|
157
182
|
*/
|
|
158
183
|
take?: number;
|
|
159
184
|
/**
|
|
160
|
-
* A string to insert in a comment at the start of the generated SQL.
|
|
161
|
-
*
|
|
162
|
-
* This will be aggressively processed to remove the danger of injection
|
|
163
|
-
* attacks, so anything other than alpha, numeric, new line or CR
|
|
185
|
+
* A string to insert in a comment at the start of the generated SQL.
|
|
186
|
+
*
|
|
187
|
+
* This will be aggressively processed to remove the danger of injection
|
|
188
|
+
* attacks, so anything other than alpha, numeric, new line or CR
|
|
164
189
|
* characters will be replaced with space.
|
|
165
190
|
*/
|
|
166
191
|
comment?: string;
|