@mikro-orm/knex 6.2.9-dev.8 → 6.2.9
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/AbstractSqlDriver.d.ts +6 -0
- package/AbstractSqlDriver.js +39 -6
- package/PivotCollectionPersister.d.ts +1 -0
- package/PivotCollectionPersister.js +22 -12
- package/package.json +17 -3
- package/schema/DatabaseTable.js +1 -0
- package/schema/SchemaComparator.js +1 -1
- package/schema/SqlSchemaGenerator.js +8 -5
- package/typings.d.ts +1 -0
package/AbstractSqlDriver.d.ts
CHANGED
|
@@ -28,6 +28,12 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
|
|
|
28
28
|
nativeUpdate<T extends object>(entityName: string, where: FilterQuery<T>, data: EntityDictionary<T>, options?: NativeInsertUpdateOptions<T> & UpsertOptions<T>): Promise<QueryResult<T>>;
|
|
29
29
|
nativeUpdateMany<T extends object>(entityName: string, where: FilterQuery<T>[], data: EntityDictionary<T>[], options?: NativeInsertUpdateManyOptions<T> & UpsertManyOptions<T>): Promise<QueryResult<T>>;
|
|
30
30
|
nativeDelete<T extends object>(entityName: string, where: FilterQuery<T> | string | any, options?: DeleteOptions<T>): Promise<QueryResult<T>>;
|
|
31
|
+
/**
|
|
32
|
+
* Fast comparison for collection snapshots that are represented by PK arrays.
|
|
33
|
+
* Compares scalars via `===` and fallbacks to Utils.equals()` for more complex types like Buffer.
|
|
34
|
+
* Always expects the same length of the arrays, since we only compare PKs of the same entity type.
|
|
35
|
+
*/
|
|
36
|
+
private comparePrimaryKeyArrays;
|
|
31
37
|
syncCollections<T extends object, O extends object>(collections: Iterable<Collection<T, O>>, options?: DriverMethodOptions): Promise<void>;
|
|
32
38
|
loadFromPivotTable<T extends object, O extends object>(prop: EntityProperty, owners: Primary<O>[][], where?: FilterQuery<any>, orderBy?: OrderDefinition<T>, ctx?: Transaction, options?: FindOptions<T, any, any, any>, pivotJoin?: boolean): Promise<Dictionary<T[]>>;
|
|
33
39
|
private getPivotOrderBy;
|
package/AbstractSqlDriver.js
CHANGED
|
@@ -389,12 +389,21 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
389
389
|
const usedDups = [];
|
|
390
390
|
props.forEach(prop => {
|
|
391
391
|
if (prop.fieldNames.length > 1) {
|
|
392
|
-
const
|
|
393
|
-
const
|
|
392
|
+
const newFields = [];
|
|
393
|
+
const allParam = [...row[prop.name] ?? prop.fieldNames.map(() => null)];
|
|
394
|
+
const newParam = [];
|
|
394
395
|
prop.fieldNames.forEach((field, idx) => {
|
|
396
|
+
if (usedDups.includes(field)) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
newFields.push(field);
|
|
400
|
+
newParam.push(allParam[idx]);
|
|
401
|
+
});
|
|
402
|
+
const param = core_1.Utils.flatten(newParam);
|
|
403
|
+
newFields.forEach((field, idx) => {
|
|
395
404
|
if (!duplicates.includes(field) || !usedDups.includes(field)) {
|
|
396
405
|
params.push(param[idx]);
|
|
397
|
-
keys.push(
|
|
406
|
+
keys.push('?');
|
|
398
407
|
usedDups.push(field);
|
|
399
408
|
}
|
|
400
409
|
});
|
|
@@ -622,6 +631,26 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
622
631
|
const qb = this.createQueryBuilder(entityName, options.ctx, 'write', false).delete(where).withSchema(this.getSchemaName(meta, options));
|
|
623
632
|
return this.rethrow(qb.execute('run', false));
|
|
624
633
|
}
|
|
634
|
+
/**
|
|
635
|
+
* Fast comparison for collection snapshots that are represented by PK arrays.
|
|
636
|
+
* Compares scalars via `===` and fallbacks to Utils.equals()` for more complex types like Buffer.
|
|
637
|
+
* Always expects the same length of the arrays, since we only compare PKs of the same entity type.
|
|
638
|
+
*/
|
|
639
|
+
comparePrimaryKeyArrays(a, b) {
|
|
640
|
+
for (let i = a.length; i-- !== 0;) {
|
|
641
|
+
if (['number', 'string', 'bigint', 'boolean'].includes(typeof a[i])) {
|
|
642
|
+
if (a[i] !== b[i]) {
|
|
643
|
+
return false;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
else {
|
|
647
|
+
if (!core_1.Utils.equals(a[i], b[i])) {
|
|
648
|
+
return false;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
return true;
|
|
653
|
+
}
|
|
625
654
|
async syncCollections(collections, options) {
|
|
626
655
|
const groups = {};
|
|
627
656
|
for (const coll of collections) {
|
|
@@ -629,7 +658,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
629
658
|
const meta = wrapped.__meta;
|
|
630
659
|
const pks = wrapped.getPrimaryKeys(true);
|
|
631
660
|
const snap = coll.getSnapshot();
|
|
632
|
-
const includes = (arr, item) => !!arr.find(i =>
|
|
661
|
+
const includes = (arr, item) => !!arr.find(i => this.comparePrimaryKeyArrays(i, item));
|
|
633
662
|
const snapshot = snap ? snap.map(item => (0, core_1.helper)(item).getPrimaryKeys(true)) : [];
|
|
634
663
|
const current = coll.getItems(false).map(item => (0, core_1.helper)(item).getPrimaryKeys(true));
|
|
635
664
|
const deleteDiff = snap ? snapshot.filter(item => !includes(current, item)) : true;
|
|
@@ -639,8 +668,12 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
639
668
|
// wrong order if we just delete and insert to the end (only owning sides can have fixed order)
|
|
640
669
|
if (coll.property.owner && coll.property.fixedOrder && !equals && Array.isArray(deleteDiff)) {
|
|
641
670
|
deleteDiff.length = insertDiff.length = 0;
|
|
642
|
-
|
|
643
|
-
|
|
671
|
+
for (const item of snapshot) {
|
|
672
|
+
deleteDiff.push(item);
|
|
673
|
+
}
|
|
674
|
+
for (const item of current) {
|
|
675
|
+
insertDiff.push(item);
|
|
676
|
+
}
|
|
644
677
|
}
|
|
645
678
|
if (coll.property.kind === core_1.ReferenceKind.ONE_TO_MANY) {
|
|
646
679
|
const cols = coll.property.referencedColumnNames;
|
|
@@ -8,6 +8,7 @@ export declare class PivotCollectionPersister<Entity extends object> {
|
|
|
8
8
|
private readonly platform;
|
|
9
9
|
private readonly inserts;
|
|
10
10
|
private readonly deletes;
|
|
11
|
+
private readonly batchSize;
|
|
11
12
|
private order;
|
|
12
13
|
constructor(meta: EntityMetadata<Entity>, driver: AbstractSqlDriver, ctx?: any, schema?: string | undefined);
|
|
13
14
|
enqueueUpdate(prop: EntityProperty<Entity>, insertDiff: Primary<Entity>[][], deleteDiff: Primary<Entity>[][] | boolean, pks: Primary<Entity>[]): void;
|
|
@@ -44,6 +44,7 @@ class PivotCollectionPersister {
|
|
|
44
44
|
platform;
|
|
45
45
|
inserts = new Map();
|
|
46
46
|
deletes = new Map();
|
|
47
|
+
batchSize;
|
|
47
48
|
order = 0;
|
|
48
49
|
constructor(meta, driver, ctx, schema) {
|
|
49
50
|
this.meta = meta;
|
|
@@ -51,6 +52,7 @@ class PivotCollectionPersister {
|
|
|
51
52
|
this.ctx = ctx;
|
|
52
53
|
this.schema = schema;
|
|
53
54
|
this.platform = this.driver.getPlatform();
|
|
55
|
+
this.batchSize = this.driver.config.get('batchSize');
|
|
54
56
|
}
|
|
55
57
|
enqueueUpdate(prop, insertDiff, deleteDiff, pks) {
|
|
56
58
|
if (insertDiff.length) {
|
|
@@ -90,13 +92,18 @@ class PivotCollectionPersister {
|
|
|
90
92
|
}
|
|
91
93
|
async execute() {
|
|
92
94
|
if (this.deletes.size > 0) {
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
.
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
const deletes = [...this.deletes.values()];
|
|
96
|
+
for (let i = 0; i < deletes.length; i += this.batchSize) {
|
|
97
|
+
const chunk = deletes.slice(i, i + this.batchSize);
|
|
98
|
+
const cond = { $or: [] };
|
|
99
|
+
for (const item of chunk) {
|
|
100
|
+
cond.$or.push(item.getCondition());
|
|
101
|
+
}
|
|
102
|
+
await this.driver.nativeDelete(this.meta.className, cond, {
|
|
103
|
+
ctx: this.ctx,
|
|
104
|
+
schema: this.schema,
|
|
105
|
+
});
|
|
98
106
|
}
|
|
99
|
-
await this.driver.execute(knex.delete());
|
|
100
107
|
}
|
|
101
108
|
if (this.inserts.size === 0) {
|
|
102
109
|
return;
|
|
@@ -108,12 +115,15 @@ class PivotCollectionPersister {
|
|
|
108
115
|
items = items.filter(i => i);
|
|
109
116
|
/* istanbul ignore else */
|
|
110
117
|
if (this.platform.allowsMultiInsert()) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
118
|
+
for (let i = 0; i < items.length; i += this.batchSize) {
|
|
119
|
+
const chunk = items.slice(i, i + this.batchSize);
|
|
120
|
+
await this.driver.nativeInsertMany(this.meta.className, chunk, {
|
|
121
|
+
ctx: this.ctx,
|
|
122
|
+
schema: this.schema,
|
|
123
|
+
convertCustomTypes: false,
|
|
124
|
+
processCollections: false,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
117
127
|
}
|
|
118
128
|
else {
|
|
119
129
|
await core_1.Utils.runSerial(items, item => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/knex",
|
|
3
|
-
"version": "6.2.9
|
|
3
|
+
"version": "6.2.9",
|
|
4
4
|
"description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "index.mjs",
|
|
@@ -63,9 +63,23 @@
|
|
|
63
63
|
"sqlstring": "2.3.3"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@mikro-orm/core": "^6.2.
|
|
66
|
+
"@mikro-orm/core": "^6.2.9"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
|
-
"@mikro-orm/core": "6.
|
|
69
|
+
"@mikro-orm/core": "^6.0.0",
|
|
70
|
+
"better-sqlite3": "*",
|
|
71
|
+
"libsql": "*",
|
|
72
|
+
"mariadb": "*"
|
|
73
|
+
},
|
|
74
|
+
"peerDependenciesMeta": {
|
|
75
|
+
"better-sqlite3": {
|
|
76
|
+
"optional": true
|
|
77
|
+
},
|
|
78
|
+
"libsql": {
|
|
79
|
+
"optional": true
|
|
80
|
+
},
|
|
81
|
+
"mariadb": {
|
|
82
|
+
"optional": true
|
|
83
|
+
}
|
|
70
84
|
}
|
|
71
85
|
}
|
package/schema/DatabaseTable.js
CHANGED
|
@@ -484,7 +484,7 @@ class SchemaComparator {
|
|
|
484
484
|
// index that has no constraints.
|
|
485
485
|
return true;
|
|
486
486
|
}
|
|
487
|
-
return index1.primary === index2.primary && index1.unique === index2.unique;
|
|
487
|
+
return index1.primary === index2.primary && index1.unique === index2.unique && index1.deferMode === index2.deferMode;
|
|
488
488
|
}
|
|
489
489
|
diffExpression(expr1, expr2) {
|
|
490
490
|
// expressions like check constraints might be normalized by the driver,
|
|
@@ -90,11 +90,11 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
90
90
|
await this.execute(sql);
|
|
91
91
|
}
|
|
92
92
|
async createNamespace(name) {
|
|
93
|
-
const sql =
|
|
93
|
+
const sql = this.helper.getCreateNamespaceSQL(name);
|
|
94
94
|
await this.execute(sql);
|
|
95
95
|
}
|
|
96
96
|
async dropNamespace(name) {
|
|
97
|
-
const sql =
|
|
97
|
+
const sql = this.helper.getDropNamespaceSQL(name);
|
|
98
98
|
await this.execute(sql);
|
|
99
99
|
}
|
|
100
100
|
async clearDatabase(options) {
|
|
@@ -359,14 +359,17 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
359
359
|
const foreignKey = Object.values(diff.addedForeignKeys).find(fk => fk.columnNames.length === 1 && fk.columnNames[0] === column.name);
|
|
360
360
|
if (foreignKey && this.options.createForeignKeyConstraints) {
|
|
361
361
|
delete diff.addedForeignKeys[foreignKey.constraintName];
|
|
362
|
-
col.references(foreignKey.referencedColumnNames[0])
|
|
362
|
+
const builder = col.references(foreignKey.referencedColumnNames[0])
|
|
363
363
|
.inTable(this.getReferencedTableName(foreignKey.referencedTableName))
|
|
364
364
|
.withKeyName(foreignKey.constraintName)
|
|
365
365
|
.onUpdate(foreignKey.updateRule)
|
|
366
366
|
.onDelete(foreignKey.deleteRule);
|
|
367
|
+
if (foreignKey.deferMode) {
|
|
368
|
+
builder.deferrable(foreignKey.deferMode);
|
|
369
|
+
}
|
|
367
370
|
}
|
|
368
371
|
}
|
|
369
|
-
for (const { column, changedProperties
|
|
372
|
+
for (const { column, changedProperties } of Object.values(diff.changedColumns)) {
|
|
370
373
|
if (changedProperties.size === 1 && changedProperties.has('comment')) {
|
|
371
374
|
continue;
|
|
372
375
|
}
|
|
@@ -527,7 +530,7 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
|
|
|
527
530
|
table.index(columns.map(column => this.knex.raw(column)), index.keyName, { indexType: 'unique' });
|
|
528
531
|
}
|
|
529
532
|
else {
|
|
530
|
-
table.unique(index.columnNames, { indexName: index.keyName });
|
|
533
|
+
table.unique(index.columnNames, { indexName: index.keyName, deferrable: index.deferMode });
|
|
531
534
|
}
|
|
532
535
|
}
|
|
533
536
|
else if (index.expression) {
|