@mikro-orm/core 7.1.9-dev.1 → 7.1.9-dev.11
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/hydration/ObjectHydrator.js +3 -0
- package/naming-strategy/AbstractNamingStrategy.js +2 -1
- package/naming-strategy/NamingStrategy.d.ts +2 -1
- package/package.json +1 -1
- package/unit-of-work/ChangeSetPersister.js +12 -5
- package/utils/Configuration.js +2 -1
- package/utils/EntityComparator.js +1 -0
- package/utils/Utils.js +1 -1
|
@@ -364,6 +364,9 @@ export class ObjectHydrator extends Hydrator {
|
|
|
364
364
|
ret.push(` data${dataKey}.forEach((_, idx_${idx}) => {`);
|
|
365
365
|
ret.push(...hydrateEmbedded(prop, [...path, `[idx_${idx}]`], `${dataKey}[idx_${idx}]`).map(l => ' ' + l));
|
|
366
366
|
ret.push(` });`);
|
|
367
|
+
ret.push(` } else if (data${dataKey} === null) {`);
|
|
368
|
+
/* v8 ignore next */
|
|
369
|
+
ret.push(` entity${entityKey} = ${this.config.get('forceUndefined') ? 'undefined' : 'null'};`);
|
|
367
370
|
ret.push(` }`);
|
|
368
371
|
return ret;
|
|
369
372
|
};
|
|
@@ -10,7 +10,8 @@ export class AbstractNamingStrategy {
|
|
|
10
10
|
classToMigrationName(timestamp, customMigrationName) {
|
|
11
11
|
let migrationName = `Migration${timestamp}`;
|
|
12
12
|
if (customMigrationName) {
|
|
13
|
-
|
|
13
|
+
// the name becomes part of a class identifier
|
|
14
|
+
migrationName += `_${customMigrationName.replace(/[^$\p{ID_Continue}]+/gu, '_')}`;
|
|
14
15
|
}
|
|
15
16
|
return migrationName;
|
|
16
17
|
}
|
|
@@ -9,7 +9,8 @@ export interface NamingStrategy {
|
|
|
9
9
|
*/
|
|
10
10
|
classToTableName(entityName: string, tableName?: string): string;
|
|
11
11
|
/**
|
|
12
|
-
* Return a migration name. This name should allow ordering
|
|
12
|
+
* Return a migration name. This name should allow ordering, and has to be a valid class identifier,
|
|
13
|
+
* as it is used as the class name in the generated migration file.
|
|
13
14
|
*/
|
|
14
15
|
classToMigrationName(timestamp: string, customMigrationName?: string): string;
|
|
15
16
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
|
-
"version": "7.1.9-dev.
|
|
3
|
+
"version": "7.1.9-dev.11",
|
|
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",
|
|
@@ -230,11 +230,15 @@ export class ChangeSetPersister {
|
|
|
230
230
|
}
|
|
231
231
|
const res = await this.#driver.nativeUpdateMany(meta.class, cond, payload, options);
|
|
232
232
|
const map = new Map();
|
|
233
|
-
|
|
233
|
+
// returning rows are not mapped yet, so they are keyed by field names - we need to build the hash
|
|
234
|
+
// from those to be able to match them with `getSerializedPrimaryKey()` of the entity
|
|
235
|
+
const pkFields = meta.getPrimaryProps().flatMap(prop => prop.fieldNames);
|
|
236
|
+
res.rows?.forEach(item => map.set(Utils.getPrimaryKeyHash(pkFields.map(field => item[field])), item));
|
|
234
237
|
for (const changeSet of changeSets) {
|
|
235
238
|
if (res.rows) {
|
|
236
239
|
const row = map.get(helper(changeSet.entity).getSerializedPrimaryKey());
|
|
237
|
-
|
|
240
|
+
// STI batches can mix child types, so map through the change set's own metadata
|
|
241
|
+
this.mapReturnedValues(changeSet.entity, changeSet.payload, row, changeSet.meta);
|
|
238
242
|
}
|
|
239
243
|
changeSet.persisted = true;
|
|
240
244
|
}
|
|
@@ -375,7 +379,8 @@ export class ChangeSetPersister {
|
|
|
375
379
|
changeSets.forEach(cs => {
|
|
376
380
|
Utils.keys(cs.payload).forEach(k => {
|
|
377
381
|
if (isRaw(cs.payload[k]) && isRaw(cs.entity[k])) {
|
|
378
|
-
|
|
382
|
+
// STI batches can mix child types, so the property might not exist on `meta`
|
|
383
|
+
returning.add(cs.meta.properties[k]);
|
|
379
384
|
}
|
|
380
385
|
});
|
|
381
386
|
});
|
|
@@ -400,12 +405,14 @@ export class ChangeSetPersister {
|
|
|
400
405
|
options = this.prepareOptions(meta, options, {
|
|
401
406
|
fields: Utils.unique(reloadProps.map(prop => prop.name)),
|
|
402
407
|
});
|
|
403
|
-
|
|
408
|
+
// a mixed STI batch shares one table but the child discriminator would filter out the siblings
|
|
409
|
+
const target = changeSets.some(cs => cs.meta !== meta) && meta.root.discriminatorColumn ? meta.root : meta;
|
|
410
|
+
const data = await this.#driver.find(target.class, { [pk]: { $in: pks } }, options);
|
|
404
411
|
const map = new Map();
|
|
405
412
|
data.forEach(item => map.set(Utils.getCompositeKeyHash(item, meta, false, this.#platform, true), item));
|
|
406
413
|
for (const changeSet of changeSets) {
|
|
407
414
|
const data = map.get(helper(changeSet.entity).getSerializedPrimaryKey());
|
|
408
|
-
this.#hydrator.hydrate(changeSet.entity, meta, data, this.#factory, 'full', false, true);
|
|
415
|
+
this.#hydrator.hydrate(changeSet.entity, changeSet.meta, data, this.#factory, 'full', false, true);
|
|
409
416
|
Object.assign(changeSet.payload, data); // merge to the changeset payload, so it gets saved to the entity snapshot
|
|
410
417
|
}
|
|
411
418
|
}
|
package/utils/Configuration.js
CHANGED
|
@@ -85,7 +85,8 @@ const DEFAULTS = {
|
|
|
85
85
|
safe: false,
|
|
86
86
|
snapshot: true,
|
|
87
87
|
emit: 'ts',
|
|
88
|
-
|
|
88
|
+
// mirrors `NamingStrategy.classToMigrationName`, so the file name matches the class it declares
|
|
89
|
+
fileName: (timestamp, name) => `Migration${timestamp}${name ? '_' + name.replace(/[^$\p{ID_Continue}]+/gu, '_') : ''}`,
|
|
89
90
|
},
|
|
90
91
|
schemaGenerator: {
|
|
91
92
|
createForeignKeyConstraints: true,
|
|
@@ -447,6 +447,7 @@ export class EntityComparator {
|
|
|
447
447
|
const ret = [];
|
|
448
448
|
const padding = ' '.repeat(level * 2);
|
|
449
449
|
const idx = this.#tmpIndex++;
|
|
450
|
+
ret.push(`${padding}if (entity${entityKey} === null) ret${dataKey} = null;`);
|
|
450
451
|
ret.push(`${padding}if (Array.isArray(entity${entityKey})) {`);
|
|
451
452
|
ret.push(`${padding} ret${dataKey} = [];`);
|
|
452
453
|
ret.push(`${padding} entity${entityKey}.forEach((_, idx_${idx}) => {`);
|
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.9-dev.
|
|
156
|
+
static #ORM_VERSION = '7.1.9-dev.11';
|
|
157
157
|
/**
|
|
158
158
|
* Checks if the argument is instance of `Object`. Returns false for arrays.
|
|
159
159
|
*/
|