@strapi/database 4.3.3 → 4.3.6
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/jest.config.js +1 -1
- package/lib/__tests__/lifecycles.test.js +1 -1
- package/lib/connection.js +4 -4
- package/lib/dialects/dialect.js +8 -2
- package/lib/dialects/index.js +2 -2
- package/lib/dialects/mysql/index.js +2 -2
- package/lib/dialects/mysql/schema-inspector.js +12 -16
- package/lib/dialects/postgresql/index.js +2 -2
- package/lib/dialects/postgresql/schema-inspector.js +30 -25
- package/lib/dialects/sqlite/index.js +1 -1
- package/lib/dialects/sqlite/schema-inspector.js +5 -5
- package/lib/entity-manager.js +29 -61
- package/lib/entity-repository.js +1 -1
- package/lib/errors/database.js +12 -0
- package/lib/errors/index.js +15 -0
- package/lib/errors/invalid-date.js +14 -0
- package/lib/errors/invalid-datetime.js +14 -0
- package/lib/errors/invalid-time.js +14 -0
- package/lib/errors/not-null.js +15 -0
- package/lib/fields/biginteger.js +17 -0
- package/lib/fields/boolean.js +39 -0
- package/lib/fields/date.js +16 -0
- package/lib/fields/datetime.js +19 -0
- package/lib/fields/field.js +17 -0
- package/lib/{fields.d.ts → fields/index.d.ts} +0 -0
- package/lib/fields/index.js +49 -0
- package/lib/fields/json.js +16 -0
- package/lib/fields/number.js +23 -0
- package/lib/fields/shared/parsers.js +69 -0
- package/lib/fields/string.js +17 -0
- package/lib/fields/time.js +17 -0
- package/lib/fields/timestamp.js +19 -0
- package/lib/index.js +1 -1
- package/lib/lifecycles/index.js +2 -2
- package/lib/lifecycles/subscribers/models-lifecycles.js +1 -1
- package/lib/lifecycles/subscribers/timestamps.js +2 -2
- package/lib/metadata/index.js +2 -2
- package/lib/metadata/relations.js +12 -15
- package/lib/migrations/index.js +5 -5
- package/lib/migrations/storage.js +4 -11
- package/lib/query/helpers/join.js +5 -5
- package/lib/query/helpers/order-by.js +1 -1
- package/lib/query/helpers/populate.js +43 -51
- package/lib/query/helpers/search.js +5 -5
- package/lib/query/helpers/transform.js +2 -2
- package/lib/query/helpers/where.js +17 -17
- package/lib/query/query-builder.js +11 -14
- package/lib/schema/builder.js +16 -14
- package/lib/schema/diff.js +15 -15
- package/lib/schema/index.js +1 -2
- package/lib/schema/schema.js +4 -4
- package/lib/schema/storage.js +3 -6
- package/lib/types/index.js +6 -6
- package/lib/utils/content-types.js +3 -3
- package/package.json +3 -3
- package/lib/errors.js +0 -56
- package/lib/fields.js +0 -231
|
@@ -5,7 +5,7 @@ const _ = require('lodash/fp');
|
|
|
5
5
|
const types = require('../../types');
|
|
6
6
|
const { fromRow } = require('./transform');
|
|
7
7
|
|
|
8
|
-
const getRootLevelPopulate = meta => {
|
|
8
|
+
const getRootLevelPopulate = (meta) => {
|
|
9
9
|
const populate = {};
|
|
10
10
|
|
|
11
11
|
for (const attributeName in meta.attributes) {
|
|
@@ -80,7 +80,7 @@ const processPopulate = (populate, ctx) => {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
if (!types.isRelation(attribute.type)) {
|
|
83
|
-
|
|
83
|
+
continue;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
// make sure id is present for future populate queries
|
|
@@ -130,21 +130,19 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
130
130
|
|
|
131
131
|
const isCount = populateValue.count === true;
|
|
132
132
|
|
|
133
|
-
const fromTargetRow = rowOrRows => fromRow(targetMeta, rowOrRows);
|
|
133
|
+
const fromTargetRow = (rowOrRows) => fromRow(targetMeta, rowOrRows);
|
|
134
134
|
|
|
135
135
|
if (attribute.relation === 'oneToOne' || attribute.relation === 'manyToOne') {
|
|
136
136
|
if (attribute.joinColumn) {
|
|
137
|
-
const {
|
|
138
|
-
|
|
139
|
-
referencedColumn: referencedColumnName,
|
|
140
|
-
} = attribute.joinColumn;
|
|
137
|
+
const { name: joinColumnName, referencedColumn: referencedColumnName } =
|
|
138
|
+
attribute.joinColumn;
|
|
141
139
|
|
|
142
140
|
const referencedValues = _.uniq(
|
|
143
|
-
results.map(r => r[joinColumnName]).filter(value => !_.isNil(value))
|
|
141
|
+
results.map((r) => r[joinColumnName]).filter((value) => !_.isNil(value))
|
|
144
142
|
);
|
|
145
143
|
|
|
146
144
|
if (_.isEmpty(referencedValues)) {
|
|
147
|
-
results.forEach(result => {
|
|
145
|
+
results.forEach((result) => {
|
|
148
146
|
result[key] = null;
|
|
149
147
|
});
|
|
150
148
|
|
|
@@ -160,7 +158,7 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
160
158
|
|
|
161
159
|
const map = _.groupBy(referencedColumnName, rows);
|
|
162
160
|
|
|
163
|
-
results.forEach(result => {
|
|
161
|
+
results.forEach((result) => {
|
|
164
162
|
result[key] = fromTargetRow(_.first(map[result[joinColumnName]]));
|
|
165
163
|
});
|
|
166
164
|
|
|
@@ -172,20 +170,18 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
172
170
|
|
|
173
171
|
const qb = db.entityManager.createQueryBuilder(targetMeta.uid);
|
|
174
172
|
|
|
175
|
-
const {
|
|
176
|
-
|
|
177
|
-
referencedColumn: referencedColumnName,
|
|
178
|
-
} = joinTable.joinColumn;
|
|
173
|
+
const { name: joinColumnName, referencedColumn: referencedColumnName } =
|
|
174
|
+
joinTable.joinColumn;
|
|
179
175
|
|
|
180
176
|
const alias = qb.getAlias();
|
|
181
177
|
const joinColAlias = `${alias}.${joinColumnName}`;
|
|
182
178
|
|
|
183
179
|
const referencedValues = _.uniq(
|
|
184
|
-
results.map(r => r[referencedColumnName]).filter(value => !_.isNil(value))
|
|
180
|
+
results.map((r) => r[referencedColumnName]).filter((value) => !_.isNil(value))
|
|
185
181
|
);
|
|
186
182
|
|
|
187
183
|
if (_.isEmpty(referencedValues)) {
|
|
188
|
-
results.forEach(result => {
|
|
184
|
+
results.forEach((result) => {
|
|
189
185
|
result[key] = null;
|
|
190
186
|
});
|
|
191
187
|
continue;
|
|
@@ -208,7 +204,7 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
208
204
|
|
|
209
205
|
const map = _.groupBy(joinColumnName, rows);
|
|
210
206
|
|
|
211
|
-
results.forEach(result => {
|
|
207
|
+
results.forEach((result) => {
|
|
212
208
|
result[key] = fromTargetRow(_.first(map[result[referencedColumnName]]));
|
|
213
209
|
});
|
|
214
210
|
|
|
@@ -218,17 +214,15 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
218
214
|
continue;
|
|
219
215
|
} else if (attribute.relation === 'oneToMany') {
|
|
220
216
|
if (attribute.joinColumn) {
|
|
221
|
-
const {
|
|
222
|
-
|
|
223
|
-
referencedColumn: referencedColumnName,
|
|
224
|
-
} = attribute.joinColumn;
|
|
217
|
+
const { name: joinColumnName, referencedColumn: referencedColumnName } =
|
|
218
|
+
attribute.joinColumn;
|
|
225
219
|
|
|
226
220
|
const referencedValues = _.uniq(
|
|
227
|
-
results.map(r => r[joinColumnName]).filter(value => !_.isNil(value))
|
|
221
|
+
results.map((r) => r[joinColumnName]).filter((value) => !_.isNil(value))
|
|
228
222
|
);
|
|
229
223
|
|
|
230
224
|
if (_.isEmpty(referencedValues)) {
|
|
231
|
-
results.forEach(result => {
|
|
225
|
+
results.forEach((result) => {
|
|
232
226
|
result[key] = null;
|
|
233
227
|
});
|
|
234
228
|
continue;
|
|
@@ -243,7 +237,7 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
243
237
|
|
|
244
238
|
const map = _.groupBy(referencedColumnName, rows);
|
|
245
239
|
|
|
246
|
-
results.forEach(result => {
|
|
240
|
+
results.forEach((result) => {
|
|
247
241
|
result[key] = fromTargetRow(map[result[joinColumnName]] || []);
|
|
248
242
|
});
|
|
249
243
|
|
|
@@ -255,21 +249,19 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
255
249
|
|
|
256
250
|
const qb = db.entityManager.createQueryBuilder(targetMeta.uid);
|
|
257
251
|
|
|
258
|
-
const {
|
|
259
|
-
|
|
260
|
-
referencedColumn: referencedColumnName,
|
|
261
|
-
} = joinTable.joinColumn;
|
|
252
|
+
const { name: joinColumnName, referencedColumn: referencedColumnName } =
|
|
253
|
+
joinTable.joinColumn;
|
|
262
254
|
|
|
263
255
|
const alias = qb.getAlias();
|
|
264
256
|
const joinColAlias = `${alias}.${joinColumnName}`;
|
|
265
257
|
|
|
266
258
|
const referencedValues = _.uniq(
|
|
267
|
-
results.map(r => r[referencedColumnName]).filter(value => !_.isNil(value))
|
|
259
|
+
results.map((r) => r[referencedColumnName]).filter((value) => !_.isNil(value))
|
|
268
260
|
);
|
|
269
261
|
|
|
270
262
|
if (isCount) {
|
|
271
263
|
if (_.isEmpty(referencedValues)) {
|
|
272
|
-
results.forEach(result => {
|
|
264
|
+
results.forEach((result) => {
|
|
273
265
|
result[key] = { count: 0 };
|
|
274
266
|
});
|
|
275
267
|
continue;
|
|
@@ -295,7 +287,7 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
295
287
|
return map;
|
|
296
288
|
}, {});
|
|
297
289
|
|
|
298
|
-
results.forEach(result => {
|
|
290
|
+
results.forEach((result) => {
|
|
299
291
|
result[key] = map[result[referencedColumnName]] || { count: 0 };
|
|
300
292
|
});
|
|
301
293
|
|
|
@@ -303,7 +295,7 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
303
295
|
}
|
|
304
296
|
|
|
305
297
|
if (_.isEmpty(referencedValues)) {
|
|
306
|
-
results.forEach(result => {
|
|
298
|
+
results.forEach((result) => {
|
|
307
299
|
result[key] = [];
|
|
308
300
|
});
|
|
309
301
|
continue;
|
|
@@ -326,7 +318,7 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
326
318
|
|
|
327
319
|
const map = _.groupBy(joinColumnName, rows);
|
|
328
320
|
|
|
329
|
-
results.forEach(r => {
|
|
321
|
+
results.forEach((r) => {
|
|
330
322
|
r[key] = fromTargetRow(map[r[referencedColumnName]] || []);
|
|
331
323
|
});
|
|
332
324
|
continue;
|
|
@@ -343,12 +335,12 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
343
335
|
const alias = qb.getAlias();
|
|
344
336
|
const joinColAlias = `${alias}.${joinColumnName}`;
|
|
345
337
|
const referencedValues = _.uniq(
|
|
346
|
-
results.map(r => r[referencedColumnName]).filter(value => !_.isNil(value))
|
|
338
|
+
results.map((r) => r[referencedColumnName]).filter((value) => !_.isNil(value))
|
|
347
339
|
);
|
|
348
340
|
|
|
349
341
|
if (isCount) {
|
|
350
342
|
if (_.isEmpty(referencedValues)) {
|
|
351
|
-
results.forEach(result => {
|
|
343
|
+
results.forEach((result) => {
|
|
352
344
|
result[key] = { count: 0 };
|
|
353
345
|
});
|
|
354
346
|
continue;
|
|
@@ -374,7 +366,7 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
374
366
|
return map;
|
|
375
367
|
}, {});
|
|
376
368
|
|
|
377
|
-
results.forEach(result => {
|
|
369
|
+
results.forEach((result) => {
|
|
378
370
|
result[key] = map[result[referencedColumnName]] || { count: 0 };
|
|
379
371
|
});
|
|
380
372
|
|
|
@@ -382,7 +374,7 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
382
374
|
}
|
|
383
375
|
|
|
384
376
|
if (_.isEmpty(referencedValues)) {
|
|
385
|
-
results.forEach(result => {
|
|
377
|
+
results.forEach((result) => {
|
|
386
378
|
result[key] = [];
|
|
387
379
|
});
|
|
388
380
|
continue;
|
|
@@ -405,7 +397,7 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
405
397
|
|
|
406
398
|
const map = _.groupBy(joinColumnName, rows);
|
|
407
399
|
|
|
408
|
-
results.forEach(result => {
|
|
400
|
+
results.forEach((result) => {
|
|
409
401
|
result[key] = fromTargetRow(map[result[referencedColumnName]] || []);
|
|
410
402
|
});
|
|
411
403
|
|
|
@@ -419,11 +411,11 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
419
411
|
const { idColumn, typeColumn } = targetAttribute.morphColumn;
|
|
420
412
|
|
|
421
413
|
const referencedValues = _.uniq(
|
|
422
|
-
results.map(r => r[idColumn.referencedColumn]).filter(value => !_.isNil(value))
|
|
414
|
+
results.map((r) => r[idColumn.referencedColumn]).filter((value) => !_.isNil(value))
|
|
423
415
|
);
|
|
424
416
|
|
|
425
417
|
if (_.isEmpty(referencedValues)) {
|
|
426
|
-
results.forEach(result => {
|
|
418
|
+
results.forEach((result) => {
|
|
427
419
|
result[key] = null;
|
|
428
420
|
});
|
|
429
421
|
|
|
@@ -439,7 +431,7 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
439
431
|
|
|
440
432
|
const map = _.groupBy(idColumn.name, rows);
|
|
441
433
|
|
|
442
|
-
results.forEach(result => {
|
|
434
|
+
results.forEach((result) => {
|
|
443
435
|
const matchingRows = map[result[idColumn.referencedColumn]];
|
|
444
436
|
|
|
445
437
|
const matchingValue =
|
|
@@ -455,11 +447,11 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
455
447
|
const { idColumn, typeColumn } = morphColumn;
|
|
456
448
|
|
|
457
449
|
const referencedValues = _.uniq(
|
|
458
|
-
results.map(r => r[idColumn.referencedColumn]).filter(value => !_.isNil(value))
|
|
450
|
+
results.map((r) => r[idColumn.referencedColumn]).filter((value) => !_.isNil(value))
|
|
459
451
|
);
|
|
460
452
|
|
|
461
453
|
if (_.isEmpty(referencedValues)) {
|
|
462
|
-
results.forEach(result => {
|
|
454
|
+
results.forEach((result) => {
|
|
463
455
|
result[key] = attribute.relation === 'morphOne' ? null : [];
|
|
464
456
|
});
|
|
465
457
|
|
|
@@ -494,7 +486,7 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
494
486
|
|
|
495
487
|
const map = _.groupBy(idColumn.name, rows);
|
|
496
488
|
|
|
497
|
-
results.forEach(result => {
|
|
489
|
+
results.forEach((result) => {
|
|
498
490
|
const matchingRows = map[result[idColumn.referencedColumn]];
|
|
499
491
|
|
|
500
492
|
const matchingValue =
|
|
@@ -515,7 +507,7 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
515
507
|
// fetch join table to create the ids map then do the same as morphToOne without the first
|
|
516
508
|
|
|
517
509
|
const referencedValues = _.uniq(
|
|
518
|
-
results.map(r => r[joinColumn.referencedColumn]).filter(value => !_.isNil(value))
|
|
510
|
+
results.map((r) => r[joinColumn.referencedColumn]).filter((value) => !_.isNil(value))
|
|
519
511
|
);
|
|
520
512
|
|
|
521
513
|
const qb = db.entityManager.createQueryBuilder(joinTable.name);
|
|
@@ -568,16 +560,16 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
568
560
|
map[type] = _.groupBy(idColumn.referencedColumn, rows);
|
|
569
561
|
}
|
|
570
562
|
|
|
571
|
-
results.forEach(result => {
|
|
563
|
+
results.forEach((result) => {
|
|
572
564
|
const joinResults = joinMap[result[joinColumn.referencedColumn]] || [];
|
|
573
565
|
|
|
574
|
-
const matchingRows = joinResults.flatMap(joinResult => {
|
|
566
|
+
const matchingRows = joinResults.flatMap((joinResult) => {
|
|
575
567
|
const id = joinResult[idColumn.name];
|
|
576
568
|
const type = joinResult[typeColumn.name];
|
|
577
569
|
|
|
578
|
-
const fromTargetRow = rowOrRows => fromRow(db.metadata.get(type), rowOrRows);
|
|
570
|
+
const fromTargetRow = (rowOrRows) => fromRow(db.metadata.get(type), rowOrRows);
|
|
579
571
|
|
|
580
|
-
return (map[type][id] || []).map(row => {
|
|
572
|
+
return (map[type][id] || []).map((row) => {
|
|
581
573
|
return {
|
|
582
574
|
[typeField]: type,
|
|
583
575
|
...fromTargetRow(row),
|
|
@@ -632,7 +624,7 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
632
624
|
map[type] = _.groupBy(idColumn.referencedColumn, rows);
|
|
633
625
|
}
|
|
634
626
|
|
|
635
|
-
results.forEach(result => {
|
|
627
|
+
results.forEach((result) => {
|
|
636
628
|
const id = result[idColumn.name];
|
|
637
629
|
const type = result[typeColumn.name];
|
|
638
630
|
|
|
@@ -643,7 +635,7 @@ const applyPopulate = async (results, populate, ctx) => {
|
|
|
643
635
|
|
|
644
636
|
const matchingRows = map[type][id];
|
|
645
637
|
|
|
646
|
-
const fromTargetRow = rowOrRows => fromRow(db.metadata.get(type), rowOrRows);
|
|
638
|
+
const fromTargetRow = (rowOrRows) => fromRow(db.metadata.get(type), rowOrRows);
|
|
647
639
|
|
|
648
640
|
result[key] = fromTargetRow(_.first(matchingRows));
|
|
649
641
|
});
|
|
@@ -13,7 +13,7 @@ const applySearch = (knex, query, ctx) => {
|
|
|
13
13
|
|
|
14
14
|
const searchColumns = ['id'];
|
|
15
15
|
|
|
16
|
-
const stringColumns = Object.keys(attributes).filter(attributeName => {
|
|
16
|
+
const stringColumns = Object.keys(attributes).filter((attributeName) => {
|
|
17
17
|
const attribute = attributes[attributeName];
|
|
18
18
|
return types.isString(attribute.type) && attribute.searchable !== false;
|
|
19
19
|
});
|
|
@@ -21,7 +21,7 @@ const applySearch = (knex, query, ctx) => {
|
|
|
21
21
|
searchColumns.push(...stringColumns);
|
|
22
22
|
|
|
23
23
|
if (!_.isNaN(_.toNumber(query))) {
|
|
24
|
-
const numberColumns = Object.keys(attributes).filter(attributeName => {
|
|
24
|
+
const numberColumns = Object.keys(attributes).filter((attributeName) => {
|
|
25
25
|
const attribute = attributes[attributeName];
|
|
26
26
|
return types.isNumber(attribute.type) && attribute.searchable !== false;
|
|
27
27
|
});
|
|
@@ -31,7 +31,7 @@ const applySearch = (knex, query, ctx) => {
|
|
|
31
31
|
|
|
32
32
|
switch (db.dialect.client) {
|
|
33
33
|
case 'postgres': {
|
|
34
|
-
searchColumns.forEach(attr => {
|
|
34
|
+
searchColumns.forEach((attr) => {
|
|
35
35
|
const columnName = toColumnName(meta, attr);
|
|
36
36
|
return knex.orWhereRaw(`??::text ILIKE ?`, [
|
|
37
37
|
qb.aliasColumn(columnName),
|
|
@@ -42,7 +42,7 @@ const applySearch = (knex, query, ctx) => {
|
|
|
42
42
|
break;
|
|
43
43
|
}
|
|
44
44
|
case 'sqlite': {
|
|
45
|
-
searchColumns.forEach(attr => {
|
|
45
|
+
searchColumns.forEach((attr) => {
|
|
46
46
|
const columnName = toColumnName(meta, attr);
|
|
47
47
|
return knex.orWhereRaw(`?? LIKE ? ESCAPE '\\'`, [
|
|
48
48
|
qb.aliasColumn(columnName),
|
|
@@ -52,7 +52,7 @@ const applySearch = (knex, query, ctx) => {
|
|
|
52
52
|
break;
|
|
53
53
|
}
|
|
54
54
|
case 'mysql': {
|
|
55
|
-
searchColumns.forEach(attr => {
|
|
55
|
+
searchColumns.forEach((attr) => {
|
|
56
56
|
const columnName = toColumnName(meta, attr);
|
|
57
57
|
return knex.orWhereRaw(`?? LIKE ?`, [
|
|
58
58
|
qb.aliasColumn(columnName),
|
|
@@ -7,7 +7,7 @@ const { createField } = require('../../fields');
|
|
|
7
7
|
|
|
8
8
|
const fromRow = (meta, row) => {
|
|
9
9
|
if (Array.isArray(row)) {
|
|
10
|
-
return row.map(singleRow => fromRow(meta, singleRow));
|
|
10
|
+
return row.map((singleRow) => fromRow(meta, singleRow));
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
const { attributes } = meta;
|
|
@@ -48,7 +48,7 @@ const toRow = (meta, data = {}) => {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
if (_.isArray(data)) {
|
|
51
|
-
return data.map(datum => toRow(meta, datum));
|
|
51
|
+
return data.map((datum) => toRow(meta, datum));
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
const { attributes } = meta;
|
|
@@ -45,7 +45,7 @@ const CAST_OPERATORS = [
|
|
|
45
45
|
|
|
46
46
|
const ARRAY_OPERATORS = ['$in', '$notIn', '$between'];
|
|
47
47
|
|
|
48
|
-
const isOperator = key => OPERATORS.includes(key);
|
|
48
|
+
const isOperator = (key) => OPERATORS.includes(key);
|
|
49
49
|
|
|
50
50
|
const castValue = (value, attribute) => {
|
|
51
51
|
if (!attribute) {
|
|
@@ -63,7 +63,7 @@ const castValue = (value, attribute) => {
|
|
|
63
63
|
|
|
64
64
|
const processAttributeWhere = (attribute, where, operator = '$eq') => {
|
|
65
65
|
if (_.isArray(where)) {
|
|
66
|
-
return where.map(sub => processAttributeWhere(attribute, sub, operator));
|
|
66
|
+
return where.map((sub) => processAttributeWhere(attribute, sub, operator));
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
if (!_.isPlainObject(where)) {
|
|
@@ -102,7 +102,7 @@ const processWhere = (where, ctx) => {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
if (_.isArray(where)) {
|
|
105
|
-
return where.map(sub => processWhere(sub, ctx));
|
|
105
|
+
return where.map((sub) => processWhere(sub, ctx));
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
const processNested = (where, ctx) => {
|
|
@@ -124,7 +124,7 @@ const processWhere = (where, ctx) => {
|
|
|
124
124
|
|
|
125
125
|
// if operator $and $or then loop over them
|
|
126
126
|
if (GROUP_OPERATORS.includes(key)) {
|
|
127
|
-
filters[key] = value.map(sub => processNested(sub, ctx));
|
|
127
|
+
filters[key] = value.map((sub) => processNested(sub, ctx));
|
|
128
128
|
continue;
|
|
129
129
|
}
|
|
130
130
|
|
|
@@ -190,9 +190,9 @@ const processWhere = (where, ctx) => {
|
|
|
190
190
|
// TODO: add type casting per operator at some point
|
|
191
191
|
const applyOperator = (qb, column, operator, value) => {
|
|
192
192
|
if (Array.isArray(value) && !ARRAY_OPERATORS.includes(operator)) {
|
|
193
|
-
return qb.where(subQB => {
|
|
194
|
-
value.forEach(subValue =>
|
|
195
|
-
subQB.orWhere(innerQB => {
|
|
193
|
+
return qb.where((subQB) => {
|
|
194
|
+
value.forEach((subValue) =>
|
|
195
|
+
subQB.orWhere((innerQB) => {
|
|
196
196
|
applyOperator(innerQB, column, operator, subValue);
|
|
197
197
|
})
|
|
198
198
|
);
|
|
@@ -201,7 +201,7 @@ const applyOperator = (qb, column, operator, value) => {
|
|
|
201
201
|
|
|
202
202
|
switch (operator) {
|
|
203
203
|
case '$not': {
|
|
204
|
-
qb.whereNot(qb => applyWhereToColumn(qb, column, value));
|
|
204
|
+
qb.whereNot((qb) => applyWhereToColumn(qb, column, value));
|
|
205
205
|
break;
|
|
206
206
|
}
|
|
207
207
|
|
|
@@ -325,7 +325,7 @@ const applyWhereToColumn = (qb, column, columnWhere) => {
|
|
|
325
325
|
return qb.where(column, columnWhere);
|
|
326
326
|
}
|
|
327
327
|
|
|
328
|
-
Object.keys(columnWhere).forEach(operator => {
|
|
328
|
+
Object.keys(columnWhere).forEach((operator) => {
|
|
329
329
|
const value = columnWhere[operator];
|
|
330
330
|
|
|
331
331
|
applyOperator(qb, column, operator, value);
|
|
@@ -338,33 +338,33 @@ const applyWhere = (qb, where) => {
|
|
|
338
338
|
}
|
|
339
339
|
|
|
340
340
|
if (_.isArray(where)) {
|
|
341
|
-
return qb.where(subQB => where.forEach(subWhere => applyWhere(subQB, subWhere)));
|
|
341
|
+
return qb.where((subQB) => where.forEach((subWhere) => applyWhere(subQB, subWhere)));
|
|
342
342
|
}
|
|
343
343
|
|
|
344
|
-
Object.keys(where).forEach(key => {
|
|
344
|
+
Object.keys(where).forEach((key) => {
|
|
345
345
|
const value = where[key];
|
|
346
346
|
|
|
347
347
|
if (key === '$and') {
|
|
348
|
-
return qb.where(subQB => {
|
|
349
|
-
value.forEach(v => applyWhere(subQB, v));
|
|
348
|
+
return qb.where((subQB) => {
|
|
349
|
+
value.forEach((v) => applyWhere(subQB, v));
|
|
350
350
|
});
|
|
351
351
|
}
|
|
352
352
|
|
|
353
353
|
if (key === '$or') {
|
|
354
|
-
return qb.where(subQB => {
|
|
355
|
-
value.forEach(v => subQB.orWhere(inner => applyWhere(inner, v)));
|
|
354
|
+
return qb.where((subQB) => {
|
|
355
|
+
value.forEach((v) => subQB.orWhere((inner) => applyWhere(inner, v)));
|
|
356
356
|
});
|
|
357
357
|
}
|
|
358
358
|
|
|
359
359
|
if (key === '$not') {
|
|
360
|
-
return qb.whereNot(qb => applyWhere(qb, value));
|
|
360
|
+
return qb.whereNot((qb) => applyWhere(qb, value));
|
|
361
361
|
}
|
|
362
362
|
|
|
363
363
|
applyWhereToColumn(qb, key, value);
|
|
364
364
|
});
|
|
365
365
|
};
|
|
366
366
|
|
|
367
|
-
const fieldLowerFn = qb => {
|
|
367
|
+
const fieldLowerFn = (qb) => {
|
|
368
368
|
// Postgres requires string to be passed
|
|
369
369
|
if (qb.client.config.client === 'postgres') {
|
|
370
370
|
return 'LOWER(CAST(?? AS VARCHAR))';
|
|
@@ -225,15 +225,9 @@ const createQueryBuilder = (uid, db) => {
|
|
|
225
225
|
this.select('id');
|
|
226
226
|
const subQB = this.getKnexQuery();
|
|
227
227
|
|
|
228
|
-
const nestedSubQuery = db
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
.from(subQB.as('subQuery'));
|
|
232
|
-
|
|
233
|
-
return db
|
|
234
|
-
.getConnection(tableName)
|
|
235
|
-
[state.type]()
|
|
236
|
-
.whereIn('id', nestedSubQuery);
|
|
228
|
+
const nestedSubQuery = db.getConnection().select('id').from(subQB.as('subQuery'));
|
|
229
|
+
|
|
230
|
+
return db.getConnection(tableName)[state.type]().whereIn('id', nestedSubQuery);
|
|
237
231
|
},
|
|
238
232
|
|
|
239
233
|
processState() {
|
|
@@ -263,11 +257,11 @@ const createQueryBuilder = (uid, db) => {
|
|
|
263
257
|
},
|
|
264
258
|
|
|
265
259
|
processSelect() {
|
|
266
|
-
state.select = state.select.map(field => helpers.toColumnName(meta, field));
|
|
260
|
+
state.select = state.select.map((field) => helpers.toColumnName(meta, field));
|
|
267
261
|
|
|
268
262
|
if (this.shouldUseDistinct()) {
|
|
269
|
-
const joinsOrderByColumns = state.joins.flatMap(join => {
|
|
270
|
-
return _.keys(join.orderBy).map(key => this.aliasColumn(key, join.alias));
|
|
263
|
+
const joinsOrderByColumns = state.joins.flatMap((join) => {
|
|
264
|
+
return _.keys(join.orderBy).map((key) => this.aliasColumn(key, join.alias));
|
|
271
265
|
});
|
|
272
266
|
const orderByColumns = state.orderBy.map(({ column }) => column);
|
|
273
267
|
|
|
@@ -292,7 +286,7 @@ const createQueryBuilder = (uid, db) => {
|
|
|
292
286
|
|
|
293
287
|
switch (state.type) {
|
|
294
288
|
case 'select': {
|
|
295
|
-
qb.select(state.select.map(column => this.aliasColumn(column)));
|
|
289
|
+
qb.select(state.select.map((column) => this.aliasColumn(column)));
|
|
296
290
|
|
|
297
291
|
if (this.shouldUseDistinct()) {
|
|
298
292
|
qb.distinct();
|
|
@@ -337,6 +331,9 @@ const createQueryBuilder = (uid, db) => {
|
|
|
337
331
|
db.truncate();
|
|
338
332
|
break;
|
|
339
333
|
}
|
|
334
|
+
default: {
|
|
335
|
+
throw new Error('Unknown query type');
|
|
336
|
+
}
|
|
340
337
|
}
|
|
341
338
|
|
|
342
339
|
if (state.transaction) {
|
|
@@ -374,7 +371,7 @@ const createQueryBuilder = (uid, db) => {
|
|
|
374
371
|
|
|
375
372
|
// if there are joins and it is a delete or update use a sub query
|
|
376
373
|
if (state.search) {
|
|
377
|
-
qb.where(subQb => {
|
|
374
|
+
qb.where((subQb) => {
|
|
378
375
|
helpers.applySearch(subQb, state.search, { qb: this, db, uid });
|
|
379
376
|
});
|
|
380
377
|
}
|
package/lib/schema/builder.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const { isNil, prop, omit, castArray } = require('lodash/fp');
|
|
4
4
|
const debug = require('debug')('strapi::database');
|
|
5
5
|
|
|
6
|
-
module.exports = db => {
|
|
6
|
+
module.exports = (db) => {
|
|
7
7
|
const helpers = createHelpers(db);
|
|
8
8
|
|
|
9
9
|
return {
|
|
@@ -20,7 +20,7 @@ module.exports = db => {
|
|
|
20
20
|
* @param {Schema} schema - database schema
|
|
21
21
|
*/
|
|
22
22
|
async createSchema(schema) {
|
|
23
|
-
await db.connection.transaction(async trx => {
|
|
23
|
+
await db.connection.transaction(async (trx) => {
|
|
24
24
|
await this.createTables(schema.tables, trx);
|
|
25
25
|
});
|
|
26
26
|
},
|
|
@@ -56,7 +56,7 @@ module.exports = db => {
|
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
await db.connection.transaction(async trx => {
|
|
59
|
+
await db.connection.transaction(async (trx) => {
|
|
60
60
|
for (const table of schema.tables.reverse()) {
|
|
61
61
|
const schemaBuilder = this.getSchemaBuilder(trx);
|
|
62
62
|
await helpers.dropTable(schemaBuilder, table);
|
|
@@ -73,7 +73,7 @@ module.exports = db => {
|
|
|
73
73
|
const { forceMigration } = db.config.settings;
|
|
74
74
|
|
|
75
75
|
await db.dialect.startSchemaUpdate();
|
|
76
|
-
await db.connection.transaction(async trx => {
|
|
76
|
+
await db.connection.transaction(async (trx) => {
|
|
77
77
|
await this.createTables(schemaDiff.tables.added, trx);
|
|
78
78
|
|
|
79
79
|
if (forceMigration) {
|
|
@@ -107,7 +107,7 @@ module.exports = db => {
|
|
|
107
107
|
};
|
|
108
108
|
};
|
|
109
109
|
|
|
110
|
-
const createHelpers = db => {
|
|
110
|
+
const createHelpers = (db) => {
|
|
111
111
|
/**
|
|
112
112
|
* Creates a foreign key on a table
|
|
113
113
|
* @param {Knex.TableBuilder} tableBuilder
|
|
@@ -243,23 +243,25 @@ const createHelpers = db => {
|
|
|
243
243
|
* @param {Table} table
|
|
244
244
|
*/
|
|
245
245
|
const createTable = async (schemaBuilder, table) => {
|
|
246
|
-
await schemaBuilder.createTable(table.name, tableBuilder => {
|
|
246
|
+
await schemaBuilder.createTable(table.name, (tableBuilder) => {
|
|
247
247
|
// columns
|
|
248
|
-
(table.columns || []).forEach(column => createColumn(tableBuilder, column));
|
|
248
|
+
(table.columns || []).forEach((column) => createColumn(tableBuilder, column));
|
|
249
249
|
|
|
250
250
|
// indexes
|
|
251
|
-
(table.indexes || []).forEach(index => createIndex(tableBuilder, index));
|
|
251
|
+
(table.indexes || []).forEach((index) => createIndex(tableBuilder, index));
|
|
252
252
|
|
|
253
253
|
// foreign keys
|
|
254
254
|
|
|
255
255
|
if (!db.dialect.canAlterConstraints()) {
|
|
256
|
-
(table.foreignKeys || []).forEach(foreignKey =>
|
|
256
|
+
(table.foreignKeys || []).forEach((foreignKey) =>
|
|
257
|
+
createForeignKey(tableBuilder, foreignKey)
|
|
258
|
+
);
|
|
257
259
|
}
|
|
258
260
|
});
|
|
259
261
|
};
|
|
260
262
|
|
|
261
263
|
const alterTable = async (schemaBuilder, table) => {
|
|
262
|
-
await schemaBuilder.alterTable(table.name, tableBuilder => {
|
|
264
|
+
await schemaBuilder.alterTable(table.name, (tableBuilder) => {
|
|
263
265
|
// Delete indexes / fks / columns
|
|
264
266
|
|
|
265
267
|
for (const removedIndex of table.indexes.removed) {
|
|
@@ -344,8 +346,8 @@ const createHelpers = db => {
|
|
|
344
346
|
*/
|
|
345
347
|
const createTableForeignKeys = async (schemaBuilder, table) => {
|
|
346
348
|
// foreign keys
|
|
347
|
-
await schemaBuilder.table(table.name, tableBuilder => {
|
|
348
|
-
(table.foreignKeys || []).forEach(foreignKey => createForeignKey(tableBuilder, foreignKey));
|
|
349
|
+
await schemaBuilder.table(table.name, (tableBuilder) => {
|
|
350
|
+
(table.foreignKeys || []).forEach((foreignKey) => createForeignKey(tableBuilder, foreignKey));
|
|
349
351
|
});
|
|
350
352
|
};
|
|
351
353
|
|
|
@@ -360,8 +362,8 @@ const createHelpers = db => {
|
|
|
360
362
|
}
|
|
361
363
|
|
|
362
364
|
// foreign keys
|
|
363
|
-
await schemaBuilder.table(table.name, tableBuilder => {
|
|
364
|
-
(table.foreignKeys || []).forEach(foreignKey => dropForeignKey(tableBuilder, foreignKey));
|
|
365
|
+
await schemaBuilder.table(table.name, (tableBuilder) => {
|
|
366
|
+
(table.foreignKeys || []).forEach((foreignKey) => dropForeignKey(tableBuilder, foreignKey));
|
|
365
367
|
});
|
|
366
368
|
};
|
|
367
369
|
|