@mikro-orm/knex 6.2.9-dev.12 → 6.2.9-dev.14

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.
@@ -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;
@@ -631,6 +631,26 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
631
631
  const qb = this.createQueryBuilder(entityName, options.ctx, 'write', false).delete(where).withSchema(this.getSchemaName(meta, options));
632
632
  return this.rethrow(qb.execute('run', false));
633
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
+ }
634
654
  async syncCollections(collections, options) {
635
655
  const groups = {};
636
656
  for (const coll of collections) {
@@ -638,7 +658,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
638
658
  const meta = wrapped.__meta;
639
659
  const pks = wrapped.getPrimaryKeys(true);
640
660
  const snap = coll.getSnapshot();
641
- const includes = (arr, item) => !!arr.find(i => core_1.Utils.equals(i, item));
661
+ const includes = (arr, item) => !!arr.find(i => this.comparePrimaryKeyArrays(i, item));
642
662
  const snapshot = snap ? snap.map(item => (0, core_1.helper)(item).getPrimaryKeys(true)) : [];
643
663
  const current = coll.getItems(false).map(item => (0, core_1.helper)(item).getPrimaryKeys(true));
644
664
  const deleteDiff = snap ? snapshot.filter(item => !includes(current, item)) : true;
@@ -648,8 +668,12 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
648
668
  // wrong order if we just delete and insert to the end (only owning sides can have fixed order)
649
669
  if (coll.property.owner && coll.property.fixedOrder && !equals && Array.isArray(deleteDiff)) {
650
670
  deleteDiff.length = insertDiff.length = 0;
651
- deleteDiff.push(...snapshot);
652
- insertDiff.push(...current);
671
+ for (const item of snapshot) {
672
+ deleteDiff.push(item);
673
+ }
674
+ for (const item of current) {
675
+ insertDiff.push(item);
676
+ }
653
677
  }
654
678
  if (coll.property.kind === core_1.ReferenceKind.ONE_TO_MANY) {
655
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 knex = this.driver.createQueryBuilder(this.meta.className, this.ctx, 'write')
94
- .withSchema(this.schema)
95
- .getKnex();
96
- for (const item of this.deletes.values()) {
97
- knex.orWhere(item.getCondition());
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
- await this.driver.nativeInsertMany(this.meta.className, items, {
112
- ctx: this.ctx,
113
- schema: this.schema,
114
- convertCustomTypes: false,
115
- processCollections: false,
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-dev.12",
3
+ "version": "6.2.9-dev.14",
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",
@@ -66,6 +66,6 @@
66
66
  "@mikro-orm/core": "^6.2.8"
67
67
  },
68
68
  "peerDependencies": {
69
- "@mikro-orm/core": "6.2.9-dev.12"
69
+ "@mikro-orm/core": "6.2.9-dev.14"
70
70
  }
71
71
  }