@mikro-orm/knex 6.0.0-dev.4 → 6.0.0-dev.40
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/AbstractSqlConnection.d.ts → AbstractSqlConnection.d.ts} +0 -0
- package/{dist/AbstractSqlConnection.js → AbstractSqlConnection.js} +6 -1
- package/AbstractSqlDriver.d.ts +66 -0
- package/{dist/AbstractSqlDriver.js → AbstractSqlDriver.js} +268 -93
- package/{dist/AbstractSqlPlatform.d.ts → AbstractSqlPlatform.d.ts} +7 -7
- package/{dist/AbstractSqlPlatform.js → AbstractSqlPlatform.js} +12 -14
- package/{dist/MonkeyPatchable.d.ts → MonkeyPatchable.d.ts} +0 -0
- package/{dist/MonkeyPatchable.js → MonkeyPatchable.js} +0 -0
- package/{dist/README.md → README.md} +2 -2
- package/{dist/SqlEntityManager.d.ts → SqlEntityManager.d.ts} +5 -5
- package/{dist/SqlEntityManager.js → SqlEntityManager.js} +1 -2
- package/{dist/SqlEntityRepository.d.ts → SqlEntityRepository.d.ts} +3 -4
- package/{dist/SqlEntityRepository.js → SqlEntityRepository.js} +1 -2
- package/{dist/index.d.ts → index.d.ts} +1 -0
- package/{dist/index.js → index.js} +6 -1
- package/index.mjs +194 -0
- package/package.json +18 -47
- package/query/ArrayCriteriaNode.d.ts +9 -0
- package/{dist/query → query}/ArrayCriteriaNode.js +0 -0
- package/{dist/query → query}/CriteriaNode.d.ts +8 -8
- package/{dist/query → query}/CriteriaNode.js +15 -12
- package/query/CriteriaNodeFactory.d.ts +12 -0
- package/{dist/query → query}/CriteriaNodeFactory.js +10 -10
- package/{dist/query → query}/ObjectCriteriaNode.d.ts +3 -3
- package/{dist/query → query}/ObjectCriteriaNode.js +19 -6
- package/{dist/query → query}/QueryBuilder.d.ts +66 -24
- package/{dist/query → query}/QueryBuilder.js +381 -94
- package/{dist/query → query}/QueryBuilderHelper.d.ts +19 -11
- package/{dist/query → query}/QueryBuilderHelper.js +227 -116
- package/{dist/query → query}/ScalarCriteriaNode.d.ts +2 -2
- package/{dist/query → query}/ScalarCriteriaNode.js +6 -6
- package/{dist/query → query}/enums.d.ts +0 -0
- package/{dist/query → query}/enums.js +0 -0
- package/{dist/query → query}/index.d.ts +0 -0
- package/{dist/query → query}/index.js +5 -1
- package/{dist/schema → schema}/DatabaseSchema.d.ts +1 -1
- package/{dist/schema → schema}/DatabaseSchema.js +11 -19
- package/{dist/schema → schema}/DatabaseTable.d.ts +9 -9
- package/{dist/schema → schema}/DatabaseTable.js +22 -22
- package/{dist/schema → schema}/SchemaComparator.d.ts +7 -5
- package/{dist/schema → schema}/SchemaComparator.js +60 -10
- package/{dist/schema → schema}/SchemaHelper.d.ts +15 -10
- package/{dist/schema → schema}/SchemaHelper.js +46 -8
- package/{dist/schema/SchemaGenerator.d.ts → schema/SqlSchemaGenerator.d.ts} +10 -12
- package/{dist/schema/SchemaGenerator.js → schema/SqlSchemaGenerator.js} +89 -45
- package/{dist/schema → schema}/index.d.ts +1 -1
- package/{dist/schema → schema}/index.js +6 -2
- package/{dist/typings.d.ts → typings.d.ts} +21 -16
- package/{dist/typings.js → typings.js} +0 -0
- package/CHANGELOG.md +0 -661
- package/dist/AbstractSqlDriver.d.ts +0 -55
- package/dist/LICENSE +0 -21
- package/dist/index.mjs +0 -26
- package/dist/package.json +0 -99
- package/dist/query/ArrayCriteriaNode.d.ts +0 -9
- package/dist/query/CriteriaNodeFactory.d.ts +0 -12
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AbstractSqlDriver = void 0;
|
|
4
4
|
const core_1 = require("@mikro-orm/core");
|
|
5
|
-
const
|
|
5
|
+
const query_1 = require("./query");
|
|
6
6
|
const SqlEntityManager_1 = require("./SqlEntityManager");
|
|
7
7
|
class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
8
8
|
constructor(config, platform, connection, connector) {
|
|
@@ -21,21 +21,33 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
21
21
|
async find(entityName, where, options = {}) {
|
|
22
22
|
options = { populate: [], orderBy: [], ...options };
|
|
23
23
|
const meta = this.metadata.find(entityName);
|
|
24
|
+
if (meta?.virtual) {
|
|
25
|
+
return this.findVirtual(entityName, where, options);
|
|
26
|
+
}
|
|
24
27
|
const populate = this.autoJoinOneToOneOwner(meta, options.populate, options.fields);
|
|
25
28
|
const joinedProps = this.joinedProps(meta, populate);
|
|
26
|
-
const qb = this.createQueryBuilder(entityName, options.ctx,
|
|
29
|
+
const qb = this.createQueryBuilder(entityName, options.ctx, options.connectionType, false);
|
|
27
30
|
const fields = this.buildFields(meta, populate, joinedProps, qb, options.fields);
|
|
28
31
|
const joinedPropsOrderBy = this.buildJoinedPropsOrderBy(entityName, qb, meta, joinedProps);
|
|
32
|
+
const orderBy = [...core_1.Utils.asArray(options.orderBy), ...joinedPropsOrderBy];
|
|
29
33
|
if (core_1.Utils.isPrimaryKey(where, meta.compositePK)) {
|
|
30
34
|
where = { [core_1.Utils.getPrimaryKeyHash(meta.primaryKeys)]: where };
|
|
31
35
|
}
|
|
36
|
+
const { first, last, before, after } = options;
|
|
37
|
+
const isCursorPagination = [first, last, before, after].some(v => v != null);
|
|
32
38
|
qb.select(fields)
|
|
33
|
-
.populate(populate)
|
|
39
|
+
.populate(populate, joinedProps.length > 0 ? options.populateWhere : undefined)
|
|
34
40
|
.where(where)
|
|
35
|
-
.orderBy([...core_1.Utils.asArray(options.orderBy), ...joinedPropsOrderBy])
|
|
36
41
|
.groupBy(options.groupBy)
|
|
37
42
|
.having(options.having)
|
|
38
43
|
.withSchema(this.getSchemaName(meta, options));
|
|
44
|
+
if (isCursorPagination) {
|
|
45
|
+
const { orderBy: newOrderBy, where } = this.processCursorOptions(meta, options, orderBy);
|
|
46
|
+
qb.andWhere(where).orderBy(newOrderBy);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
qb.orderBy(orderBy);
|
|
50
|
+
}
|
|
39
51
|
if (options.limit !== undefined) {
|
|
40
52
|
qb.limit(options.limit, options.offset);
|
|
41
53
|
}
|
|
@@ -44,6 +56,9 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
44
56
|
}
|
|
45
57
|
core_1.Utils.asArray(options.flags).forEach(flag => qb.setFlag(flag));
|
|
46
58
|
const result = await this.rethrow(qb.execute('all'));
|
|
59
|
+
if (isCursorPagination && !first && !!last) {
|
|
60
|
+
result.reverse();
|
|
61
|
+
}
|
|
47
62
|
if (joinedProps.length > 0) {
|
|
48
63
|
return this.mergeJoinedResult(result, meta);
|
|
49
64
|
}
|
|
@@ -57,9 +72,70 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
57
72
|
if (joinedProps.length === 0) {
|
|
58
73
|
opts.limit = 1;
|
|
59
74
|
}
|
|
75
|
+
if (opts.limit > 0 && !opts.flags?.includes(core_1.QueryFlag.DISABLE_PAGINATE)) {
|
|
76
|
+
opts.flags ??= [];
|
|
77
|
+
opts.flags.push(core_1.QueryFlag.DISABLE_PAGINATE);
|
|
78
|
+
}
|
|
60
79
|
const res = await this.find(entityName, where, opts);
|
|
61
80
|
return res[0] || null;
|
|
62
81
|
}
|
|
82
|
+
async findVirtual(entityName, where, options) {
|
|
83
|
+
const meta = this.metadata.get(entityName);
|
|
84
|
+
/* istanbul ignore next */
|
|
85
|
+
if (!meta.expression) {
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
if (typeof meta.expression === 'string') {
|
|
89
|
+
return this.wrapVirtualExpressionInSubquery(meta, meta.expression, where, options);
|
|
90
|
+
}
|
|
91
|
+
const em = this.createEntityManager(false);
|
|
92
|
+
em.setTransactionContext(options.ctx);
|
|
93
|
+
const res = meta.expression(em, where, options);
|
|
94
|
+
if (res instanceof (query_1.QueryBuilder)) {
|
|
95
|
+
return this.wrapVirtualExpressionInSubquery(meta, res.getFormattedQuery(), where, options);
|
|
96
|
+
}
|
|
97
|
+
/* istanbul ignore next */
|
|
98
|
+
return res;
|
|
99
|
+
}
|
|
100
|
+
async countVirtual(entityName, where, options) {
|
|
101
|
+
const meta = this.metadata.get(entityName);
|
|
102
|
+
/* istanbul ignore next */
|
|
103
|
+
if (!meta.expression) {
|
|
104
|
+
return 0;
|
|
105
|
+
}
|
|
106
|
+
if (typeof meta.expression === 'string') {
|
|
107
|
+
return this.wrapVirtualExpressionInSubquery(meta, meta.expression, where, options, query_1.QueryType.COUNT);
|
|
108
|
+
}
|
|
109
|
+
const em = this.createEntityManager(false);
|
|
110
|
+
em.setTransactionContext(options.ctx);
|
|
111
|
+
const res = meta.expression(em, where, options);
|
|
112
|
+
if (res instanceof (query_1.QueryBuilder)) {
|
|
113
|
+
return this.wrapVirtualExpressionInSubquery(meta, res.getFormattedQuery(), where, options, query_1.QueryType.COUNT);
|
|
114
|
+
}
|
|
115
|
+
/* istanbul ignore next */
|
|
116
|
+
return res;
|
|
117
|
+
}
|
|
118
|
+
async wrapVirtualExpressionInSubquery(meta, expression, where, options, type = query_1.QueryType.SELECT) {
|
|
119
|
+
const qb = this.createQueryBuilder(meta.className, options?.ctx, options.connectionType, options.convertCustomTypes)
|
|
120
|
+
.limit(options?.limit, options?.offset);
|
|
121
|
+
if (options.orderBy) {
|
|
122
|
+
qb.orderBy(options.orderBy);
|
|
123
|
+
}
|
|
124
|
+
qb.where(where);
|
|
125
|
+
const kqb = qb.getKnexQuery().clear('select');
|
|
126
|
+
if (type === query_1.QueryType.COUNT) {
|
|
127
|
+
kqb.select(qb.raw('count(*) as count'));
|
|
128
|
+
}
|
|
129
|
+
else { // select
|
|
130
|
+
kqb.select('*');
|
|
131
|
+
}
|
|
132
|
+
kqb.fromRaw(`(${expression}) as ${this.platform.quoteIdentifier(qb.alias)}`);
|
|
133
|
+
const res = await this.execute(kqb);
|
|
134
|
+
if (type === query_1.QueryType.COUNT) {
|
|
135
|
+
return res[0].count;
|
|
136
|
+
}
|
|
137
|
+
return res.map(row => this.mapResult(row, meta));
|
|
138
|
+
}
|
|
63
139
|
mapResult(result, meta, populate = [], qb, map = {}) {
|
|
64
140
|
const ret = super.mapResult(result, meta);
|
|
65
141
|
/* istanbul ignore if */
|
|
@@ -90,8 +166,8 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
90
166
|
}));
|
|
91
167
|
if (!hasPK) {
|
|
92
168
|
// initialize empty collections
|
|
93
|
-
if ([core_1.
|
|
94
|
-
result[relation.name]
|
|
169
|
+
if ([core_1.ReferenceKind.MANY_TO_MANY, core_1.ReferenceKind.ONE_TO_MANY].includes(relation.kind)) {
|
|
170
|
+
result[relation.name] ??= [];
|
|
95
171
|
}
|
|
96
172
|
return;
|
|
97
173
|
}
|
|
@@ -115,8 +191,8 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
115
191
|
else {
|
|
116
192
|
map[key] = result;
|
|
117
193
|
}
|
|
118
|
-
if ([core_1.
|
|
119
|
-
result[relation.name]
|
|
194
|
+
if ([core_1.ReferenceKind.MANY_TO_MANY, core_1.ReferenceKind.ONE_TO_MANY].includes(relation.kind)) {
|
|
195
|
+
result[relation.name] ??= [];
|
|
120
196
|
this.appendToCollection(meta2, result[relation.name], relationPojo);
|
|
121
197
|
}
|
|
122
198
|
else {
|
|
@@ -137,23 +213,25 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
137
213
|
collection.push(relationPojo);
|
|
138
214
|
}
|
|
139
215
|
}
|
|
140
|
-
async count(entityName, where, options = {}
|
|
216
|
+
async count(entityName, where, options = {}) {
|
|
141
217
|
const meta = this.metadata.find(entityName);
|
|
142
|
-
|
|
143
|
-
|
|
218
|
+
if (meta?.virtual) {
|
|
219
|
+
return this.countVirtual(entityName, where, options);
|
|
220
|
+
}
|
|
221
|
+
const qb = this.createQueryBuilder(entityName, options.ctx, options.connectionType, false)
|
|
144
222
|
.groupBy(options.groupBy)
|
|
145
223
|
.having(options.having)
|
|
146
224
|
.populate(options.populate ?? [])
|
|
147
225
|
.withSchema(this.getSchemaName(meta, options))
|
|
148
226
|
.where(where);
|
|
149
|
-
return this.rethrow(qb.getCount(
|
|
227
|
+
return this.rethrow(qb.getCount());
|
|
150
228
|
}
|
|
151
229
|
async nativeInsert(entityName, data, options = {}) {
|
|
152
|
-
options.convertCustomTypes
|
|
230
|
+
options.convertCustomTypes ??= true;
|
|
153
231
|
const meta = this.metadata.find(entityName);
|
|
154
232
|
const collections = this.extractManyToMany(entityName, data);
|
|
155
|
-
const pks = this.
|
|
156
|
-
const qb = this.createQueryBuilder(entityName, options.ctx,
|
|
233
|
+
const pks = meta?.primaryKeys ?? [this.config.getNamingStrategy().referenceColumnName()];
|
|
234
|
+
const qb = this.createQueryBuilder(entityName, options.ctx, 'write', options.convertCustomTypes).withSchema(this.getSchemaName(meta, options));
|
|
157
235
|
const res = await this.rethrow(qb.insert(data).execute('run', false));
|
|
158
236
|
res.row = res.row || {};
|
|
159
237
|
let pk;
|
|
@@ -161,39 +239,41 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
161
239
|
pk = core_1.Utils.getPrimaryKeyCond(data, pks);
|
|
162
240
|
}
|
|
163
241
|
else {
|
|
164
|
-
|
|
242
|
+
/* istanbul ignore next */
|
|
243
|
+
res.insertId = data[pks[0]] ?? res.insertId ?? res.row[pks[0]];
|
|
165
244
|
pk = [res.insertId];
|
|
166
245
|
}
|
|
167
246
|
await this.processManyToMany(meta, pk, collections, false, options);
|
|
168
247
|
return res;
|
|
169
248
|
}
|
|
170
249
|
async nativeInsertMany(entityName, data, options = {}) {
|
|
171
|
-
options.processCollections
|
|
172
|
-
options.convertCustomTypes
|
|
173
|
-
const meta = this.metadata.
|
|
250
|
+
options.processCollections ??= true;
|
|
251
|
+
options.convertCustomTypes ??= true;
|
|
252
|
+
const meta = this.metadata.find(entityName);
|
|
174
253
|
const collections = options.processCollections ? data.map(d => this.extractManyToMany(entityName, d)) : [];
|
|
175
254
|
const pks = this.getPrimaryKeyFields(entityName);
|
|
176
255
|
const set = new Set();
|
|
177
|
-
data.forEach(row =>
|
|
178
|
-
const props = [...set].map(name => meta
|
|
256
|
+
data.forEach(row => core_1.Utils.keys(row).forEach(k => set.add(k)));
|
|
257
|
+
const props = [...set].map(name => meta?.properties[name] ?? { name, fieldNames: [name] });
|
|
179
258
|
const fields = core_1.Utils.flatten(props.map(prop => prop.fieldNames));
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
259
|
+
const params = [];
|
|
260
|
+
/* istanbul ignore next */
|
|
261
|
+
const tableName = meta ? this.getTableName(meta, options) : this.platform.quoteIdentifier(entityName);
|
|
262
|
+
let sql = `insert into ${tableName} `;
|
|
263
|
+
sql += fields.length > 0 ? '(' + fields.map(k => this.platform.quoteIdentifier(k)).join(', ') + ')' : `(${this.platform.quoteIdentifier(pks[0])})`;
|
|
264
|
+
if (fields.length > 0 || this.platform.usesDefaultKeyword()) {
|
|
265
|
+
sql += ' values ';
|
|
184
266
|
}
|
|
185
267
|
else {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
sql += ` values `;
|
|
190
|
-
const params = [];
|
|
268
|
+
sql += ' ' + data.map(() => `select null as ${this.platform.quoteIdentifier(pks[0])}`).join(' union all ');
|
|
269
|
+
}
|
|
270
|
+
if (fields.length > 0 || this.platform.usesDefaultKeyword()) {
|
|
191
271
|
sql += data.map(row => {
|
|
192
272
|
const keys = [];
|
|
193
273
|
props.forEach(prop => {
|
|
194
274
|
if (prop.fieldNames.length > 1) {
|
|
195
|
-
params.push(...row[prop.name]);
|
|
196
|
-
keys.push(...prop.fieldNames.map(
|
|
275
|
+
params.push(...(row[prop.name] ?? prop.fieldNames.map(() => null)));
|
|
276
|
+
keys.push(...(row[prop.name] ?? prop.fieldNames).map(() => '?'));
|
|
197
277
|
}
|
|
198
278
|
else if (prop.customType && 'convertToDatabaseValueSQL' in prop.customType && !this.platform.isRaw(row[prop.name])) {
|
|
199
279
|
keys.push(prop.customType.convertToDatabaseValueSQL('?', this.platform));
|
|
@@ -204,25 +284,25 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
204
284
|
keys.push('?');
|
|
205
285
|
}
|
|
206
286
|
});
|
|
207
|
-
return '(' + keys.join(', ') + ')';
|
|
287
|
+
return '(' + (keys.join(', ') || 'default') + ')';
|
|
208
288
|
}).join(', ');
|
|
209
|
-
if (this.platform.usesReturningStatement()) {
|
|
210
|
-
/* istanbul ignore next */
|
|
211
|
-
const returningProps = meta.props.filter(prop => prop.primary || prop.defaultRaw);
|
|
212
|
-
const returningFields = core_1.Utils.flatten(returningProps.map(prop => prop.fieldNames));
|
|
213
|
-
/* istanbul ignore next */
|
|
214
|
-
sql += returningFields.length > 0 ? ` returning ${returningFields.map(field => this.platform.quoteIdentifier(field)).join(', ')}` : '';
|
|
215
|
-
}
|
|
216
|
-
res = await this.execute(sql, params, 'run', options.ctx);
|
|
217
289
|
}
|
|
290
|
+
if (this.platform.usesReturningStatement()) {
|
|
291
|
+
/* istanbul ignore next */
|
|
292
|
+
const returningProps = meta.hydrateProps.filter(prop => prop.persist !== false && (prop.primary || prop.defaultRaw));
|
|
293
|
+
const returningFields = core_1.Utils.flatten(returningProps.map(prop => prop.fieldNames));
|
|
294
|
+
/* istanbul ignore next */
|
|
295
|
+
sql += returningFields.length > 0 ? ` returning ${returningFields.map(field => this.platform.quoteIdentifier(field)).join(', ')}` : '';
|
|
296
|
+
}
|
|
297
|
+
const res = await this.execute(sql, params, 'run', options.ctx);
|
|
218
298
|
let pk;
|
|
219
299
|
/* istanbul ignore next */
|
|
220
300
|
if (pks.length > 1) { // owner has composite pk
|
|
221
301
|
pk = data.map(d => core_1.Utils.getPrimaryKeyCond(d, pks));
|
|
222
302
|
}
|
|
223
303
|
else {
|
|
224
|
-
res.row
|
|
225
|
-
res.rows
|
|
304
|
+
res.row ??= {};
|
|
305
|
+
res.rows ??= [];
|
|
226
306
|
pk = data.map((d, i) => d[pks[0]] ?? res.rows[i]?.[pks[0]]).map(d => [d]);
|
|
227
307
|
res.insertId = res.insertId || res.row[pks[0]];
|
|
228
308
|
}
|
|
@@ -232,19 +312,29 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
232
312
|
return res;
|
|
233
313
|
}
|
|
234
314
|
async nativeUpdate(entityName, where, data, options = {}) {
|
|
235
|
-
options.convertCustomTypes
|
|
315
|
+
options.convertCustomTypes ??= true;
|
|
236
316
|
const meta = this.metadata.find(entityName);
|
|
237
317
|
const pks = this.getPrimaryKeyFields(entityName);
|
|
238
318
|
const collections = this.extractManyToMany(entityName, data);
|
|
239
319
|
let res = { affectedRows: 0, insertId: 0, row: {} };
|
|
240
320
|
if (core_1.Utils.isPrimaryKey(where) && pks.length === 1) {
|
|
241
|
-
|
|
321
|
+
/* istanbul ignore next */
|
|
322
|
+
where = { [meta?.primaryKeys[0] ?? pks[0]]: where };
|
|
242
323
|
}
|
|
243
324
|
if (core_1.Utils.hasObjectKeys(data)) {
|
|
244
|
-
const qb = this.createQueryBuilder(entityName, options.ctx,
|
|
245
|
-
.
|
|
246
|
-
|
|
247
|
-
|
|
325
|
+
const qb = this.createQueryBuilder(entityName, options.ctx, 'write', options.convertCustomTypes)
|
|
326
|
+
.withSchema(this.getSchemaName(meta, options));
|
|
327
|
+
if (options.upsert) {
|
|
328
|
+
/* istanbul ignore next */
|
|
329
|
+
const uniqueFields = core_1.Utils.isPlainObject(where) ? core_1.Utils.keys(where) : meta.primaryKeys;
|
|
330
|
+
/* istanbul ignore next */
|
|
331
|
+
qb.insert(data)
|
|
332
|
+
.onConflict(uniqueFields.map(p => meta?.properties[p]?.fieldNames[0] ?? p))
|
|
333
|
+
.merge(core_1.Utils.keys(data).filter(f => !uniqueFields.includes(f)));
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
qb.update(data).where(where);
|
|
337
|
+
}
|
|
248
338
|
res = await this.rethrow(qb.execute('run', false));
|
|
249
339
|
}
|
|
250
340
|
/* istanbul ignore next */
|
|
@@ -253,12 +343,20 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
253
343
|
return res;
|
|
254
344
|
}
|
|
255
345
|
async nativeUpdateMany(entityName, where, data, options = {}) {
|
|
256
|
-
options.processCollections
|
|
257
|
-
options.convertCustomTypes
|
|
346
|
+
options.processCollections ??= true;
|
|
347
|
+
options.convertCustomTypes ??= true;
|
|
258
348
|
const meta = this.metadata.get(entityName);
|
|
349
|
+
if (options.upsert) {
|
|
350
|
+
const uniqueFields = core_1.Utils.isPlainObject(where[0]) ? Object.keys(where[0]) : meta.primaryKeys;
|
|
351
|
+
const qb = this.createQueryBuilder(entityName, options.ctx, 'write', options.convertCustomTypes).withSchema(this.getSchemaName(meta, options));
|
|
352
|
+
qb.insert(data)
|
|
353
|
+
.onConflict(uniqueFields.map(p => meta?.properties[p]?.fieldNames[0] ?? p))
|
|
354
|
+
.merge(Object.keys(data[0]).filter(f => !uniqueFields.includes(f)));
|
|
355
|
+
return qb.execute('run', false);
|
|
356
|
+
}
|
|
259
357
|
const collections = options.processCollections ? data.map(d => this.extractManyToMany(entityName, d)) : [];
|
|
260
358
|
const keys = new Set();
|
|
261
|
-
data.forEach(row =>
|
|
359
|
+
data.forEach(row => core_1.Utils.keys(row).forEach(k => keys.add(k)));
|
|
262
360
|
const pkCond = core_1.Utils.flatten(meta.primaryKeys.map(pk => meta.properties[pk].fieldNames)).map(pk => `${this.platform.quoteIdentifier(pk)} = ?`).join(' and ');
|
|
263
361
|
const params = [];
|
|
264
362
|
let sql = `update ${this.getTableName(meta, options)} set `;
|
|
@@ -276,7 +374,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
276
374
|
else {
|
|
277
375
|
sql += '?';
|
|
278
376
|
}
|
|
279
|
-
params.push(...pks, prop.fieldNames.length > 1 ? data[idx][key][fieldNameIdx] : data[idx][key]);
|
|
377
|
+
params.push(...pks, prop.fieldNames.length > 1 ? data[idx][key]?.[fieldNameIdx] : data[idx][key]);
|
|
280
378
|
}
|
|
281
379
|
});
|
|
282
380
|
sql += ` else ${this.platform.quoteIdentifier(fieldName)} end, `;
|
|
@@ -300,15 +398,24 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
300
398
|
const pks = core_1.Utils.flatten(pkProps.map(pk => meta.properties[pk].fieldNames));
|
|
301
399
|
sql += pks.length > 1 ? `(${pks.map(pk => `${this.platform.quoteIdentifier(pk)}`).join(', ')})` : this.platform.quoteIdentifier(pks[0]);
|
|
302
400
|
const conds = where.map(cond => {
|
|
401
|
+
if (core_1.Utils.isPlainObject(cond) && core_1.Utils.getObjectKeysSize(cond) === 1) {
|
|
402
|
+
cond = Object.values(cond)[0];
|
|
403
|
+
}
|
|
303
404
|
if (pks.length > 1) {
|
|
304
|
-
pkProps.forEach(pk =>
|
|
405
|
+
pkProps.forEach(pk => {
|
|
406
|
+
if (Array.isArray(cond[pk])) {
|
|
407
|
+
params.push(...core_1.Utils.flatten(cond[pk]));
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
params.push(cond[pk]);
|
|
411
|
+
}
|
|
412
|
+
});
|
|
305
413
|
return `(${new Array(pks.length).fill('?').join(', ')})`;
|
|
306
414
|
}
|
|
307
415
|
params.push(cond);
|
|
308
416
|
return '?';
|
|
309
417
|
});
|
|
310
|
-
|
|
311
|
-
sql += ` in (${values}${conds.join(', ')})`;
|
|
418
|
+
sql += ` in (${conds.join(', ')})`;
|
|
312
419
|
const res = await this.rethrow(this.execute(sql, params, 'run', options.ctx));
|
|
313
420
|
for (let i = 0; i < collections.length; i++) {
|
|
314
421
|
await this.processManyToMany(meta, where[i], collections[i], false, options);
|
|
@@ -321,17 +428,17 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
321
428
|
if (core_1.Utils.isPrimaryKey(where) && pks.length === 1) {
|
|
322
429
|
where = { [pks[0]]: where };
|
|
323
430
|
}
|
|
324
|
-
const qb = this.createQueryBuilder(entityName, options.ctx,
|
|
431
|
+
const qb = this.createQueryBuilder(entityName, options.ctx, 'write', false).delete(where).withSchema(this.getSchemaName(meta, options));
|
|
325
432
|
return this.rethrow(qb.execute('run', false));
|
|
326
433
|
}
|
|
327
434
|
async syncCollection(coll, options) {
|
|
328
|
-
const wrapped = coll.owner
|
|
435
|
+
const wrapped = (0, core_1.helper)(coll.owner);
|
|
329
436
|
const meta = wrapped.__meta;
|
|
330
437
|
const pks = wrapped.getPrimaryKeys(true);
|
|
331
438
|
const snap = coll.getSnapshot();
|
|
332
439
|
const includes = (arr, item) => !!arr.find(i => core_1.Utils.equals(i, item));
|
|
333
|
-
const snapshot = snap ? snap.map(item => item.
|
|
334
|
-
const current = coll.getItems(false).map(item => item.
|
|
440
|
+
const snapshot = snap ? snap.map(item => (0, core_1.helper)(item).getPrimaryKeys(true)) : [];
|
|
441
|
+
const current = coll.getItems(false).map(item => (0, core_1.helper)(item).getPrimaryKeys(true));
|
|
335
442
|
const deleteDiff = snap ? snapshot.filter(item => !includes(current, item)) : true;
|
|
336
443
|
const insertDiff = current.filter(item => !includes(snapshot, item));
|
|
337
444
|
const target = snapshot.filter(item => includes(current, item)).concat(...insertDiff);
|
|
@@ -343,9 +450,9 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
343
450
|
deleteDiff.push(...snapshot);
|
|
344
451
|
insertDiff.push(...current);
|
|
345
452
|
}
|
|
346
|
-
if (coll.property.
|
|
453
|
+
if (coll.property.kind === core_1.ReferenceKind.ONE_TO_MANY) {
|
|
347
454
|
const cols = coll.property.referencedColumnNames;
|
|
348
|
-
const qb = this.createQueryBuilder(coll.property.type, ctx,
|
|
455
|
+
const qb = this.createQueryBuilder(coll.property.type, ctx, 'write')
|
|
349
456
|
.withSchema(this.getSchemaName(meta, options))
|
|
350
457
|
.update({ [coll.property.mappedBy]: pks })
|
|
351
458
|
.getKnexQuery()
|
|
@@ -354,10 +461,10 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
354
461
|
}
|
|
355
462
|
/* istanbul ignore next */
|
|
356
463
|
const ownerSchema = wrapped.getSchema() === '*' ? this.config.get('schema') : wrapped.getSchema();
|
|
357
|
-
const pivotMeta = this.metadata.find(coll.property.
|
|
464
|
+
const pivotMeta = this.metadata.find(coll.property.pivotEntity);
|
|
358
465
|
if (pivotMeta.schema === '*') {
|
|
359
466
|
/* istanbul ignore next */
|
|
360
|
-
options
|
|
467
|
+
options ??= {};
|
|
361
468
|
options.schema = ownerSchema;
|
|
362
469
|
}
|
|
363
470
|
return this.rethrow(this.updateCollectionDiff(meta, coll.property, pks, deleteDiff, insertDiff, options));
|
|
@@ -365,7 +472,8 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
365
472
|
async loadFromPivotTable(prop, owners, where = {}, orderBy, ctx, options) {
|
|
366
473
|
const pivotProp2 = this.getPivotInverseProperty(prop);
|
|
367
474
|
const ownerMeta = this.metadata.find(pivotProp2.type);
|
|
368
|
-
const
|
|
475
|
+
const pivotMeta = this.metadata.find(prop.pivotEntity);
|
|
476
|
+
const cond = { [`${prop.pivotEntity}.${pivotProp2.name}`]: { $in: ownerMeta.compositePK ? owners : owners.map(o => o[0]) } };
|
|
369
477
|
/* istanbul ignore if */
|
|
370
478
|
if (!core_1.Utils.isEmpty(where) && Object.keys(where).every(k => core_1.Utils.isOperator(k, false))) {
|
|
371
479
|
where = cond;
|
|
@@ -374,15 +482,23 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
374
482
|
where = { ...where, ...cond };
|
|
375
483
|
}
|
|
376
484
|
orderBy = this.getPivotOrderBy(prop, orderBy);
|
|
377
|
-
const qb = this.createQueryBuilder(prop.type, ctx,
|
|
485
|
+
const qb = this.createQueryBuilder(prop.type, ctx, options?.connectionType)
|
|
378
486
|
.unsetFlag(core_1.QueryFlag.CONVERT_CUSTOM_TYPES)
|
|
379
487
|
.withSchema(this.getSchemaName(prop.targetMeta, options));
|
|
380
|
-
const populate = this.autoJoinOneToOneOwner(prop.targetMeta, [{ field: prop.
|
|
488
|
+
const populate = this.autoJoinOneToOneOwner(prop.targetMeta, [{ field: prop.pivotEntity }]);
|
|
381
489
|
const fields = this.buildFields(prop.targetMeta, (options?.populate ?? []), [], qb, options?.fields);
|
|
382
490
|
qb.select(fields).populate(populate).where(where).orderBy(orderBy).setLockMode(options?.lockMode, options?.lockTableAliases);
|
|
383
491
|
if (owners.length === 1 && (options?.offset != null || options?.limit != null)) {
|
|
384
492
|
qb.limit(options.limit, options.offset);
|
|
385
493
|
}
|
|
494
|
+
if (prop.targetMeta.schema !== '*' && pivotMeta.schema === '*' && options?.schema) {
|
|
495
|
+
// eslint-disable-next-line dot-notation
|
|
496
|
+
qb['finalize']();
|
|
497
|
+
// eslint-disable-next-line dot-notation
|
|
498
|
+
Object.values(qb['_joins']).forEach(join => {
|
|
499
|
+
join.schema = options.schema;
|
|
500
|
+
});
|
|
501
|
+
}
|
|
386
502
|
const items = owners.length ? await this.rethrow(qb.execute('all')) : [];
|
|
387
503
|
const map = {};
|
|
388
504
|
const pkProps = ownerMeta.getPrimaryProps();
|
|
@@ -407,33 +523,24 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
407
523
|
async execute(queryOrKnex, params = [], method = 'all', ctx) {
|
|
408
524
|
return this.rethrow(this.connection.execute(queryOrKnex, params, method, ctx));
|
|
409
525
|
}
|
|
410
|
-
getTableName(meta, options) {
|
|
411
|
-
let tableName = this.platform.quoteIdentifier(meta.collection);
|
|
412
|
-
if (options.schema === '*') {
|
|
413
|
-
return this.platform.quoteIdentifier(this.config.get('schema')) + '.' + tableName;
|
|
414
|
-
}
|
|
415
|
-
if (meta.schema || options.schema) {
|
|
416
|
-
tableName = this.platform.quoteIdentifier(options.schema ?? meta.schema) + '.' + tableName;
|
|
417
|
-
}
|
|
418
|
-
return tableName;
|
|
419
|
-
}
|
|
420
526
|
/**
|
|
421
527
|
* 1:1 owner side needs to be marked for population so QB auto-joins the owner id
|
|
422
528
|
*/
|
|
423
529
|
autoJoinOneToOneOwner(meta, populate, fields = []) {
|
|
424
|
-
if (!this.config.get('autoJoinOneToOneOwner')
|
|
530
|
+
if (!this.config.get('autoJoinOneToOneOwner')) {
|
|
425
531
|
return populate;
|
|
426
532
|
}
|
|
427
533
|
const relationsToPopulate = populate.map(({ field }) => field);
|
|
428
534
|
const toPopulate = meta.relations
|
|
429
|
-
.filter(prop => prop.
|
|
535
|
+
.filter(prop => prop.kind === core_1.ReferenceKind.ONE_TO_ONE && !prop.owner && !relationsToPopulate.includes(prop.name))
|
|
536
|
+
.filter(prop => fields.length === 0 || fields.some(f => prop.name === f || prop.name.startsWith(`${String(f)}.`)))
|
|
430
537
|
.map(prop => ({ field: prop.name, strategy: prop.strategy }));
|
|
431
538
|
return [...populate, ...toPopulate];
|
|
432
539
|
}
|
|
433
540
|
joinedProps(meta, populate) {
|
|
434
541
|
return populate.filter(p => {
|
|
435
542
|
const prop = meta.properties[p.field] || {};
|
|
436
|
-
return (p.strategy || prop.strategy || this.config.get('loadStrategy')) === core_1.LoadStrategy.JOINED && prop.
|
|
543
|
+
return (p.strategy || prop.strategy || this.config.get('loadStrategy')) === core_1.LoadStrategy.JOINED && prop.kind !== core_1.ReferenceKind.SCALAR;
|
|
437
544
|
});
|
|
438
545
|
}
|
|
439
546
|
/**
|
|
@@ -458,12 +565,15 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
458
565
|
getFieldsForJoinedLoad(qb, meta, explicitFields, populate = [], parentTableAlias, parentJoinPath) {
|
|
459
566
|
const fields = [];
|
|
460
567
|
const joinedProps = this.joinedProps(meta, populate);
|
|
568
|
+
if (explicitFields?.includes('*')) {
|
|
569
|
+
fields.push('*');
|
|
570
|
+
}
|
|
461
571
|
const shouldHaveColumn = (prop, populate, fields) => {
|
|
462
572
|
if (!this.platform.shouldHaveColumn(prop, populate)) {
|
|
463
573
|
return false;
|
|
464
574
|
}
|
|
465
575
|
if (!fields || prop.primary) {
|
|
466
|
-
return
|
|
576
|
+
return !fields?.includes('*');
|
|
467
577
|
}
|
|
468
578
|
return fields.includes(prop.name);
|
|
469
579
|
};
|
|
@@ -506,20 +616,34 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
506
616
|
}
|
|
507
617
|
return prop.fieldNames;
|
|
508
618
|
}
|
|
509
|
-
|
|
510
|
-
|
|
619
|
+
/** @internal */
|
|
620
|
+
createQueryBuilder(entityName, ctx, preferredConnectionType, convertCustomTypes) {
|
|
621
|
+
const connectionType = this.resolveConnectionType({ ctx, connectionType: preferredConnectionType });
|
|
622
|
+
const qb = new query_1.QueryBuilder(entityName, this.metadata, this, ctx, undefined, connectionType);
|
|
511
623
|
if (!convertCustomTypes) {
|
|
512
624
|
qb.unsetFlag(core_1.QueryFlag.CONVERT_CUSTOM_TYPES);
|
|
513
625
|
}
|
|
514
626
|
return qb;
|
|
515
627
|
}
|
|
628
|
+
resolveConnectionType(args) {
|
|
629
|
+
if (args.ctx) {
|
|
630
|
+
return 'write';
|
|
631
|
+
}
|
|
632
|
+
else if (args.connectionType) {
|
|
633
|
+
return args.connectionType;
|
|
634
|
+
}
|
|
635
|
+
else if (this.config.get('preferReadReplicas') === true) {
|
|
636
|
+
return 'read';
|
|
637
|
+
}
|
|
638
|
+
return 'write';
|
|
639
|
+
}
|
|
516
640
|
extractManyToMany(entityName, data) {
|
|
517
641
|
if (!this.metadata.has(entityName)) {
|
|
518
642
|
return {};
|
|
519
643
|
}
|
|
520
644
|
const ret = {};
|
|
521
645
|
this.metadata.find(entityName).relations.forEach(prop => {
|
|
522
|
-
if (prop.
|
|
646
|
+
if (prop.kind === core_1.ReferenceKind.MANY_TO_MANY && data[prop.name]) {
|
|
523
647
|
ret[prop.name] = data[prop.name].map((item) => core_1.Utils.asArray(item));
|
|
524
648
|
delete data[prop.name];
|
|
525
649
|
}
|
|
@@ -541,7 +665,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
541
665
|
deleteDiff = [];
|
|
542
666
|
}
|
|
543
667
|
if (deleteDiff === true || deleteDiff.length > 0) {
|
|
544
|
-
const qb1 = this.createQueryBuilder(prop.
|
|
668
|
+
const qb1 = this.createQueryBuilder(prop.pivotEntity, options?.ctx, 'write')
|
|
545
669
|
.withSchema(this.getSchemaName(meta, options))
|
|
546
670
|
.unsetFlag(core_1.QueryFlag.CONVERT_CUSTOM_TYPES);
|
|
547
671
|
const knex = qb1.getKnex();
|
|
@@ -562,11 +686,15 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
562
686
|
});
|
|
563
687
|
/* istanbul ignore else */
|
|
564
688
|
if (this.platform.allowsMultiInsert()) {
|
|
565
|
-
await this.nativeInsertMany(prop.
|
|
689
|
+
await this.nativeInsertMany(prop.pivotEntity, items, {
|
|
690
|
+
...options,
|
|
691
|
+
convertCustomTypes: false,
|
|
692
|
+
processCollections: false,
|
|
693
|
+
});
|
|
566
694
|
}
|
|
567
695
|
else {
|
|
568
696
|
await core_1.Utils.runSerial(items, item => {
|
|
569
|
-
return this.createQueryBuilder(prop.
|
|
697
|
+
return this.createQueryBuilder(prop.pivotEntity, options?.ctx, 'write')
|
|
570
698
|
.unsetFlag(core_1.QueryFlag.CONVERT_CUSTOM_TYPES)
|
|
571
699
|
.withSchema(this.getSchemaName(meta, options))
|
|
572
700
|
.insert(item)
|
|
@@ -575,7 +703,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
575
703
|
}
|
|
576
704
|
}
|
|
577
705
|
async lockPessimistic(entity, options) {
|
|
578
|
-
const meta = entity.
|
|
706
|
+
const meta = (0, core_1.helper)(entity).__meta;
|
|
579
707
|
const qb = this.createQueryBuilder(entity.constructor.name, options.ctx).unsetFlag(core_1.QueryFlag.CONVERT_CUSTOM_TYPES).withSchema(options.schema ?? meta.schema);
|
|
580
708
|
const cond = core_1.Utils.getPrimaryKeyCond(entity, meta.primaryKeys);
|
|
581
709
|
qb.select('1').where(cond).setLockMode(options.lockMode, options.lockTableAliases);
|
|
@@ -590,7 +718,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
590
718
|
const path = `${parentPath ? parentPath : entityName}.${relation.field}`;
|
|
591
719
|
const propAlias = qb.getAliasForJoinPath(path);
|
|
592
720
|
if (propOrderBy) {
|
|
593
|
-
|
|
721
|
+
core_1.Utils.keys(propOrderBy).forEach(field => {
|
|
594
722
|
orderBy.push({ [`${propAlias}.${field}`]: propOrderBy[field] });
|
|
595
723
|
});
|
|
596
724
|
}
|
|
@@ -601,6 +729,43 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
601
729
|
});
|
|
602
730
|
return orderBy;
|
|
603
731
|
}
|
|
732
|
+
normalizeFields(fields, prefix = '') {
|
|
733
|
+
const ret = [];
|
|
734
|
+
for (const field of fields) {
|
|
735
|
+
if (typeof field === 'string') {
|
|
736
|
+
ret.push(prefix + field);
|
|
737
|
+
continue;
|
|
738
|
+
}
|
|
739
|
+
if (core_1.Utils.isPlainObject(field)) {
|
|
740
|
+
for (const key of Object.keys(field)) {
|
|
741
|
+
ret.push(...this.normalizeFields(field[key], key + '.'));
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
return ret;
|
|
746
|
+
}
|
|
747
|
+
processField(meta, prop, field, ret, populate, joinedProps, qb) {
|
|
748
|
+
if (!prop || (prop.kind === core_1.ReferenceKind.ONE_TO_ONE && !prop.owner)) {
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
if (prop.kind === core_1.ReferenceKind.EMBEDDED) {
|
|
752
|
+
if (prop.object) {
|
|
753
|
+
ret.push(prop.fieldNames[0]);
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
const parts = field.split('.');
|
|
757
|
+
const top = parts.shift();
|
|
758
|
+
for (const key of Object.keys(prop.embeddedProps)) {
|
|
759
|
+
if (!top || key === top) {
|
|
760
|
+
this.processField(meta, prop.embeddedProps[key], parts.join('.'), ret, populate, joinedProps, qb);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
if (prop.fieldNames) {
|
|
766
|
+
ret.push(...prop.fieldNames);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
604
769
|
buildFields(meta, populate, joinedProps, qb, fields) {
|
|
605
770
|
const lazyProps = meta.props.filter(prop => prop.lazy && !populate.some(p => p.field === prop.name || p.all));
|
|
606
771
|
const hasLazyFormulas = meta.props.some(p => p.lazy && p.formula);
|
|
@@ -611,11 +776,21 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
611
776
|
ret.push(...this.getFieldsForJoinedLoad(qb, meta, fields, populate));
|
|
612
777
|
}
|
|
613
778
|
else if (fields) {
|
|
614
|
-
for (const field of
|
|
615
|
-
if (
|
|
779
|
+
for (const field of this.normalizeFields(fields)) {
|
|
780
|
+
if (field === '*') {
|
|
781
|
+
ret.push('*');
|
|
616
782
|
continue;
|
|
617
783
|
}
|
|
618
|
-
|
|
784
|
+
const parts = field.split('.');
|
|
785
|
+
const rootPropName = parts.shift(); // first one is the `prop`
|
|
786
|
+
const prop = core_1.QueryHelper.findProperty(rootPropName, {
|
|
787
|
+
metadata: this.metadata,
|
|
788
|
+
platform: this.platform,
|
|
789
|
+
entityName: meta.className,
|
|
790
|
+
where: {},
|
|
791
|
+
aliasMap: qb.getAliasMap(),
|
|
792
|
+
});
|
|
793
|
+
this.processField(meta, prop, parts.join('.'), ret, populate, joinedProps, qb);
|
|
619
794
|
}
|
|
620
795
|
ret.unshift(...meta.primaryKeys.filter(pk => !fields.includes(pk)));
|
|
621
796
|
}
|
|
@@ -638,7 +813,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
638
813
|
.filter(prop => prop.customType?.convertToDatabaseValueSQL || prop.customType?.convertToJSValueSQL)
|
|
639
814
|
.forEach(prop => ret.push(prop.name));
|
|
640
815
|
}
|
|
641
|
-
return ret.length > 0 ? ret : ['*'];
|
|
816
|
+
return ret.length > 0 ? core_1.Utils.unique(ret) : ['*'];
|
|
642
817
|
}
|
|
643
818
|
}
|
|
644
819
|
exports.AbstractSqlDriver = AbstractSqlDriver;
|