@mikro-orm/knex 7.0.0-dev.84 → 7.0.0-dev.86

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.
@@ -792,7 +792,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
792
792
  }
793
793
  const tableName = `${schema ?? '_'}.${pivotMeta.tableName}`;
794
794
  const persister = groups[tableName] ??= new PivotCollectionPersister(pivotMeta, this, options?.ctx, schema, options?.loggerContext);
795
- persister.enqueueUpdate(coll.property, insertDiff, deleteDiff, pks);
795
+ persister.enqueueUpdate(coll.property, insertDiff, deleteDiff, pks, coll.isInitialized());
796
796
  }
797
797
  for (const persister of Utils.values(groups)) {
798
798
  await this.rethrow(persister.execute());
@@ -1063,7 +1063,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
1063
1063
  if (prop.kind === ReferenceKind.EMBEDDED && !prop.object) {
1064
1064
  return Object.entries(prop.embeddedProps).flatMap(([name, childProp]) => {
1065
1065
  const childFields = explicitFields ? Utils.extractChildElements(explicitFields, prop.name) : [];
1066
- if (childFields.length > 0 && !this.shouldHaveColumn(prop.targetMeta, { ...childProp, name }, [], childFields)) {
1066
+ if (!this.shouldHaveColumn(prop.targetMeta, { ...childProp, name }, [], childFields.length > 0 ? childFields : undefined)) {
1067
1067
  return [];
1068
1068
  }
1069
1069
  return this.mapPropToFieldNames(qb, childProp, tableAlias, childFields);
@@ -6,14 +6,17 @@ export declare class PivotCollectionPersister<Entity extends object> {
6
6
  private readonly ctx?;
7
7
  private readonly schema?;
8
8
  private readonly loggerContext?;
9
- private readonly platform;
10
9
  private readonly inserts;
10
+ private readonly upserts;
11
11
  private readonly deletes;
12
12
  private readonly batchSize;
13
13
  private order;
14
14
  constructor(meta: EntityMetadata<Entity>, driver: AbstractSqlDriver, ctx?: Transaction | undefined, schema?: string | undefined, loggerContext?: Dictionary | undefined);
15
- enqueueUpdate(prop: EntityProperty<Entity>, insertDiff: Primary<Entity>[][], deleteDiff: Primary<Entity>[][] | boolean, pks: Primary<Entity>[]): void;
15
+ enqueueUpdate(prop: EntityProperty<Entity>, insertDiff: Primary<Entity>[][], deleteDiff: Primary<Entity>[][] | boolean, pks: Primary<Entity>[], isInitialized?: boolean): void;
16
16
  private enqueueInsert;
17
+ private enqueueUpsert;
18
+ private createInsertStatement;
17
19
  private enqueueDelete;
20
+ private collectStatements;
18
21
  execute(): Promise<void>;
19
22
  }
@@ -38,8 +38,8 @@ export class PivotCollectionPersister {
38
38
  ctx;
39
39
  schema;
40
40
  loggerContext;
41
- platform;
42
41
  inserts = new Map();
42
+ upserts = new Map();
43
43
  deletes = new Map();
44
44
  batchSize;
45
45
  order = 0;
@@ -49,12 +49,16 @@ export class PivotCollectionPersister {
49
49
  this.ctx = ctx;
50
50
  this.schema = schema;
51
51
  this.loggerContext = loggerContext;
52
- this.platform = this.driver.getPlatform();
53
52
  this.batchSize = this.driver.config.get('batchSize');
54
53
  }
55
- enqueueUpdate(prop, insertDiff, deleteDiff, pks) {
54
+ enqueueUpdate(prop, insertDiff, deleteDiff, pks, isInitialized = true) {
56
55
  if (insertDiff.length) {
57
- this.enqueueInsert(prop, insertDiff, pks);
56
+ if (isInitialized) {
57
+ this.enqueueInsert(prop, insertDiff, pks);
58
+ }
59
+ else {
60
+ this.enqueueUpsert(prop, insertDiff, pks);
61
+ }
58
62
  }
59
63
  if (deleteDiff === true || (Array.isArray(deleteDiff) && deleteDiff.length)) {
60
64
  this.enqueueDelete(prop, deleteDiff, pks);
@@ -62,17 +66,29 @@ export class PivotCollectionPersister {
62
66
  }
63
67
  enqueueInsert(prop, insertDiff, pks) {
64
68
  for (const fks of insertDiff) {
65
- const data = prop.owner ? [...fks, ...pks] : [...pks, ...fks];
66
- const keys = prop.owner
67
- ? [...prop.inverseJoinColumns, ...prop.joinColumns]
68
- : [...prop.joinColumns, ...prop.inverseJoinColumns];
69
- const statement = new InsertStatement(keys, data, this.order++);
69
+ const statement = this.createInsertStatement(prop, fks, pks);
70
70
  const hash = statement.getHash();
71
71
  if (prop.owner || !this.inserts.has(hash)) {
72
72
  this.inserts.set(hash, statement);
73
73
  }
74
74
  }
75
75
  }
76
+ enqueueUpsert(prop, insertDiff, pks) {
77
+ for (const fks of insertDiff) {
78
+ const statement = this.createInsertStatement(prop, fks, pks);
79
+ const hash = statement.getHash();
80
+ if (prop.owner || !this.upserts.has(hash)) {
81
+ this.upserts.set(hash, statement);
82
+ }
83
+ }
84
+ }
85
+ createInsertStatement(prop, fks, pks) {
86
+ const data = prop.owner ? [...fks, ...pks] : [...pks, ...fks];
87
+ const keys = prop.owner
88
+ ? [...prop.inverseJoinColumns, ...prop.joinColumns]
89
+ : [...prop.joinColumns, ...prop.inverseJoinColumns];
90
+ return new InsertStatement(keys, data, this.order++);
91
+ }
76
92
  enqueueDelete(prop, deleteDiff, pks) {
77
93
  if (deleteDiff === true) {
78
94
  const statement = new DeleteStatement(prop.joinColumns, pks);
@@ -88,6 +104,13 @@ export class PivotCollectionPersister {
88
104
  this.deletes.set(statement.getHash(), statement);
89
105
  }
90
106
  }
107
+ collectStatements(statements) {
108
+ const items = [];
109
+ for (const statement of statements.values()) {
110
+ items[statement.order] = statement.getData();
111
+ }
112
+ return items.filter(Boolean);
113
+ }
91
114
  async execute() {
92
115
  if (this.deletes.size > 0) {
93
116
  const deletes = [...this.deletes.values()];
@@ -104,23 +127,33 @@ export class PivotCollectionPersister {
104
127
  });
105
128
  }
106
129
  }
107
- if (this.inserts.size === 0) {
108
- return;
109
- }
110
- let items = [];
111
- for (const insert of this.inserts.values()) {
112
- items[insert.order] = insert.getData();
130
+ if (this.inserts.size > 0) {
131
+ const filtered = this.collectStatements(this.inserts);
132
+ for (let i = 0; i < filtered.length; i += this.batchSize) {
133
+ const chunk = filtered.slice(i, i + this.batchSize);
134
+ await this.driver.nativeInsertMany(this.meta.className, chunk, {
135
+ ctx: this.ctx,
136
+ schema: this.schema,
137
+ convertCustomTypes: false,
138
+ processCollections: false,
139
+ loggerContext: this.loggerContext,
140
+ });
141
+ }
113
142
  }
114
- items = items.filter(i => i);
115
- for (let i = 0; i < items.length; i += this.batchSize) {
116
- const chunk = items.slice(i, i + this.batchSize);
117
- await this.driver.nativeInsertMany(this.meta.className, chunk, {
118
- ctx: this.ctx,
119
- schema: this.schema,
120
- convertCustomTypes: false,
121
- processCollections: false,
122
- loggerContext: this.loggerContext,
123
- });
143
+ if (this.upserts.size > 0) {
144
+ const filtered = this.collectStatements(this.upserts);
145
+ for (let i = 0; i < filtered.length; i += this.batchSize) {
146
+ const chunk = filtered.slice(i, i + this.batchSize);
147
+ await this.driver.nativeUpdateMany(this.meta.className, [], chunk, {
148
+ ctx: this.ctx,
149
+ schema: this.schema,
150
+ convertCustomTypes: false,
151
+ processCollections: false,
152
+ upsert: true,
153
+ onConflictAction: 'ignore',
154
+ loggerContext: this.loggerContext,
155
+ });
156
+ }
124
157
  }
125
158
  }
126
159
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/knex",
3
- "version": "7.0.0-dev.84",
3
+ "version": "7.0.0-dev.86",
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
  "type": "module",
6
6
  "exports": {
@@ -54,9 +54,9 @@
54
54
  "sqlstring": "2.3.3"
55
55
  },
56
56
  "devDependencies": {
57
- "@mikro-orm/core": "^6.6.1"
57
+ "@mikro-orm/core": "^6.6.2"
58
58
  },
59
59
  "peerDependencies": {
60
- "@mikro-orm/core": "7.0.0-dev.84"
60
+ "@mikro-orm/core": "7.0.0-dev.86"
61
61
  }
62
62
  }