@mikro-orm/core 7.1.15-dev.12 → 7.1.15-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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "7.1.15-dev.12",
3
+ "version": "7.1.15-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
  "keywords": [
6
6
  "data-mapper",
package/typings.d.ts CHANGED
@@ -1050,6 +1050,8 @@ export declare class EntityMetadata<Entity = any, Class extends EntityCtor<Entit
1050
1050
  constructor(meta?: Partial<EntityMetadata>);
1051
1051
  addProperty(prop: Partial<EntityProperty<Entity>>): void;
1052
1052
  removeProperty(name: string, sync?: boolean): void;
1053
+ /** For TPT entities, the version column exists only on the table of the entity that declares it. */
1054
+ ownsVersionProperty(): boolean;
1053
1055
  getPrimaryProps(flatten?: boolean): EntityProperty<Entity>[];
1054
1056
  getPrimaryProp(): EntityProperty<Entity>;
1055
1057
  /**
package/typings.js CHANGED
@@ -79,6 +79,13 @@ export class EntityMetadata {
79
79
  this.sync();
80
80
  }
81
81
  }
82
+ /** For TPT entities, the version column exists only on the table of the entity that declares it. */
83
+ ownsVersionProperty() {
84
+ if (!this.versionProperty) {
85
+ return false;
86
+ }
87
+ return this.inheritanceType !== 'tpt' || !this.ownProps || this.ownProps.some(p => p.name === this.versionProperty);
88
+ }
82
89
  getPrimaryProps(flatten = false) {
83
90
  const pks = this.primaryKeys.map(pk => this.properties[pk]);
84
91
  if (flatten) {
@@ -304,10 +304,10 @@ export class ChangeSetPersister {
304
304
  convertCustomTypes: false,
305
305
  });
306
306
  if (meta.concurrencyCheckKeys.size === 0 &&
307
- (!meta.versionProperty || changeSet.entity[meta.versionProperty] == null)) {
307
+ (!meta.ownsVersionProperty() || changeSet.entity[meta.versionProperty] == null)) {
308
308
  return this.#driver.nativeUpdate(changeSet.meta.class, cond, changeSet.payload, options);
309
309
  }
310
- if (meta.versionProperty) {
310
+ if (meta.ownsVersionProperty()) {
311
311
  cond[meta.versionProperty] = this.#platform.convertVersionValue(changeSet.entity[meta.versionProperty], meta.properties[meta.versionProperty]);
312
312
  }
313
313
  this.checkConcurrencyKeys(meta, changeSet, cond);
@@ -315,14 +315,14 @@ export class ChangeSetPersister {
315
315
  }
316
316
  async checkOptimisticLocks(meta, changeSets, options) {
317
317
  if (meta.concurrencyCheckKeys.size === 0 &&
318
- (!meta.versionProperty || changeSets.every(cs => cs.entity[meta.versionProperty] == null))) {
318
+ (!meta.ownsVersionProperty() || changeSets.every(cs => cs.entity[meta.versionProperty] == null))) {
319
319
  return;
320
320
  }
321
321
  // skip entity references as they don't have version values loaded
322
322
  changeSets = changeSets.filter(cs => helper(cs.entity).__initialized);
323
323
  const $or = changeSets.map(cs => {
324
324
  const cond = Utils.getPrimaryKeyCond(cs.originalEntity, meta.primaryKeys.concat(...meta.concurrencyCheckKeys));
325
- if (meta.versionProperty) {
325
+ if (meta.ownsVersionProperty()) {
326
326
  // @ts-ignore
327
327
  cond[meta.versionProperty] = this.#platform.convertVersionValue(cs.entity[meta.versionProperty], meta.properties[meta.versionProperty]);
328
328
  }
@@ -336,7 +336,9 @@ export class ChangeSetPersister {
336
336
  return o;
337
337
  }, {}),
338
338
  });
339
- const res = await this.#driver.find(meta.root.class, { $or }, options);
339
+ // TPT tables query their own metadata, as the version column might not live on the root table
340
+ const target = meta.inheritanceType === 'tpt' ? meta : meta.root;
341
+ const res = await this.#driver.find(target.class, { $or }, options);
340
342
  if (res.length !== changeSets.length) {
341
343
  // a FK pointing to a composite PK is an array, so the values need to be compared deeply
342
344
  const compare = (a, b, keys) => keys.every(k => equals(a[k], b[k]));
@@ -356,7 +358,7 @@ export class ChangeSetPersister {
356
358
  * so we use a single query in case of both versioning and default values is used.
357
359
  */
358
360
  async reloadVersionValues(meta, changeSets, options) {
359
- const reloadProps = meta.versionProperty && !this.#usesReturningStatement ? [meta.properties[meta.versionProperty]] : [];
361
+ const reloadProps = meta.ownsVersionProperty() && !this.#usesReturningStatement ? [meta.properties[meta.versionProperty]] : [];
360
362
  if (changeSets[0].type === ChangeSetType.CREATE) {
361
363
  for (const prop of meta.props) {
362
364
  if (prop.persist === false) {
@@ -331,6 +331,7 @@ export class UnitOfWork {
331
331
  let parentCs = changeSet.tptChangeSets.find(pc => pc.meta === current);
332
332
  if (!parentCs) {
333
333
  parentCs = new ChangeSet(entity, changeSet.type, {}, current);
334
+ parentCs.originalEntity = changeSet.originalEntity;
334
335
  changeSet.tptChangeSets.splice(idx, 0, parentCs);
335
336
  }
336
337
  idx++;
@@ -705,13 +706,14 @@ export class UnitOfWork {
705
706
  payload[pk] = identifiers[i] ?? originalChangeSet.payload[pk];
706
707
  }
707
708
  }
708
- if (!isCreate && Object.keys(payload).length === 0) {
709
+ // the table declaring the version property still needs its bump and lock check
710
+ if (!isCreate && Object.keys(payload).length === 0 && !current.ownsVersionProperty()) {
709
711
  current = current.tptParent;
710
712
  continue;
711
713
  }
712
714
  const cs = new ChangeSet(entity, originalChangeSet.type, payload, current);
715
+ cs.originalEntity = originalChangeSet.originalEntity;
713
716
  if (current === meta) {
714
- cs.originalEntity = originalChangeSet.originalEntity;
715
717
  leafCs = cs;
716
718
  }
717
719
  else {
@@ -1208,7 +1210,8 @@ export class UnitOfWork {
1208
1210
  const addToGroup = (cs) => {
1209
1211
  // Skip stub TPT changesets with empty payload (e.g. leaf with no own-property changes on UPDATE)
1210
1212
  if ((cs.type === ChangeSetType.UPDATE || cs.type === ChangeSetType.UPDATE_EARLY) &&
1211
- !Utils.hasObjectKeys(cs.payload)) {
1213
+ !Utils.hasObjectKeys(cs.payload) &&
1214
+ !cs.meta.ownsVersionProperty()) {
1212
1215
  return;
1213
1216
  }
1214
1217
  const group = groups[cs.type];
package/utils/Utils.js CHANGED
@@ -153,7 +153,7 @@ export function parseJsonSafe(value) {
153
153
  /** Collection of general-purpose utility methods used throughout the ORM. */
154
154
  export class Utils {
155
155
  static PK_SEPARATOR = '~~~';
156
- static #ORM_VERSION = '7.1.15-dev.12';
156
+ static #ORM_VERSION = '7.1.15-dev.14';
157
157
  /**
158
158
  * Checks if the argument is instance of `Object`. Returns false for arrays.
159
159
  */