taon-type-sql 21.0.11 → 21.0.15
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/browser/package.json +1 -1
- package/browser-prod/README.md +24 -0
- package/browser-prod/fesm2022/taon-type-sql-browser.mjs +859 -0
- package/browser-prod/fesm2022/taon-type-sql-browser.mjs.map +1 -0
- package/browser-prod/types/taon-type-sql-browser.d.ts +254 -0
- package/lib/build-info._auto-generated_.d.ts +5 -1
- package/lib/build-info._auto-generated_.js +6 -2
- package/lib/build-info._auto-generated_.js.map +1 -1
- package/lib/env/env.angular-node-app.d.ts +30 -29
- package/lib/env/env.angular-node-app.js +32 -31
- package/lib/env/env.angular-node-app.js.map +1 -1
- package/lib/env/env.docs-webapp.d.ts +30 -29
- package/lib/env/env.docs-webapp.js +32 -31
- package/lib/env/env.docs-webapp.js.map +1 -1
- package/lib/env/env.electron-app.d.ts +30 -29
- package/lib/env/env.electron-app.js +32 -31
- package/lib/env/env.electron-app.js.map +1 -1
- package/lib/env/env.mobile-app.d.ts +30 -29
- package/lib/env/env.mobile-app.js +32 -31
- package/lib/env/env.mobile-app.js.map +1 -1
- package/lib/env/env.npm-lib-and-cli-tool.d.ts +30 -29
- package/lib/env/env.npm-lib-and-cli-tool.js +32 -31
- package/lib/env/env.npm-lib-and-cli-tool.js.map +1 -1
- package/lib/env/env.vscode-plugin.d.ts +30 -29
- package/lib/env/env.vscode-plugin.js +32 -31
- package/lib/env/env.vscode-plugin.js.map +1 -1
- package/lib/index._auto-generated_.js +1 -1
- package/lib/index._auto-generated_.js.map +1 -1
- package/lib-prod/build-info._auto-generated_.d.ts +24 -0
- package/lib-prod/build-info._auto-generated_.js +30 -0
- package/lib-prod/build-info._auto-generated_.js.map +1 -0
- package/lib-prod/builder/column/basic-column.d.ts +8 -0
- package/lib-prod/builder/column/basic-column.js +15 -0
- package/lib-prod/builder/column/basic-column.js.map +1 -0
- package/lib-prod/builder/column/boolean-column.d.ts +9 -0
- package/lib-prod/builder/column/boolean-column.js +15 -0
- package/lib-prod/builder/column/boolean-column.js.map +1 -0
- package/lib-prod/builder/column/comparable-column.d.ts +18 -0
- package/lib-prod/builder/column/comparable-column.js +42 -0
- package/lib-prod/builder/column/comparable-column.js.map +1 -0
- package/lib-prod/builder/column/date-column.d.ts +9 -0
- package/lib-prod/builder/column/date-column.js +15 -0
- package/lib-prod/builder/column/date-column.js.map +1 -0
- package/lib-prod/builder/column/number-column.d.ts +10 -0
- package/lib-prod/builder/column/number-column.js +20 -0
- package/lib-prod/builder/column/number-column.js.map +1 -0
- package/lib-prod/builder/column/query-column.d.ts +18 -0
- package/lib-prod/builder/column/query-column.js +26 -0
- package/lib-prod/builder/column/query-column.js.map +1 -0
- package/lib-prod/builder/column/string-column.d.ts +17 -0
- package/lib-prod/builder/column/string-column.js +37 -0
- package/lib-prod/builder/column/string-column.js.map +1 -0
- package/lib-prod/builder/column/value-column.d.ts +15 -0
- package/lib-prod/builder/column/value-column.js +30 -0
- package/lib-prod/builder/column/value-column.js.map +1 -0
- package/lib-prod/builder/condition/query-column-condition.d.ts +13 -0
- package/lib-prod/builder/condition/query-column-condition.js +23 -0
- package/lib-prod/builder/condition/query-column-condition.js.map +1 -0
- package/lib-prod/builder/condition/query-condition-chain.d.ts +17 -0
- package/lib-prod/builder/condition/query-condition-chain.js +34 -0
- package/lib-prod/builder/condition/query-condition-chain.js.map +1 -0
- package/lib-prod/builder/condition/query-condition.d.ts +7 -0
- package/lib-prod/builder/condition/query-condition.js +7 -0
- package/lib-prod/builder/condition/query-condition.js.map +1 -0
- package/lib-prod/builder/condition/query-join-condition.d.ts +12 -0
- package/lib-prod/builder/condition/query-join-condition.js +23 -0
- package/lib-prod/builder/condition/query-join-condition.js.map +1 -0
- package/lib-prod/builder/helpers/generics-helper.d.ts +2 -0
- package/lib-prod/builder/helpers/generics-helper.js +7 -0
- package/lib-prod/builder/helpers/generics-helper.js.map +1 -0
- package/lib-prod/builder/helpers/internal-types.d.ts +15 -0
- package/lib-prod/builder/helpers/internal-types.js +4 -0
- package/lib-prod/builder/helpers/internal-types.js.map +1 -0
- package/lib-prod/builder/join/joined-tables-chain.d.ts +11 -0
- package/lib-prod/builder/join/joined-tables-chain.js +18 -0
- package/lib-prod/builder/join/joined-tables-chain.js.map +1 -0
- package/lib-prod/builder/join/joined-tables.d.ts +12 -0
- package/lib-prod/builder/join/joined-tables.js +25 -0
- package/lib-prod/builder/join/joined-tables.js.map +1 -0
- package/lib-prod/builder/other/query-ordering.d.ts +10 -0
- package/lib-prod/builder/other/query-ordering.js +21 -0
- package/lib-prod/builder/other/query-ordering.js.map +1 -0
- package/lib-prod/builder/query/select-query.d.ts +29 -0
- package/lib-prod/builder/query/select-query.js +54 -0
- package/lib-prod/builder/query/select-query.js.map +1 -0
- package/lib-prod/builder/query/table-condition-query.d.ts +16 -0
- package/lib-prod/builder/query/table-condition-query.js +31 -0
- package/lib-prod/builder/query/table-condition-query.js.map +1 -0
- package/lib-prod/builder/query/table-query.d.ts +23 -0
- package/lib-prod/builder/query/table-query.js +60 -0
- package/lib-prod/builder/query/table-query.js.map +1 -0
- package/lib-prod/builder/query-source.d.ts +14 -0
- package/lib-prod/builder/query-source.js +22 -0
- package/lib-prod/builder/query-source.js.map +1 -0
- package/lib-prod/builder/query-table.d.ts +15 -0
- package/lib-prod/builder/query-table.js +28 -0
- package/lib-prod/builder/query-table.js.map +1 -0
- package/lib-prod/client/mysql.d.ts +5 -0
- package/lib-prod/client/mysql.js +11 -0
- package/lib-prod/client/mysql.js.map +1 -0
- package/lib-prod/client/pg.d.ts +5 -0
- package/lib-prod/client/pg.js +11 -0
- package/lib-prod/client/pg.js.map +1 -0
- package/lib-prod/client/query-processor.d.ts +10 -0
- package/lib-prod/client/query-processor.js +73 -0
- package/lib-prod/client/query-processor.js.map +1 -0
- package/lib-prod/converter/param-converter.d.ts +2 -0
- package/lib-prod/converter/param-converter.js +31 -0
- package/lib-prod/converter/param-converter.js.map +1 -0
- package/lib-prod/converter/parameterized-converter.d.ts +5 -0
- package/lib-prod/converter/parameterized-converter.js +18 -0
- package/lib-prod/converter/parameterized-converter.js.map +1 -0
- package/lib-prod/converter/query-converter.d.ts +2 -0
- package/lib-prod/converter/query-converter.js +284 -0
- package/lib-prod/converter/query-converter.js.map +1 -0
- package/lib-prod/converter/result-converter.d.ts +2 -0
- package/lib-prod/converter/result-converter.js +89 -0
- package/lib-prod/converter/result-converter.js.map +1 -0
- package/lib-prod/converter/sql-converter.d.ts +2 -0
- package/lib-prod/converter/sql-converter.js +9 -0
- package/lib-prod/converter/sql-converter.js.map +1 -0
- package/lib-prod/converter/type-converter.d.ts +4 -0
- package/lib-prod/converter/type-converter.js +43 -0
- package/lib-prod/converter/type-converter.js.map +1 -0
- package/lib-prod/converter/types.d.ts +5 -0
- package/lib-prod/converter/types.js +3 -0
- package/lib-prod/converter/types.js.map +1 -0
- package/lib-prod/env/env.angular-node-app.d.ts +64 -0
- package/lib-prod/env/env.angular-node-app.js +71 -0
- package/lib-prod/env/env.angular-node-app.js.map +1 -0
- package/lib-prod/env/env.docs-webapp.d.ts +64 -0
- package/lib-prod/env/env.docs-webapp.js +71 -0
- package/lib-prod/env/env.docs-webapp.js.map +1 -0
- package/lib-prod/env/env.electron-app.d.ts +64 -0
- package/lib-prod/env/env.electron-app.js +71 -0
- package/lib-prod/env/env.electron-app.js.map +1 -0
- package/lib-prod/env/env.mobile-app.d.ts +64 -0
- package/lib-prod/env/env.mobile-app.js +71 -0
- package/lib-prod/env/env.mobile-app.js.map +1 -0
- package/lib-prod/env/env.npm-lib-and-cli-tool.d.ts +64 -0
- package/lib-prod/env/env.npm-lib-and-cli-tool.js +71 -0
- package/lib-prod/env/env.npm-lib-and-cli-tool.js.map +1 -0
- package/lib-prod/env/env.vscode-plugin.d.ts +64 -0
- package/lib-prod/env/env.vscode-plugin.js +71 -0
- package/lib-prod/env/env.vscode-plugin.js.map +1 -0
- package/lib-prod/env/index.d.ts +6 -0
- package/lib-prod/env/index.js +23 -0
- package/lib-prod/env/index.js.map +1 -0
- package/lib-prod/index._auto-generated_.d.ts +0 -0
- package/lib-prod/index._auto-generated_.js +6 -0
- package/lib-prod/index._auto-generated_.js.map +1 -0
- package/lib-prod/index.d.ts +25 -0
- package/lib-prod/index.js +48 -0
- package/lib-prod/index.js.map +1 -0
- package/package.json +2 -1
- package/tmp-environment.json +9 -5
- package/websql/package.json +1 -1
- package/websql-prod/README.md +24 -0
- package/websql-prod/fesm2022/taon-type-sql-websql.mjs +859 -0
- package/websql-prod/fesm2022/taon-type-sql-websql.mjs.map +1 -0
- package/websql-prod/types/taon-type-sql-websql.d.ts +254 -0
|
@@ -0,0 +1,859 @@
|
|
|
1
|
+
import { Log } from 'ng2-logger/browser-prod';
|
|
2
|
+
|
|
3
|
+
// TODO I had to copy-paste the method implementations to every child class to avoid circular dependencies
|
|
4
|
+
class QueryCondition {
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
class QueryConditionChain extends QueryCondition {
|
|
8
|
+
constructor(sibling, child, chainType) {
|
|
9
|
+
super();
|
|
10
|
+
this._parenthesis = false;
|
|
11
|
+
this._negation = false;
|
|
12
|
+
this._sibling = sibling;
|
|
13
|
+
this._child = child;
|
|
14
|
+
this._chainType = chainType;
|
|
15
|
+
}
|
|
16
|
+
// TODO how to call this
|
|
17
|
+
$() {
|
|
18
|
+
this._parenthesis = true;
|
|
19
|
+
return this;
|
|
20
|
+
}
|
|
21
|
+
not() {
|
|
22
|
+
this._negation = true;
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
and(condition) {
|
|
26
|
+
return new QueryConditionChain(this, condition, 'and');
|
|
27
|
+
}
|
|
28
|
+
or(condition) {
|
|
29
|
+
return new QueryConditionChain(this, condition, 'or');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
class QueryColumnCondition extends QueryCondition {
|
|
34
|
+
constructor(column, type, ...values) {
|
|
35
|
+
super();
|
|
36
|
+
this._column = column;
|
|
37
|
+
this._type = type;
|
|
38
|
+
this._values = values;
|
|
39
|
+
}
|
|
40
|
+
and(condition) {
|
|
41
|
+
return new QueryConditionChain(this, condition, 'and');
|
|
42
|
+
}
|
|
43
|
+
or(condition) {
|
|
44
|
+
return new QueryConditionChain(this, condition, 'or');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
class QueryColumn {
|
|
49
|
+
constructor(_table, _name, _modifiers = []) {
|
|
50
|
+
this._table = _table;
|
|
51
|
+
this._name = _name;
|
|
52
|
+
this._modifiers = _modifiers;
|
|
53
|
+
}
|
|
54
|
+
as(alias) {
|
|
55
|
+
return new this.constructor(this._table, this._name, this._modifiers.concat({ name: 'as', params: alias }));
|
|
56
|
+
}
|
|
57
|
+
isNull() {
|
|
58
|
+
return new QueryColumnCondition(this, 'is-null');
|
|
59
|
+
}
|
|
60
|
+
isNotNull() {
|
|
61
|
+
return new QueryColumnCondition(this, 'is-not-null');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
class QueryOrdering {
|
|
66
|
+
constructor(column, direction) {
|
|
67
|
+
this._column = column;
|
|
68
|
+
this._direction = direction;
|
|
69
|
+
}
|
|
70
|
+
nullsFirst() {
|
|
71
|
+
this._nullsPosition = 'FIRST';
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
nullsLast() {
|
|
75
|
+
this._nullsPosition = 'LAST';
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
class QueryJoinCondition extends QueryCondition {
|
|
81
|
+
constructor(column, type, otherColumn) {
|
|
82
|
+
super();
|
|
83
|
+
this._column = column;
|
|
84
|
+
this._type = type;
|
|
85
|
+
this._otherColumn = otherColumn;
|
|
86
|
+
}
|
|
87
|
+
and(condition) {
|
|
88
|
+
return new QueryConditionChain(this, condition, 'and');
|
|
89
|
+
}
|
|
90
|
+
or(condition) {
|
|
91
|
+
return new QueryConditionChain(this, condition, 'or');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
class ValueColumn extends QueryColumn {
|
|
96
|
+
constructor(table, name, modifiers = []) {
|
|
97
|
+
super(table, name, modifiers);
|
|
98
|
+
}
|
|
99
|
+
asc() {
|
|
100
|
+
return new QueryOrdering(this, 'ASC');
|
|
101
|
+
}
|
|
102
|
+
desc() {
|
|
103
|
+
return new QueryOrdering(this, 'DESC');
|
|
104
|
+
}
|
|
105
|
+
eq(value) {
|
|
106
|
+
if (value instanceof QueryColumn) {
|
|
107
|
+
return new QueryJoinCondition(this, 'eq', value);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
return new QueryColumnCondition(this, 'eq', value);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
ne(value) {
|
|
114
|
+
return new QueryColumnCondition(this, 'ne', value);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
class ComparableColumn extends ValueColumn {
|
|
119
|
+
constructor(table, name, modifiers = []) {
|
|
120
|
+
super(table, name, modifiers);
|
|
121
|
+
}
|
|
122
|
+
lt(value) {
|
|
123
|
+
return new QueryColumnCondition(this, 'lt', value);
|
|
124
|
+
}
|
|
125
|
+
gt(value) {
|
|
126
|
+
return new QueryColumnCondition(this, 'gt', value);
|
|
127
|
+
}
|
|
128
|
+
lte(value) {
|
|
129
|
+
return new QueryColumnCondition(this, 'lte', value);
|
|
130
|
+
}
|
|
131
|
+
gte(value) {
|
|
132
|
+
return new QueryColumnCondition(this, 'gte', value);
|
|
133
|
+
}
|
|
134
|
+
in(values) {
|
|
135
|
+
return new QueryColumnCondition(this, 'in', ...values);
|
|
136
|
+
}
|
|
137
|
+
notIn(values) {
|
|
138
|
+
return new QueryColumnCondition(this, 'not-in', ...values);
|
|
139
|
+
}
|
|
140
|
+
between(value1, value2) {
|
|
141
|
+
return new QueryColumnCondition(this, 'between', value1, value2);
|
|
142
|
+
}
|
|
143
|
+
notBetween(value1, value2) {
|
|
144
|
+
return new QueryColumnCondition(this, 'not-between', value1, value2);
|
|
145
|
+
}
|
|
146
|
+
// min/max exists for text columns too, not just numeric and date
|
|
147
|
+
min() {
|
|
148
|
+
return new this.constructor(this._table, this._name, this._modifiers.concat({ name: 'min' }));
|
|
149
|
+
}
|
|
150
|
+
max() {
|
|
151
|
+
return new this.constructor(this._table, this._name, this._modifiers.concat({ name: 'max' }));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
class NumberColumn extends ComparableColumn {
|
|
156
|
+
constructor(table, name, modifiers = []) {
|
|
157
|
+
super(table, name, modifiers);
|
|
158
|
+
this._type = 'number';
|
|
159
|
+
}
|
|
160
|
+
count() {
|
|
161
|
+
return new NumberColumn(this._table, this._name, this._modifiers.concat({ name: 'count' }));
|
|
162
|
+
}
|
|
163
|
+
sum() {
|
|
164
|
+
return new NumberColumn(this._table, this._name, this._modifiers.concat({ name: 'sum' }));
|
|
165
|
+
}
|
|
166
|
+
avg() {
|
|
167
|
+
return new NumberColumn(this._table, this._name, this._modifiers.concat({ name: 'avg' }));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// This file is only needed because the QueryColumn can't implement its count method b. of circular dependencies
|
|
172
|
+
class BasicColumn extends QueryColumn {
|
|
173
|
+
constructor(table, name, modifiers = []) {
|
|
174
|
+
super(table, name, modifiers);
|
|
175
|
+
}
|
|
176
|
+
count() {
|
|
177
|
+
return new NumberColumn(this._table, this._name, this._modifiers.concat({ name: 'count' }));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
class BooleanColumn extends ValueColumn {
|
|
182
|
+
constructor(table, name, modifiers = []) {
|
|
183
|
+
super(table, name, modifiers);
|
|
184
|
+
this._type = 'boolean';
|
|
185
|
+
}
|
|
186
|
+
count() {
|
|
187
|
+
return new NumberColumn(this._table, this._name, this._modifiers.concat({ name: 'count' }));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
class DateColumn extends ComparableColumn {
|
|
192
|
+
constructor(table, name, modifiers = []) {
|
|
193
|
+
super(table, name, modifiers);
|
|
194
|
+
this._type = 'date';
|
|
195
|
+
}
|
|
196
|
+
count() {
|
|
197
|
+
return new NumberColumn(this._table, this._name, this._modifiers.concat({ name: 'count' }));
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
class StringColumn extends ComparableColumn {
|
|
202
|
+
constructor(table, name, modifiers = []) {
|
|
203
|
+
super(table, name, modifiers);
|
|
204
|
+
this._type = 'string';
|
|
205
|
+
}
|
|
206
|
+
count() {
|
|
207
|
+
return new NumberColumn(this._table, this._name, this._modifiers.concat({ name: 'count' }));
|
|
208
|
+
}
|
|
209
|
+
lower() {
|
|
210
|
+
return new this.constructor(this._table, this._name, this._modifiers.concat({ name: 'lower' }));
|
|
211
|
+
}
|
|
212
|
+
upper() {
|
|
213
|
+
return new this.constructor(this._table, this._name, this._modifiers.concat({ name: 'upper' }));
|
|
214
|
+
}
|
|
215
|
+
contains(value) {
|
|
216
|
+
return this.like('%' + value + '%');
|
|
217
|
+
}
|
|
218
|
+
startsWith(value) {
|
|
219
|
+
return this.like(value + '%');
|
|
220
|
+
}
|
|
221
|
+
endsWith(value) {
|
|
222
|
+
return this.like('%' + value);
|
|
223
|
+
}
|
|
224
|
+
like(value) {
|
|
225
|
+
return new QueryColumnCondition(this, 'like', value);
|
|
226
|
+
}
|
|
227
|
+
notLike(value) {
|
|
228
|
+
return new QueryColumnCondition(this, 'not-like', value);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
class JoinedTablesChain {
|
|
233
|
+
constructor(_table, _modifier, _parent) {
|
|
234
|
+
this._table = _table;
|
|
235
|
+
this._modifier = _modifier;
|
|
236
|
+
this._parent = _parent;
|
|
237
|
+
}
|
|
238
|
+
on(condition) {
|
|
239
|
+
return new JoinedTables(condition, this);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
class JoinedTables {
|
|
244
|
+
constructor(_condition, _parent) {
|
|
245
|
+
this._condition = _condition;
|
|
246
|
+
this._parent = _parent;
|
|
247
|
+
}
|
|
248
|
+
innerJoin(table) {
|
|
249
|
+
return new JoinedTablesChain(table, 'inner', this);
|
|
250
|
+
}
|
|
251
|
+
leftJoin(table) {
|
|
252
|
+
return new JoinedTablesChain(table, 'left', this);
|
|
253
|
+
}
|
|
254
|
+
rightJoin(table) {
|
|
255
|
+
return new JoinedTablesChain(table, 'right', this);
|
|
256
|
+
}
|
|
257
|
+
fullJoin(table) {
|
|
258
|
+
return new JoinedTablesChain(table, 'full', this);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
class SelectQuery {
|
|
263
|
+
constructor(_queryProcessor, _tables) {
|
|
264
|
+
this._queryProcessor = _queryProcessor;
|
|
265
|
+
this._tables = _tables;
|
|
266
|
+
this._distinct = false;
|
|
267
|
+
this._conditions = [];
|
|
268
|
+
this._groupBy = [];
|
|
269
|
+
this._having = [];
|
|
270
|
+
this._orderings = [];
|
|
271
|
+
this._columns = [];
|
|
272
|
+
}
|
|
273
|
+
offset(offset) {
|
|
274
|
+
this._offset = offset;
|
|
275
|
+
return this;
|
|
276
|
+
}
|
|
277
|
+
limit(limit) {
|
|
278
|
+
this._limit = limit;
|
|
279
|
+
return this;
|
|
280
|
+
}
|
|
281
|
+
distinct() {
|
|
282
|
+
this._distinct = true;
|
|
283
|
+
return this;
|
|
284
|
+
}
|
|
285
|
+
where(...conditions) {
|
|
286
|
+
this._conditions = conditions;
|
|
287
|
+
return this;
|
|
288
|
+
}
|
|
289
|
+
groupBy(...columns) {
|
|
290
|
+
this._groupBy = columns;
|
|
291
|
+
return this;
|
|
292
|
+
}
|
|
293
|
+
having(...conditions) {
|
|
294
|
+
this._having = conditions;
|
|
295
|
+
return this;
|
|
296
|
+
}
|
|
297
|
+
orderBy(...orderings) {
|
|
298
|
+
this._orderings = orderings;
|
|
299
|
+
return this;
|
|
300
|
+
}
|
|
301
|
+
select(...columns) {
|
|
302
|
+
this._columns = columns;
|
|
303
|
+
this._action = 'select';
|
|
304
|
+
return this._queryProcessor(this);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
class TableConditionQuery {
|
|
309
|
+
constructor(_queryProcessor, _table, _conditions) {
|
|
310
|
+
this._queryProcessor = _queryProcessor;
|
|
311
|
+
this._table = _table;
|
|
312
|
+
this._conditions = _conditions;
|
|
313
|
+
this._columns = [];
|
|
314
|
+
}
|
|
315
|
+
update(entity) {
|
|
316
|
+
this._entity = entity;
|
|
317
|
+
this._action = 'update';
|
|
318
|
+
return this._queryProcessor(this);
|
|
319
|
+
}
|
|
320
|
+
delete() {
|
|
321
|
+
this._action = 'delete';
|
|
322
|
+
return this._queryProcessor(this);
|
|
323
|
+
}
|
|
324
|
+
count() {
|
|
325
|
+
this._columns = [this._table.$all.count()];
|
|
326
|
+
this._action = 'select';
|
|
327
|
+
return this._queryProcessor(this).then((rows) => rows[0]);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
class TableQuery {
|
|
332
|
+
constructor(_queryProcessor, _table) {
|
|
333
|
+
this._queryProcessor = _queryProcessor;
|
|
334
|
+
this._table = _table;
|
|
335
|
+
this._columns = [];
|
|
336
|
+
}
|
|
337
|
+
where(...conditions) {
|
|
338
|
+
return new TableConditionQuery(this._queryProcessor, this._table, conditions);
|
|
339
|
+
}
|
|
340
|
+
insert(param) {
|
|
341
|
+
this._entity = param;
|
|
342
|
+
this._action = 'insert';
|
|
343
|
+
return this._queryProcessor(this);
|
|
344
|
+
}
|
|
345
|
+
deleteAll() {
|
|
346
|
+
this._action = 'delete';
|
|
347
|
+
return this._queryProcessor(this);
|
|
348
|
+
}
|
|
349
|
+
updateAll(entity) {
|
|
350
|
+
this._entity = entity;
|
|
351
|
+
this._action = 'update';
|
|
352
|
+
return this._queryProcessor(this);
|
|
353
|
+
}
|
|
354
|
+
countAll() {
|
|
355
|
+
this._columns = [this._table.$all.count()];
|
|
356
|
+
this._action = 'select';
|
|
357
|
+
return this._queryProcessor(this).then((rows) => rows[0]);
|
|
358
|
+
}
|
|
359
|
+
delete(id) {
|
|
360
|
+
return this._whereId(id).delete().then(count => count > 0);
|
|
361
|
+
}
|
|
362
|
+
update(id, entity) {
|
|
363
|
+
return this._whereId(id).update(entity).then(count => count > 0);
|
|
364
|
+
}
|
|
365
|
+
get(id) {
|
|
366
|
+
let query = this._whereId(id);
|
|
367
|
+
return this._queryProcessor({ _action: 'select', ...query })
|
|
368
|
+
.then((rows) => rows[0]);
|
|
369
|
+
}
|
|
370
|
+
_whereId(id) {
|
|
371
|
+
// TODO remove assertions if $id typing is fixed
|
|
372
|
+
let $id = this._table.$id;
|
|
373
|
+
if ($id instanceof ValueColumn) {
|
|
374
|
+
return this.where($id.eq(id));
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
return this.where(...Object.keys($id).map(key => this._table[key].eq(id[key])));
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
class QuerySource {
|
|
383
|
+
constructor(_queryProcessor) {
|
|
384
|
+
this._queryProcessor = _queryProcessor;
|
|
385
|
+
}
|
|
386
|
+
from(table1, table2, table3) {
|
|
387
|
+
if (table3 != null)
|
|
388
|
+
return new SelectQuery(this._queryProcessor, [table1, table2, table3]);
|
|
389
|
+
else if (table2 != null)
|
|
390
|
+
return new SelectQuery(this._queryProcessor, [table1, table2]);
|
|
391
|
+
return new SelectQuery(this._queryProcessor, [table1]);
|
|
392
|
+
}
|
|
393
|
+
table(table) {
|
|
394
|
+
return new TableQuery(this._queryProcessor, table);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
class QueryTable {
|
|
399
|
+
constructor(_$name) {
|
|
400
|
+
this._$name = _$name;
|
|
401
|
+
// abstract readonly $id; // FIXME I got a dozen incomprehensible type errors
|
|
402
|
+
this.$all = new BasicColumn(this, '*');
|
|
403
|
+
}
|
|
404
|
+
innerJoin(table) {
|
|
405
|
+
return new JoinedTablesChain(table, 'inner', this);
|
|
406
|
+
}
|
|
407
|
+
leftJoin(table) {
|
|
408
|
+
return new JoinedTablesChain(table, 'left', this);
|
|
409
|
+
}
|
|
410
|
+
rightJoin(table) {
|
|
411
|
+
return new JoinedTablesChain(table, 'right', this);
|
|
412
|
+
}
|
|
413
|
+
fullJoin(table) {
|
|
414
|
+
return new JoinedTablesChain(table, 'full', this);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
function number(param) {
|
|
419
|
+
let result = Number(param);
|
|
420
|
+
if (Number.isNaN(result))
|
|
421
|
+
throw new Error('Invalid number parameter in SQL query: ' + param);
|
|
422
|
+
return result;
|
|
423
|
+
}
|
|
424
|
+
function boolean(param) {
|
|
425
|
+
if (typeof param === 'boolean')
|
|
426
|
+
return param;
|
|
427
|
+
if (param instanceof Boolean)
|
|
428
|
+
return param.valueOf();
|
|
429
|
+
if (param === 'true')
|
|
430
|
+
return true;
|
|
431
|
+
if (param === 'false')
|
|
432
|
+
return false;
|
|
433
|
+
throw new Error('Invalid boolean parameter in SQL query: ' + param);
|
|
434
|
+
}
|
|
435
|
+
function date(param) {
|
|
436
|
+
if (param instanceof Date)
|
|
437
|
+
return param; // @ts-ignore
|
|
438
|
+
if (typeof param === 'number' || param instanceof Number)
|
|
439
|
+
return new Date(param);
|
|
440
|
+
if (typeof param === 'string' || param instanceof String) {
|
|
441
|
+
if (Number.isNaN(Date.parse(String(param))))
|
|
442
|
+
throw new Error('Invalid date parameter in SQL query: ' + param); // @ts-ignore
|
|
443
|
+
return new Date(param);
|
|
444
|
+
}
|
|
445
|
+
throw new Error('Invalid date parameter in SQL query: ' + param);
|
|
446
|
+
}
|
|
447
|
+
function string(param) {
|
|
448
|
+
if (typeof param === 'string')
|
|
449
|
+
return param;
|
|
450
|
+
if (param instanceof String)
|
|
451
|
+
return param.valueOf();
|
|
452
|
+
throw new Error('Invalid string parameter in SQL query: ' + param);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
function createQueryConverter(paramConverter, options, engine) {
|
|
456
|
+
return convertQuery;
|
|
457
|
+
function convertQuery(query) {
|
|
458
|
+
if (query._action === 'select')
|
|
459
|
+
return convertSelectQuery(query);
|
|
460
|
+
if (query._action === 'delete')
|
|
461
|
+
return convertDeleteQuery(query);
|
|
462
|
+
if (query._action === 'update')
|
|
463
|
+
return convertUpdateQuery(query);
|
|
464
|
+
if (query._action === 'insert')
|
|
465
|
+
return convertInsertQuery(query);
|
|
466
|
+
throw new Error('Unknown query type:' + query._action);
|
|
467
|
+
}
|
|
468
|
+
function convertDeleteQuery(query) {
|
|
469
|
+
let s = 'DELETE FROM ' + convertTable(query._table);
|
|
470
|
+
s += convertConditions(query._conditions);
|
|
471
|
+
return s;
|
|
472
|
+
}
|
|
473
|
+
function convertUpdateQuery(query) {
|
|
474
|
+
let s = 'UPDATE ' + convertTable(query._table) + ' SET ';
|
|
475
|
+
s += convertUpdateSetters(query._table, query._entity);
|
|
476
|
+
s += convertConditions(query._conditions);
|
|
477
|
+
return s;
|
|
478
|
+
}
|
|
479
|
+
function convertUpdateSetters(table, entity) {
|
|
480
|
+
return Object.keys(entity).sort().map(key => {
|
|
481
|
+
let value = entity[key];
|
|
482
|
+
let column = table[key];
|
|
483
|
+
return convertColumnName(column) + ' = ' + convertParam(column, value);
|
|
484
|
+
}).join(', ');
|
|
485
|
+
}
|
|
486
|
+
function convertInsertQuery(query) {
|
|
487
|
+
let items = Array.isArray(query._entity) ? query._entity : [query._entity];
|
|
488
|
+
let keySet = items.reduce((set, item) => {
|
|
489
|
+
Object.keys(item).forEach(key => set.add(key));
|
|
490
|
+
return set;
|
|
491
|
+
}, new Set());
|
|
492
|
+
let keys = Array.from(keySet).sort();
|
|
493
|
+
let s = 'INSERT INTO ' + convertTable(query._table) + ' ';
|
|
494
|
+
s += '(' + keys.map(key => convertColumnName(query._table[key])).join(', ') + ')';
|
|
495
|
+
s += options.lineBreak + 'VALUES ';
|
|
496
|
+
s += items.map(item => convertInsertItem(query._table, item, keys))
|
|
497
|
+
.map((row) => '(' + row + ')').join(', ');
|
|
498
|
+
s += getPgInsertReturningIfNeeded(query);
|
|
499
|
+
return s;
|
|
500
|
+
}
|
|
501
|
+
function getPgInsertReturningIfNeeded(query) {
|
|
502
|
+
if (engine === 'pg' && query._action === 'insert' && !Array.isArray(query._entity) &&
|
|
503
|
+
query._table.$id && query._table.$id._table && query._table.$id._name) {
|
|
504
|
+
return ' RETURNING ' + convertColumnName(query._table.$id);
|
|
505
|
+
}
|
|
506
|
+
return '';
|
|
507
|
+
}
|
|
508
|
+
function convertInsertItem(table, entity, keys) {
|
|
509
|
+
return keys.map(key => {
|
|
510
|
+
let value = entity[key];
|
|
511
|
+
let column = table[key];
|
|
512
|
+
return convertParam(column, value);
|
|
513
|
+
}).join(', ');
|
|
514
|
+
}
|
|
515
|
+
function convertSelectQuery(query) {
|
|
516
|
+
let s = 'SELECT ';
|
|
517
|
+
if (query._distinct) {
|
|
518
|
+
s += 'DISTINCT ';
|
|
519
|
+
}
|
|
520
|
+
if (query._columns == null || query._columns.length === 0) {
|
|
521
|
+
s += '*';
|
|
522
|
+
}
|
|
523
|
+
else {
|
|
524
|
+
s += query._columns.map((column) => convertColumn(column)).join(', ');
|
|
525
|
+
}
|
|
526
|
+
s += options.lineBreak + 'FROM ';
|
|
527
|
+
if (query._tables) {
|
|
528
|
+
s += query._tables.map((table) => table._parent ? convertJoin(table) : convertTable(table)).join(', ');
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
s += convertTable(query._table);
|
|
532
|
+
}
|
|
533
|
+
s += convertConditions(query._conditions);
|
|
534
|
+
if (query._groupBy && query._groupBy.length > 0) {
|
|
535
|
+
s += options.lineBreak + 'GROUP BY ';
|
|
536
|
+
s += query._groupBy.map((column) => convertColumn(column)).join(', ');
|
|
537
|
+
}
|
|
538
|
+
s += convertConditions(query._having, 'HAVING');
|
|
539
|
+
if (query._orderings && query._orderings.length > 0) {
|
|
540
|
+
s += options.lineBreak + 'ORDER BY ';
|
|
541
|
+
s += query._orderings.map((ordering) => convertOrdering(ordering)).join(', ');
|
|
542
|
+
}
|
|
543
|
+
if (query._limit != null) {
|
|
544
|
+
s += options.lineBreak + 'LIMIT ' + number(query._limit);
|
|
545
|
+
}
|
|
546
|
+
if (query._offset != null) {
|
|
547
|
+
s += options.lineBreak + 'OFFSET ' + number(query._offset);
|
|
548
|
+
}
|
|
549
|
+
return s;
|
|
550
|
+
}
|
|
551
|
+
function convertConditions(conditions, keyword = 'WHERE') {
|
|
552
|
+
let s = '';
|
|
553
|
+
if (conditions && conditions.length > 0) {
|
|
554
|
+
s += options.lineBreak + keyword + ' ';
|
|
555
|
+
preprocessConditions(conditions);
|
|
556
|
+
s += conditions.map(condition => convertCondition(condition, true)).join(' AND ');
|
|
557
|
+
}
|
|
558
|
+
return s;
|
|
559
|
+
}
|
|
560
|
+
function convertJoin(joinChain) {
|
|
561
|
+
let items = [];
|
|
562
|
+
while (joinChain) {
|
|
563
|
+
items.push(joinChain);
|
|
564
|
+
joinChain = joinChain._parent;
|
|
565
|
+
}
|
|
566
|
+
let root = items[items.length - 1];
|
|
567
|
+
let s = convertTable(root);
|
|
568
|
+
for (let i = items.length - 2; i >= 0; i -= 2) {
|
|
569
|
+
let table = items[i]._table;
|
|
570
|
+
let modifier = items[i]._modifier;
|
|
571
|
+
let condition = items[i - 1]._condition;
|
|
572
|
+
let param = convertColumn(condition._otherColumn);
|
|
573
|
+
s += ' ' + modifier.toUpperCase() + ' JOIN ' + convertTable(table) + ' ON ' +
|
|
574
|
+
convertColumnCondition(condition, param);
|
|
575
|
+
}
|
|
576
|
+
return s;
|
|
577
|
+
}
|
|
578
|
+
function convertOrdering(ordering) {
|
|
579
|
+
if (ordering._column) {
|
|
580
|
+
let s = convertColumn(ordering._column);
|
|
581
|
+
if (ordering._nullsPosition != null) { // "NULLS FIRST" only exists in PG, this is the general solution
|
|
582
|
+
s += ' IS NULL ' + (ordering._nullsPosition === 'FIRST' ? 'DESC' : 'ASC') + ', ' + s;
|
|
583
|
+
}
|
|
584
|
+
if (ordering._direction === 'ASC')
|
|
585
|
+
s += ' ASC';
|
|
586
|
+
if (ordering._direction === 'DESC')
|
|
587
|
+
s += ' DESC';
|
|
588
|
+
return s;
|
|
589
|
+
}
|
|
590
|
+
else {
|
|
591
|
+
return convertColumn(ordering);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
function convertTable(table) {
|
|
595
|
+
return options.nameEscape + table._$name + options.nameEscape;
|
|
596
|
+
}
|
|
597
|
+
function convertColumn(column) {
|
|
598
|
+
let s = '';
|
|
599
|
+
if (!(column._name === '*' && column._modifiers.length > 0 && column._modifiers[0].name === 'count')) {
|
|
600
|
+
s += convertTable(column._table) + '.';
|
|
601
|
+
}
|
|
602
|
+
s += convertColumnName(column);
|
|
603
|
+
return convertColumnModifiers(s, column);
|
|
604
|
+
}
|
|
605
|
+
function convertColumnModifiers(s, column) {
|
|
606
|
+
if (column._modifiers) {
|
|
607
|
+
column._modifiers.forEach((modifier) => {
|
|
608
|
+
let name = modifier.name;
|
|
609
|
+
if (name === 'lower')
|
|
610
|
+
s = 'LOWER(' + s + ')';
|
|
611
|
+
else if (name === 'upper')
|
|
612
|
+
s = 'UPPER(' + s + ')';
|
|
613
|
+
else if (name === 'count')
|
|
614
|
+
s = 'COUNT(' + s + ')';
|
|
615
|
+
else if (name === 'sum')
|
|
616
|
+
s = 'SUM(' + s + ')';
|
|
617
|
+
else if (name === 'avg')
|
|
618
|
+
s = 'AVG(' + s + ')';
|
|
619
|
+
else if (name === 'min')
|
|
620
|
+
s = 'MIN(' + s + ')';
|
|
621
|
+
else if (name === 'max')
|
|
622
|
+
s = 'MAX(' + s + ')';
|
|
623
|
+
else if (name === 'as')
|
|
624
|
+
s = s + ' AS ' + options.nameEscape + modifier.params + options.nameEscape;
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
return s + '';
|
|
628
|
+
}
|
|
629
|
+
function convertColumnName(column) {
|
|
630
|
+
if (column._name === '*')
|
|
631
|
+
return column._name;
|
|
632
|
+
let name = typeof column._name === 'string' ? column._name : column._name.name;
|
|
633
|
+
return options.nameEscape + name + options.nameEscape;
|
|
634
|
+
}
|
|
635
|
+
function preprocessConditions(conditions) {
|
|
636
|
+
conditions.forEach(condition => {
|
|
637
|
+
if (conditions.length > 1 && condition._sibling) {
|
|
638
|
+
condition._parenthesis = true;
|
|
639
|
+
}
|
|
640
|
+
preprocessParams(condition);
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
// this is only needed, so that the $1, $2... numbering is not reversed
|
|
644
|
+
function preprocessParams(condition) {
|
|
645
|
+
if (condition._sibling) {
|
|
646
|
+
preprocessParams(condition._sibling);
|
|
647
|
+
}
|
|
648
|
+
if (!condition._sibling && !condition._child) {
|
|
649
|
+
condition.__param = getConditionParam(condition);
|
|
650
|
+
}
|
|
651
|
+
if (condition._child) {
|
|
652
|
+
preprocessParams(condition._child);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
function convertCondition(condition, root = false) {
|
|
656
|
+
if (!condition._sibling && !condition._child) {
|
|
657
|
+
return convertColumnCondition(condition, condition.__param);
|
|
658
|
+
}
|
|
659
|
+
let s = '';
|
|
660
|
+
if (condition._child) {
|
|
661
|
+
s += convertCondition(condition._child);
|
|
662
|
+
}
|
|
663
|
+
if (condition._sibling) {
|
|
664
|
+
s = convertCondition(condition._sibling, root) + ' ' + condition._chainType.toUpperCase() + ' ' + s;
|
|
665
|
+
}
|
|
666
|
+
if (condition._parenthesis || ((!root || condition._negation) && condition._child)) {
|
|
667
|
+
s = '( ' + s + ' )';
|
|
668
|
+
}
|
|
669
|
+
if (condition._negation) {
|
|
670
|
+
s = 'NOT ' + s;
|
|
671
|
+
}
|
|
672
|
+
return s;
|
|
673
|
+
}
|
|
674
|
+
function convertColumnCondition(condition, param) {
|
|
675
|
+
let s = convertColumn(condition._column);
|
|
676
|
+
s += getConditionString(condition, param);
|
|
677
|
+
return s;
|
|
678
|
+
}
|
|
679
|
+
function getConditionString(condition, param) {
|
|
680
|
+
switch (condition._type) {
|
|
681
|
+
case 'eq': return ' = ' + param;
|
|
682
|
+
case 'ne': return ' <> ' + param;
|
|
683
|
+
case 'lt': return ' < ' + param;
|
|
684
|
+
case 'gt': return ' > ' + param;
|
|
685
|
+
case 'lte': return ' <= ' + param;
|
|
686
|
+
case 'gte': return ' >= ' + param;
|
|
687
|
+
case 'is-null': return ' IS NULL';
|
|
688
|
+
case 'is-not-null': return ' IS NOT NULL';
|
|
689
|
+
case 'like': return ' LIKE ' + param;
|
|
690
|
+
case 'not-like': return ' NOT LIKE ' + param;
|
|
691
|
+
case 'in': return ' IN (' + param + ')';
|
|
692
|
+
case 'not-in': return ' NOT IN (' + param + ')';
|
|
693
|
+
case 'between': return ' BETWEEN ' + param;
|
|
694
|
+
case 'not-between': return ' NOT BETWEEN ' + param;
|
|
695
|
+
default: return '';
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
function getConditionParam(condition) {
|
|
699
|
+
let param = '';
|
|
700
|
+
if (condition._otherColumn) {
|
|
701
|
+
param = convertColumn(condition._otherColumn);
|
|
702
|
+
}
|
|
703
|
+
else {
|
|
704
|
+
let _convertParam = (param) => convertParam(condition._column, param);
|
|
705
|
+
if (condition._type === 'in' || condition._type === 'not-in') {
|
|
706
|
+
param = condition._values.map((value) => _convertParam(value)).join(', ');
|
|
707
|
+
}
|
|
708
|
+
else if (condition._type === 'between' || condition._type === 'not-between') {
|
|
709
|
+
param = _convertParam(condition._values[0]) + ' AND ' + _convertParam(condition._values[1]);
|
|
710
|
+
}
|
|
711
|
+
else if (condition._type !== 'is-null' && condition._type !== 'is-not-null') {
|
|
712
|
+
param = _convertParam(condition._values[0]);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
return param;
|
|
716
|
+
}
|
|
717
|
+
function convertParam(column, param) {
|
|
718
|
+
if (param == null)
|
|
719
|
+
return 'NULL';
|
|
720
|
+
return paramConverter(getTypedParam(column._type, param));
|
|
721
|
+
}
|
|
722
|
+
function getTypedParam(type, param) {
|
|
723
|
+
if (type === 'number')
|
|
724
|
+
return number(param);
|
|
725
|
+
else if (type === 'boolean')
|
|
726
|
+
return boolean(param);
|
|
727
|
+
else if (type === 'date')
|
|
728
|
+
return date(param);
|
|
729
|
+
else if (type === 'string')
|
|
730
|
+
return string(param);
|
|
731
|
+
return param;
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
function convertSubstitutionParam(param) {
|
|
736
|
+
if (param == null)
|
|
737
|
+
return 'NULL';
|
|
738
|
+
if (typeof param === 'string' || param instanceof String) {
|
|
739
|
+
return `'${String(param)}'`;
|
|
740
|
+
}
|
|
741
|
+
else if (typeof param === 'boolean' || param instanceof Boolean) {
|
|
742
|
+
return String(param).toUpperCase();
|
|
743
|
+
}
|
|
744
|
+
else if (param instanceof Date) {
|
|
745
|
+
return `'${param.toISOString()}'`;
|
|
746
|
+
}
|
|
747
|
+
else if (typeof param === 'number' || param instanceof Number) {
|
|
748
|
+
return String(param);
|
|
749
|
+
}
|
|
750
|
+
return `'${JSON.stringify(param)}'`;
|
|
751
|
+
}
|
|
752
|
+
// node mysql doesn't have an typeCast equivalent solution for the other direction
|
|
753
|
+
// node-postgres: https://github.com/brianc/node-postgres/issues/442
|
|
754
|
+
function convertEscapedParam(param) {
|
|
755
|
+
if (typeof param === 'object' && !(param == null || param instanceof String || param instanceof Number ||
|
|
756
|
+
param instanceof Boolean || param instanceof Date)) {
|
|
757
|
+
return JSON.stringify(param);
|
|
758
|
+
}
|
|
759
|
+
return param;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
let pgParamConverter = (index) => '$' + index;
|
|
763
|
+
let mySqlParamConverter = (index) => '?';
|
|
764
|
+
function convertSingleParam(param, params, paramConverter) {
|
|
765
|
+
params.push(convertEscapedParam(param));
|
|
766
|
+
return paramConverter(params.length);
|
|
767
|
+
}
|
|
768
|
+
function convertQueryToParameterizedSQL(query, options, engine) {
|
|
769
|
+
let params = [];
|
|
770
|
+
let paramConverter = engine === 'mysql' ? mySqlParamConverter : pgParamConverter;
|
|
771
|
+
let sql = createQueryConverter((param) => convertSingleParam(param, params, paramConverter), options, engine)(query);
|
|
772
|
+
return { sql, params };
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
function convertQueryToSQL(query, options, engine) {
|
|
776
|
+
return createQueryConverter((param) => convertSubstitutionParam(param), options, engine)(query);
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
const log = Log.create('query processor');
|
|
780
|
+
const DEFAULT_OPTIONS = {
|
|
781
|
+
lineBreaks: false,
|
|
782
|
+
parameterized: true,
|
|
783
|
+
logging: true,
|
|
784
|
+
identifierQuote: '"'
|
|
785
|
+
};
|
|
786
|
+
function mySqlTypeCast(field, next) {
|
|
787
|
+
if (field.type == 'TINY' && field.length == 1) { // Boolean
|
|
788
|
+
let value = field.string();
|
|
789
|
+
if (value == '1')
|
|
790
|
+
return true;
|
|
791
|
+
if (value == '0')
|
|
792
|
+
return false;
|
|
793
|
+
return null;
|
|
794
|
+
}
|
|
795
|
+
else if (field.type == 'JSON') {
|
|
796
|
+
let value = field.string();
|
|
797
|
+
return value == null ? null : JSON.parse(value);
|
|
798
|
+
}
|
|
799
|
+
return next();
|
|
800
|
+
}
|
|
801
|
+
function createQueryProcessor(client, _options = {}, engine = 'pg') {
|
|
802
|
+
let options = Object.assign({}, DEFAULT_OPTIONS, _options);
|
|
803
|
+
let queryOptions = {
|
|
804
|
+
lineBreak: options.lineBreaks ? '\n' : ' ',
|
|
805
|
+
nameEscape: _options.identifierQuote || (engine === 'mysql' ? '`' : '"')
|
|
806
|
+
};
|
|
807
|
+
// function processSql(query: any, sql: string, params: any[] | undefined, callback: any): Promise<any> {
|
|
808
|
+
// if (options.logging) log.i(sql);
|
|
809
|
+
// if (options.logger) options.logger(sql, params);
|
|
810
|
+
// return new Promise((resolve, reject) => {
|
|
811
|
+
// callback(sql, params, (err: any, result: any) => {
|
|
812
|
+
// if (err) reject(err);
|
|
813
|
+
// else resolve(convertResult(query, result, engine));
|
|
814
|
+
// });
|
|
815
|
+
// });
|
|
816
|
+
// }
|
|
817
|
+
// function executeSql(sql: string, params: any[] | undefined, cb: any) {
|
|
818
|
+
// if (engine === 'pg') {
|
|
819
|
+
// client.query(sql, params || cb, params ? cb : undefined);
|
|
820
|
+
// } else if (engine === 'mysql') {
|
|
821
|
+
// client.query({
|
|
822
|
+
// sql,
|
|
823
|
+
// values: params,
|
|
824
|
+
// typeCast: mySqlTypeCast
|
|
825
|
+
// }, cb);
|
|
826
|
+
// } else throw new Error('Unknown DB engine: ' + engine);
|
|
827
|
+
// }
|
|
828
|
+
return (query) => {
|
|
829
|
+
if (options.parameterized) {
|
|
830
|
+
let { sql, params } = convertQueryToParameterizedSQL(query, queryOptions, engine);
|
|
831
|
+
// if (Helpers.isWebSQL || Helpers.isNode) {
|
|
832
|
+
return client.query(sql, params);
|
|
833
|
+
// }
|
|
834
|
+
// return processSql(query, sql, params, (sql: string, params: any[], cb: any) => executeSql(sql, params, cb));
|
|
835
|
+
}
|
|
836
|
+
else {
|
|
837
|
+
let sql = convertQueryToSQL(query, queryOptions, engine);
|
|
838
|
+
// if (Helpers.isWebSQL || Helpers.isNode) {
|
|
839
|
+
return client.query(sql, undefined);
|
|
840
|
+
// }
|
|
841
|
+
// return processSql(query, sql, undefined, (sql: string, params: undefined, cb: any) => executeSql(sql, undefined, cb));
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
class MySqlQuerySource extends QuerySource {
|
|
847
|
+
constructor(client, options = {}) {
|
|
848
|
+
super(createQueryProcessor(client, options, 'mysql'));
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
// Builder:
|
|
853
|
+
|
|
854
|
+
/**
|
|
855
|
+
* Generated bundle index. Do not edit.
|
|
856
|
+
*/
|
|
857
|
+
|
|
858
|
+
export { BasicColumn, BooleanColumn, ComparableColumn, DateColumn, JoinedTables, JoinedTablesChain, MySqlQuerySource, NumberColumn, QueryColumn, QueryColumnCondition, QueryCondition, QueryConditionChain, QueryJoinCondition, QueryOrdering, QuerySource, QueryTable, SelectQuery, StringColumn, TableConditionQuery, TableQuery, ValueColumn };
|
|
859
|
+
//# sourceMappingURL=taon-type-sql-browser.mjs.map
|