@mikro-orm/core 7.0.0-dev.321 → 7.0.0-dev.322
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/EntityManager.d.ts +2 -15
- package/EntityManager.js +155 -152
- package/MikroORM.d.ts +1 -3
- package/MikroORM.js +20 -20
- package/cache/FileCacheAdapter.d.ts +1 -5
- package/cache/FileCacheAdapter.js +22 -22
- package/cache/GeneratedCacheAdapter.d.ts +1 -1
- package/cache/GeneratedCacheAdapter.js +6 -6
- package/cache/MemoryCacheAdapter.d.ts +1 -2
- package/cache/MemoryCacheAdapter.js +8 -8
- package/entity/Collection.d.ts +2 -10
- package/entity/Collection.js +95 -105
- package/entity/EntityFactory.d.ts +1 -8
- package/entity/EntityFactory.js +48 -48
- package/entity/EntityLoader.d.ts +1 -3
- package/entity/EntityLoader.js +33 -34
- package/entity/Reference.d.ts +1 -2
- package/entity/Reference.js +11 -11
- package/events/EventManager.d.ts +1 -4
- package/events/EventManager.js +21 -21
- package/hydration/ObjectHydrator.d.ts +1 -2
- package/hydration/ObjectHydrator.js +11 -11
- package/metadata/MetadataDiscovery.d.ts +1 -9
- package/metadata/MetadataDiscovery.js +147 -144
- package/metadata/MetadataStorage.d.ts +1 -5
- package/metadata/MetadataStorage.js +36 -36
- package/package.json +1 -1
- package/serialization/SerializationContext.d.ts +2 -6
- package/serialization/SerializationContext.js +14 -14
- package/unit-of-work/ChangeSetComputer.d.ts +1 -6
- package/unit-of-work/ChangeSetComputer.js +21 -21
- package/unit-of-work/ChangeSetPersister.d.ts +1 -9
- package/unit-of-work/ChangeSetPersister.js +51 -51
- package/unit-of-work/CommitOrderCalculator.d.ts +1 -4
- package/unit-of-work/CommitOrderCalculator.js +13 -13
- package/unit-of-work/IdentityMap.d.ts +2 -5
- package/unit-of-work/IdentityMap.js +18 -18
- package/unit-of-work/UnitOfWork.d.ts +5 -19
- package/unit-of-work/UnitOfWork.js +181 -173
- package/utils/AbstractMigrator.d.ts +1 -1
- package/utils/AbstractMigrator.js +6 -6
- package/utils/Configuration.d.ts +1 -6
- package/utils/Configuration.js +78 -78
- package/utils/Cursor.d.ts +1 -1
- package/utils/Cursor.js +3 -3
- package/utils/EntityComparator.d.ts +2 -11
- package/utils/EntityComparator.js +44 -44
- package/utils/TransactionManager.js +1 -2
- package/utils/Utils.js +1 -1
- package/utils/clone.js +1 -1
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import { type Dictionary, EntityMetadata, type EntityName } from '../typings.js';
|
|
2
2
|
import type { EntityManager } from '../EntityManager.js';
|
|
3
3
|
export declare class MetadataStorage {
|
|
4
|
+
#private;
|
|
4
5
|
static readonly PATH_SYMBOL: unique symbol;
|
|
5
|
-
private static readonly metadata;
|
|
6
|
-
private readonly metadata;
|
|
7
|
-
private readonly idMap;
|
|
8
|
-
private readonly classNameMap;
|
|
9
|
-
private readonly uniqueNameMap;
|
|
10
6
|
constructor(metadata?: Dictionary<EntityMetadata>);
|
|
11
7
|
static getMetadata(): Dictionary<EntityMetadata>;
|
|
12
8
|
static getMetadata<T = any>(entity: string, path: string): EntityMetadata<T>;
|
|
@@ -10,39 +10,39 @@ function getGlobalStorage(namespace) {
|
|
|
10
10
|
}
|
|
11
11
|
export class MetadataStorage {
|
|
12
12
|
static PATH_SYMBOL = Symbol.for('@mikro-orm/core/MetadataStorage.PATH_SYMBOL');
|
|
13
|
-
static metadata = getGlobalStorage('metadata');
|
|
14
|
-
|
|
15
|
-
idMap;
|
|
16
|
-
classNameMap;
|
|
17
|
-
uniqueNameMap;
|
|
13
|
+
static #metadata = getGlobalStorage('metadata');
|
|
14
|
+
#metadataMap = new Map();
|
|
15
|
+
#idMap;
|
|
16
|
+
#classNameMap;
|
|
17
|
+
#uniqueNameMap;
|
|
18
18
|
constructor(metadata = {}) {
|
|
19
|
-
this
|
|
20
|
-
this
|
|
21
|
-
this
|
|
22
|
-
for (const meta of Object.values(this
|
|
23
|
-
this
|
|
24
|
-
this
|
|
25
|
-
this.
|
|
19
|
+
this.#idMap = {};
|
|
20
|
+
this.#uniqueNameMap = {};
|
|
21
|
+
this.#classNameMap = Utils.copy(metadata, false);
|
|
22
|
+
for (const meta of Object.values(this.#classNameMap)) {
|
|
23
|
+
this.#idMap[meta._id] = meta;
|
|
24
|
+
this.#uniqueNameMap[meta.uniqueName] = meta;
|
|
25
|
+
this.#metadataMap.set(meta.class, meta);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
static getMetadata(entity, path) {
|
|
29
29
|
const key = entity && path ? entity + '-' + Utils.hash(path) : null;
|
|
30
|
-
if (key && !MetadataStorage
|
|
31
|
-
MetadataStorage
|
|
30
|
+
if (key && !MetadataStorage.#metadata[key]) {
|
|
31
|
+
MetadataStorage.#metadata[key] = new EntityMetadata({ className: entity, path });
|
|
32
32
|
}
|
|
33
33
|
if (key) {
|
|
34
|
-
return MetadataStorage
|
|
34
|
+
return MetadataStorage.#metadata[key];
|
|
35
35
|
}
|
|
36
|
-
return MetadataStorage
|
|
36
|
+
return MetadataStorage.#metadata;
|
|
37
37
|
}
|
|
38
38
|
static isKnownEntity(name) {
|
|
39
|
-
return !!Object.values(this
|
|
39
|
+
return !!Object.values(this.#metadata).find(meta => meta.className === name);
|
|
40
40
|
}
|
|
41
41
|
static clear() {
|
|
42
|
-
Object.keys(this
|
|
42
|
+
Object.keys(this.#metadata).forEach(k => delete this.#metadata[k]);
|
|
43
43
|
}
|
|
44
44
|
getAll() {
|
|
45
|
-
return this
|
|
45
|
+
return this.#metadataMap;
|
|
46
46
|
}
|
|
47
47
|
get(entityName, init = false) {
|
|
48
48
|
const exists = this.find(entityName);
|
|
@@ -61,50 +61,50 @@ export class MetadataStorage {
|
|
|
61
61
|
if (!entityName) {
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
64
|
-
const meta = this.
|
|
64
|
+
const meta = this.#metadataMap.get(entityName);
|
|
65
65
|
if (meta) {
|
|
66
66
|
return meta;
|
|
67
67
|
}
|
|
68
68
|
if (entityName instanceof EntitySchema) {
|
|
69
|
-
return this.
|
|
69
|
+
return this.#metadataMap.get(entityName.meta.class) ?? entityName.meta;
|
|
70
70
|
}
|
|
71
|
-
return this
|
|
71
|
+
return this.#classNameMap[Utils.className(entityName)];
|
|
72
72
|
}
|
|
73
73
|
has(entityName) {
|
|
74
|
-
return this.
|
|
74
|
+
return this.#metadataMap.has(entityName);
|
|
75
75
|
}
|
|
76
76
|
set(entityName, meta) {
|
|
77
|
-
this.
|
|
78
|
-
this
|
|
79
|
-
this
|
|
80
|
-
this
|
|
77
|
+
this.#metadataMap.set(entityName, meta);
|
|
78
|
+
this.#idMap[meta._id] = meta;
|
|
79
|
+
this.#uniqueNameMap[meta.uniqueName] = meta;
|
|
80
|
+
this.#classNameMap[Utils.className(entityName)] = meta;
|
|
81
81
|
return meta;
|
|
82
82
|
}
|
|
83
83
|
reset(entityName) {
|
|
84
84
|
const meta = this.find(entityName);
|
|
85
85
|
if (meta) {
|
|
86
|
-
this.
|
|
87
|
-
delete this
|
|
88
|
-
delete this
|
|
89
|
-
delete this
|
|
86
|
+
this.#metadataMap.delete(meta.class);
|
|
87
|
+
delete this.#idMap[meta._id];
|
|
88
|
+
delete this.#uniqueNameMap[meta.uniqueName];
|
|
89
|
+
delete this.#classNameMap[meta.className];
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
decorate(em) {
|
|
93
|
-
[...this.
|
|
93
|
+
[...this.#metadataMap.values()].filter(meta => meta.prototype).forEach(meta => EntityHelper.decorate(meta, em));
|
|
94
94
|
}
|
|
95
95
|
*[Symbol.iterator]() {
|
|
96
|
-
for (const meta of this.
|
|
96
|
+
for (const meta of this.#metadataMap.values()) {
|
|
97
97
|
yield meta;
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
getById(id) {
|
|
101
|
-
return this
|
|
101
|
+
return this.#idMap[id];
|
|
102
102
|
}
|
|
103
103
|
getByClassName(className, validate = true) {
|
|
104
|
-
return this.validate(this
|
|
104
|
+
return this.validate(this.#classNameMap[className], className, validate);
|
|
105
105
|
}
|
|
106
106
|
getByUniqueName(uniqueName, validate = true) {
|
|
107
|
-
return this.validate(this
|
|
107
|
+
return this.validate(this.#uniqueNameMap[uniqueName], uniqueName, validate);
|
|
108
108
|
}
|
|
109
109
|
validate(meta, id, validate) {
|
|
110
110
|
if (!meta && validate) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
|
-
"version": "7.0.0-dev.
|
|
3
|
+
"version": "7.0.0-dev.322",
|
|
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",
|
|
@@ -6,14 +6,10 @@ import type { Configuration } from '../utils/Configuration.js';
|
|
|
6
6
|
* are defined in populate hint). If not, we proceed and call `leave` afterwards.
|
|
7
7
|
*/
|
|
8
8
|
export declare class SerializationContext<T extends object> {
|
|
9
|
-
private
|
|
10
|
-
private readonly populate;
|
|
11
|
-
private readonly fields?;
|
|
12
|
-
private readonly exclude?;
|
|
9
|
+
#private;
|
|
13
10
|
readonly path: [EntityName, string][];
|
|
14
11
|
readonly visited: Set<Partial<any>>;
|
|
15
|
-
|
|
16
|
-
constructor(config: Configuration, populate?: PopulateOptions<T>[], fields?: Set<string> | undefined, exclude?: string[] | undefined);
|
|
12
|
+
constructor(config: Configuration, populate?: PopulateOptions<T>[], fields?: Set<string>, exclude?: string[]);
|
|
17
13
|
/**
|
|
18
14
|
* Returns true when there is a cycle detected.
|
|
19
15
|
*/
|
|
@@ -6,18 +6,18 @@ import { helper } from '../entity/wrap.js';
|
|
|
6
6
|
* are defined in populate hint). If not, we proceed and call `leave` afterwards.
|
|
7
7
|
*/
|
|
8
8
|
export class SerializationContext {
|
|
9
|
-
config;
|
|
10
|
-
populate;
|
|
11
|
-
fields;
|
|
12
|
-
exclude;
|
|
13
9
|
path = [];
|
|
14
10
|
visited = new Set();
|
|
15
|
-
entities = new Set();
|
|
11
|
+
#entities = new Set();
|
|
12
|
+
#config;
|
|
13
|
+
#populate;
|
|
14
|
+
#fields;
|
|
15
|
+
#exclude;
|
|
16
16
|
constructor(config, populate = [], fields, exclude) {
|
|
17
|
-
this
|
|
18
|
-
this
|
|
19
|
-
this
|
|
20
|
-
this
|
|
17
|
+
this.#config = config;
|
|
18
|
+
this.#populate = populate;
|
|
19
|
+
this.#fields = fields;
|
|
20
|
+
this.#exclude = exclude;
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
23
|
* Returns true when there is a cycle detected.
|
|
@@ -42,7 +42,7 @@ export class SerializationContext {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
close() {
|
|
45
|
-
for (const entity of this
|
|
45
|
+
for (const entity of this.#entities) {
|
|
46
46
|
delete helper(entity).__serializationContext.root;
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -73,7 +73,7 @@ export class SerializationContext {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
isMarkedAsPopulated(entityName, prop) {
|
|
76
|
-
let populate = this
|
|
76
|
+
let populate = this.#populate ?? [];
|
|
77
77
|
for (const segment of this.path) {
|
|
78
78
|
const hints = populate.filter(p => p.field === segment[1]);
|
|
79
79
|
if (hints.length > 0) {
|
|
@@ -93,10 +93,10 @@ export class SerializationContext {
|
|
|
93
93
|
return !!populate?.some(p => p.field === prop);
|
|
94
94
|
}
|
|
95
95
|
isPartiallyLoaded(entityName, prop) {
|
|
96
|
-
if (!this
|
|
96
|
+
if (!this.#fields) {
|
|
97
97
|
return true;
|
|
98
98
|
}
|
|
99
|
-
let fields = [...this
|
|
99
|
+
let fields = [...this.#fields];
|
|
100
100
|
for (const segment of this.path) {
|
|
101
101
|
/* v8 ignore next */
|
|
102
102
|
if (fields.length === 0) {
|
|
@@ -110,6 +110,6 @@ export class SerializationContext {
|
|
|
110
110
|
}
|
|
111
111
|
register(entity) {
|
|
112
112
|
helper(entity).__serializationContext.root = this;
|
|
113
|
-
this
|
|
113
|
+
this.#entities.add(entity);
|
|
114
114
|
}
|
|
115
115
|
}
|
|
@@ -3,12 +3,7 @@ import { ChangeSet } from './ChangeSet.js';
|
|
|
3
3
|
import { type Collection } from '../entity/Collection.js';
|
|
4
4
|
import type { EntityManager } from '../EntityManager.js';
|
|
5
5
|
export declare class ChangeSetComputer {
|
|
6
|
-
private
|
|
7
|
-
private readonly collectionUpdates;
|
|
8
|
-
private readonly comparator;
|
|
9
|
-
private readonly metadata;
|
|
10
|
-
private readonly platform;
|
|
11
|
-
private readonly config;
|
|
6
|
+
#private;
|
|
12
7
|
constructor(em: EntityManager, collectionUpdates: Set<Collection<AnyEntity>>);
|
|
13
8
|
computeChangeSet<T extends object>(entity: T): ChangeSet<T> | null;
|
|
14
9
|
/**
|
|
@@ -7,22 +7,22 @@ import { Reference } from '../entity/Reference.js';
|
|
|
7
7
|
import { PolymorphicRef } from '../entity/PolymorphicRef.js';
|
|
8
8
|
import { ReferenceKind } from '../enums.js';
|
|
9
9
|
export class ChangeSetComputer {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
#comparator;
|
|
11
|
+
#metadata;
|
|
12
|
+
#platform;
|
|
13
|
+
#config;
|
|
14
|
+
#em;
|
|
15
|
+
#collectionUpdates;
|
|
16
16
|
constructor(em, collectionUpdates) {
|
|
17
|
-
this
|
|
18
|
-
this
|
|
19
|
-
this
|
|
20
|
-
this
|
|
21
|
-
this
|
|
22
|
-
this
|
|
17
|
+
this.#em = em;
|
|
18
|
+
this.#collectionUpdates = collectionUpdates;
|
|
19
|
+
this.#config = this.#em.config;
|
|
20
|
+
this.#metadata = this.#em.getMetadata();
|
|
21
|
+
this.#platform = this.#em.getPlatform();
|
|
22
|
+
this.#comparator = this.#config.getComparator(this.#metadata);
|
|
23
23
|
}
|
|
24
24
|
computeChangeSet(entity) {
|
|
25
|
-
const meta = this
|
|
25
|
+
const meta = this.#metadata.get(entity.constructor);
|
|
26
26
|
if (meta.readonly) {
|
|
27
27
|
return null;
|
|
28
28
|
}
|
|
@@ -38,7 +38,7 @@ export class ChangeSetComputer {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
if (type === ChangeSetType.UPDATE && !wrapped.__initialized) {
|
|
41
|
-
const data = this
|
|
41
|
+
const data = this.#comparator.prepareEntity(entity);
|
|
42
42
|
if (Utils.equals(data, wrapped.__originalEntityData)) {
|
|
43
43
|
return null;
|
|
44
44
|
}
|
|
@@ -79,11 +79,11 @@ export class ChangeSetComputer {
|
|
|
79
79
|
type === ChangeSetType.CREATE &&
|
|
80
80
|
(entity[prop.name] == null ||
|
|
81
81
|
(Utils.isScalarReference(entity[prop.name]) && entity[prop.name].unwrap() == null))) {
|
|
82
|
-
entity[prop.name] = prop.onCreate(entity, this
|
|
82
|
+
entity[prop.name] = prop.onCreate(entity, this.#em);
|
|
83
83
|
}
|
|
84
84
|
if (prop.onUpdate && type === ChangeSetType.UPDATE) {
|
|
85
85
|
const pairs = map.get(entity) ?? [];
|
|
86
|
-
pairs.push([prop.name, prop.onUpdate(entity, this
|
|
86
|
+
pairs.push([prop.name, prop.onUpdate(entity, this.#em)]);
|
|
87
87
|
map.set(entity, pairs);
|
|
88
88
|
}
|
|
89
89
|
if (prop.kind === ReferenceKind.EMBEDDED && entity[prop.name]) {
|
|
@@ -93,7 +93,7 @@ export class ChangeSetComputer {
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
computePayload(entity, ignoreUndefined = false) {
|
|
96
|
-
const data = this
|
|
96
|
+
const data = this.#comparator.prepareEntity(entity);
|
|
97
97
|
const wrapped = helper(entity);
|
|
98
98
|
const entityName = wrapped.__meta.class;
|
|
99
99
|
const originalEntityData = wrapped.__originalEntityData;
|
|
@@ -104,7 +104,7 @@ export class ChangeSetComputer {
|
|
|
104
104
|
return data;
|
|
105
105
|
}
|
|
106
106
|
if (originalEntityData) {
|
|
107
|
-
const comparator = this
|
|
107
|
+
const comparator = this.#comparator.getEntityComparator(entityName);
|
|
108
108
|
const diff = comparator(originalEntityData, data);
|
|
109
109
|
if (ignoreUndefined) {
|
|
110
110
|
Utils.keys(diff)
|
|
@@ -144,7 +144,7 @@ export class ChangeSetComputer {
|
|
|
144
144
|
if (prop.targetKey && prop.targetMeta) {
|
|
145
145
|
const targetProp = prop.targetMeta.properties[prop.targetKey];
|
|
146
146
|
if (targetProp?.customType) {
|
|
147
|
-
value = targetProp.customType.convertToDatabaseValue(value, this
|
|
147
|
+
value = targetProp.customType.convertToDatabaseValue(value, this.#platform, { mode: 'serialization' });
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
if (prop.polymorphic) {
|
|
@@ -163,9 +163,9 @@ export class ChangeSetComputer {
|
|
|
163
163
|
return;
|
|
164
164
|
}
|
|
165
165
|
if (target.isDirty()) {
|
|
166
|
-
this
|
|
166
|
+
this.#collectionUpdates.add(target);
|
|
167
167
|
}
|
|
168
|
-
if (prop.owner && !this
|
|
168
|
+
if (prop.owner && !this.#platform.usesPivotTable()) {
|
|
169
169
|
changeSet.payload[prop.name] = target.getItems(false).map((item) => {
|
|
170
170
|
return item.__helper.__identifier ?? item.__helper.getPrimaryKey();
|
|
171
171
|
});
|
|
@@ -3,15 +3,7 @@ import { type ChangeSet } from './ChangeSet.js';
|
|
|
3
3
|
import type { DriverMethodOptions } from '../drivers/IDatabaseDriver.js';
|
|
4
4
|
import type { EntityManager } from '../EntityManager.js';
|
|
5
5
|
export declare class ChangeSetPersister {
|
|
6
|
-
private
|
|
7
|
-
private readonly platform;
|
|
8
|
-
private readonly comparator;
|
|
9
|
-
private readonly usesReturningStatement;
|
|
10
|
-
private readonly driver;
|
|
11
|
-
private readonly metadata;
|
|
12
|
-
private readonly hydrator;
|
|
13
|
-
private readonly factory;
|
|
14
|
-
private readonly config;
|
|
6
|
+
#private;
|
|
15
7
|
constructor(em: EntityManager);
|
|
16
8
|
executeInserts<T extends object>(changeSets: ChangeSet<T>[], options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
|
|
17
9
|
executeUpdates<T extends object>(changeSets: ChangeSet<T>[], batched: boolean, options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
|
|
@@ -7,25 +7,25 @@ import { Utils } from '../utils/Utils.js';
|
|
|
7
7
|
import { OptimisticLockError, ValidationError } from '../errors.js';
|
|
8
8
|
import { ReferenceKind } from '../enums.js';
|
|
9
9
|
export class ChangeSetPersister {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
#platform;
|
|
11
|
+
#comparator;
|
|
12
|
+
#usesReturningStatement;
|
|
13
|
+
#driver;
|
|
14
|
+
#metadata;
|
|
15
|
+
#hydrator;
|
|
16
|
+
#factory;
|
|
17
|
+
#config;
|
|
18
|
+
#em;
|
|
19
19
|
constructor(em) {
|
|
20
|
-
this
|
|
21
|
-
this
|
|
22
|
-
this
|
|
23
|
-
this
|
|
24
|
-
this
|
|
25
|
-
this
|
|
26
|
-
this
|
|
27
|
-
this
|
|
28
|
-
this
|
|
20
|
+
this.#em = em;
|
|
21
|
+
this.#driver = this.#em.getDriver();
|
|
22
|
+
this.#config = this.#em.config;
|
|
23
|
+
this.#metadata = this.#em.getMetadata();
|
|
24
|
+
this.#factory = this.#em.getEntityFactory();
|
|
25
|
+
this.#platform = this.#driver.getPlatform();
|
|
26
|
+
this.#hydrator = this.#config.getHydrator(this.#metadata);
|
|
27
|
+
this.#comparator = this.#config.getComparator(this.#metadata);
|
|
28
|
+
this.#usesReturningStatement = this.#platform.usesReturningStatement() || this.#platform.usesOutputStatement();
|
|
29
29
|
}
|
|
30
30
|
async executeInserts(changeSets, options, withSchema) {
|
|
31
31
|
if (!withSchema) {
|
|
@@ -33,7 +33,7 @@ export class ChangeSetPersister {
|
|
|
33
33
|
}
|
|
34
34
|
const meta = changeSets[0].meta;
|
|
35
35
|
changeSets.forEach(changeSet => this.processProperties(changeSet));
|
|
36
|
-
if (changeSets.length > 1 && this
|
|
36
|
+
if (changeSets.length > 1 && this.#config.get('useBatchInserts', this.#platform.usesBatchInserts())) {
|
|
37
37
|
return this.persistNewEntities(meta, changeSets, options);
|
|
38
38
|
}
|
|
39
39
|
for (const changeSet of changeSets) {
|
|
@@ -52,7 +52,7 @@ export class ChangeSetPersister {
|
|
|
52
52
|
if (batched &&
|
|
53
53
|
changeSets.length > 1 &&
|
|
54
54
|
!hasMixedTypes &&
|
|
55
|
-
this
|
|
55
|
+
this.#config.get('useBatchUpdates', this.#platform.usesBatchUpdates())) {
|
|
56
56
|
return this.persistManagedEntities(meta, changeSets, options);
|
|
57
57
|
}
|
|
58
58
|
for (const changeSet of changeSets) {
|
|
@@ -63,14 +63,14 @@ export class ChangeSetPersister {
|
|
|
63
63
|
if (!withSchema) {
|
|
64
64
|
return this.runForEachSchema(changeSets, 'executeDeletes', options);
|
|
65
65
|
}
|
|
66
|
-
const size = this
|
|
66
|
+
const size = this.#config.get('batchSize');
|
|
67
67
|
const meta = changeSets[0].meta;
|
|
68
68
|
const pk = Utils.getPrimaryKeyHash(meta.primaryKeys);
|
|
69
69
|
for (let i = 0; i < changeSets.length; i += size) {
|
|
70
70
|
const chunk = changeSets.slice(i, i + size);
|
|
71
71
|
const pks = chunk.map(cs => cs.getPrimaryKey());
|
|
72
72
|
options = this.prepareOptions(meta, options);
|
|
73
|
-
await this
|
|
73
|
+
await this.#driver.nativeDelete(meta.root.class, { [pk]: { $in: pks } }, options);
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
async runForEachSchema(changeSets, method, options, ...args) {
|
|
@@ -110,7 +110,7 @@ export class ChangeSetPersister {
|
|
|
110
110
|
for (const prop of meta.relations) {
|
|
111
111
|
this.processProperty(changeSet, prop);
|
|
112
112
|
}
|
|
113
|
-
if (changeSet.type === ChangeSetType.CREATE && this
|
|
113
|
+
if (changeSet.type === ChangeSetType.CREATE && this.#config.get('validateRequired')) {
|
|
114
114
|
this.validateRequired(changeSet.entity);
|
|
115
115
|
}
|
|
116
116
|
}
|
|
@@ -121,7 +121,7 @@ export class ChangeSetPersister {
|
|
|
121
121
|
});
|
|
122
122
|
this.resolveTPTIdentifiers(changeSet);
|
|
123
123
|
// Use changeSet's own meta for STI entities to get correct field mappings
|
|
124
|
-
const res = await this
|
|
124
|
+
const res = await this.#driver.nativeInsertMany(changeSet.meta.class, [changeSet.payload], options);
|
|
125
125
|
if (!wrapped.hasPrimaryKey()) {
|
|
126
126
|
this.mapPrimaryKey(meta, res.insertId ?? res.row?.[meta.primaryKeys[0]], changeSet);
|
|
127
127
|
}
|
|
@@ -129,23 +129,23 @@ export class ChangeSetPersister {
|
|
|
129
129
|
this.markAsPopulated(changeSet, meta);
|
|
130
130
|
wrapped.__initialized = true;
|
|
131
131
|
wrapped.__managed = true;
|
|
132
|
-
if (!this
|
|
132
|
+
if (!this.#usesReturningStatement) {
|
|
133
133
|
await this.reloadVersionValues(meta, [changeSet], options);
|
|
134
134
|
}
|
|
135
135
|
changeSet.persisted = true;
|
|
136
136
|
}
|
|
137
137
|
async persistNewEntities(meta, changeSets, options) {
|
|
138
|
-
const size = this
|
|
138
|
+
const size = this.#config.get('batchSize');
|
|
139
139
|
for (let i = 0; i < changeSets.length; i += size) {
|
|
140
140
|
const chunk = changeSets.slice(i, i + size);
|
|
141
141
|
await this.persistNewEntitiesBatch(meta, chunk, options);
|
|
142
|
-
if (!this
|
|
142
|
+
if (!this.#usesReturningStatement) {
|
|
143
143
|
await this.reloadVersionValues(meta, chunk, options);
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
prepareOptions(meta, options, additionalOptions) {
|
|
148
|
-
const loggerContext = Utils.merge({ id: this
|
|
148
|
+
const loggerContext = Utils.merge({ id: this.#em._id }, this.#em.getLoggerContext({ disableContextResolution: true }));
|
|
149
149
|
return {
|
|
150
150
|
...options,
|
|
151
151
|
...additionalOptions,
|
|
@@ -161,7 +161,7 @@ export class ChangeSetPersister {
|
|
|
161
161
|
for (const changeSet of changeSets) {
|
|
162
162
|
this.resolveTPTIdentifiers(changeSet);
|
|
163
163
|
}
|
|
164
|
-
const res = await this
|
|
164
|
+
const res = await this.#driver.nativeInsertMany(meta.class, changeSets.map(cs => cs.payload), options);
|
|
165
165
|
for (let i = 0; i < changeSets.length; i++) {
|
|
166
166
|
const changeSet = changeSets[i];
|
|
167
167
|
const wrapped = helper(changeSet.entity);
|
|
@@ -187,7 +187,7 @@ export class ChangeSetPersister {
|
|
|
187
187
|
changeSet.persisted = true;
|
|
188
188
|
}
|
|
189
189
|
async persistManagedEntities(meta, changeSets, options) {
|
|
190
|
-
const size = this
|
|
190
|
+
const size = this.#config.get('batchSize');
|
|
191
191
|
for (let i = 0; i < changeSets.length; i += size) {
|
|
192
192
|
const chunk = changeSets.slice(i, i + size);
|
|
193
193
|
await this.persistManagedEntitiesBatch(meta, chunk, options);
|
|
@@ -220,9 +220,9 @@ export class ChangeSetPersister {
|
|
|
220
220
|
cond.push(where);
|
|
221
221
|
payload.push(changeSet.payload);
|
|
222
222
|
}
|
|
223
|
-
const res = await this
|
|
223
|
+
const res = await this.#driver.nativeUpdateMany(meta.class, cond, payload, options);
|
|
224
224
|
const map = new Map();
|
|
225
|
-
res.rows?.forEach(item => map.set(Utils.getCompositeKeyHash(item, meta, true, this
|
|
225
|
+
res.rows?.forEach(item => map.set(Utils.getCompositeKeyHash(item, meta, true, this.#platform, true), item));
|
|
226
226
|
for (const changeSet of changeSets) {
|
|
227
227
|
if (res.rows) {
|
|
228
228
|
const row = map.get(helper(changeSet.entity).getSerializedPrimaryKey());
|
|
@@ -233,7 +233,7 @@ export class ChangeSetPersister {
|
|
|
233
233
|
}
|
|
234
234
|
mapPrimaryKey(meta, value, changeSet) {
|
|
235
235
|
const prop = meta.properties[meta.primaryKeys[0]];
|
|
236
|
-
const insertId = prop.customType ? prop.customType.convertToJSValue(value, this
|
|
236
|
+
const insertId = prop.customType ? prop.customType.convertToJSValue(value, this.#platform) : value;
|
|
237
237
|
const wrapped = helper(changeSet.entity);
|
|
238
238
|
if (!wrapped.hasPrimaryKey()) {
|
|
239
239
|
wrapped.setPrimaryKey(insertId);
|
|
@@ -242,7 +242,7 @@ export class ChangeSetPersister {
|
|
|
242
242
|
// but we need to have it as string so comparison works in change set tracking, so instead
|
|
243
243
|
// of using the raw value from db, we convert it back to the db value explicitly
|
|
244
244
|
value = prop.customType
|
|
245
|
-
? prop.customType.convertToDatabaseValue(insertId, this
|
|
245
|
+
? prop.customType.convertToDatabaseValue(insertId, this.#platform, { mode: 'serialization' })
|
|
246
246
|
: value;
|
|
247
247
|
changeSet.payload[wrapped.__meta.primaryKeys[0]] = value;
|
|
248
248
|
if (wrapped.__identifier && !Array.isArray(wrapped.__identifier)) {
|
|
@@ -253,8 +253,8 @@ export class ChangeSetPersister {
|
|
|
253
253
|
* Sets populate flag to new entities so they are serialized like if they were loaded from the db
|
|
254
254
|
*/
|
|
255
255
|
markAsPopulated(changeSet, meta) {
|
|
256
|
-
helper(changeSet.entity).__schema = this
|
|
257
|
-
if (!this
|
|
256
|
+
helper(changeSet.entity).__schema = this.#driver.getSchemaName(meta, changeSet);
|
|
257
|
+
if (!this.#config.get('populateAfterFlush')) {
|
|
258
258
|
return;
|
|
259
259
|
}
|
|
260
260
|
helper(changeSet.entity).populated();
|
|
@@ -275,13 +275,13 @@ export class ChangeSetPersister {
|
|
|
275
275
|
});
|
|
276
276
|
if (meta.concurrencyCheckKeys.size === 0 &&
|
|
277
277
|
(!meta.versionProperty || changeSet.entity[meta.versionProperty] == null)) {
|
|
278
|
-
return this
|
|
278
|
+
return this.#driver.nativeUpdate(changeSet.meta.class, cond, changeSet.payload, options);
|
|
279
279
|
}
|
|
280
280
|
if (meta.versionProperty) {
|
|
281
|
-
cond[meta.versionProperty] = this
|
|
281
|
+
cond[meta.versionProperty] = this.#platform.convertVersionValue(changeSet.entity[meta.versionProperty], meta.properties[meta.versionProperty]);
|
|
282
282
|
}
|
|
283
283
|
this.checkConcurrencyKeys(meta, changeSet, cond);
|
|
284
|
-
return this
|
|
284
|
+
return this.#driver.nativeUpdate(changeSet.meta.class, cond, changeSet.payload, options);
|
|
285
285
|
}
|
|
286
286
|
async checkOptimisticLocks(meta, changeSets, options) {
|
|
287
287
|
if (meta.concurrencyCheckKeys.size === 0 &&
|
|
@@ -294,7 +294,7 @@ export class ChangeSetPersister {
|
|
|
294
294
|
const cond = Utils.getPrimaryKeyCond(cs.originalEntity, meta.primaryKeys.concat(...meta.concurrencyCheckKeys));
|
|
295
295
|
if (meta.versionProperty) {
|
|
296
296
|
// @ts-ignore
|
|
297
|
-
cond[meta.versionProperty] = this
|
|
297
|
+
cond[meta.versionProperty] = this.#platform.convertVersionValue(cs.entity[meta.versionProperty], meta.properties[meta.versionProperty]);
|
|
298
298
|
}
|
|
299
299
|
return cond;
|
|
300
300
|
});
|
|
@@ -302,7 +302,7 @@ export class ChangeSetPersister {
|
|
|
302
302
|
options = this.prepareOptions(meta, options, {
|
|
303
303
|
fields: primaryKeys,
|
|
304
304
|
});
|
|
305
|
-
const res = await this
|
|
305
|
+
const res = await this.#driver.find(meta.root.class, { $or }, options);
|
|
306
306
|
if (res.length !== changeSets.length) {
|
|
307
307
|
const compare = (a, b, keys) => keys.every(k => a[k] === b[k]);
|
|
308
308
|
const entity = changeSets.find(cs => {
|
|
@@ -321,7 +321,7 @@ export class ChangeSetPersister {
|
|
|
321
321
|
* so we use a single query in case of both versioning and default values is used.
|
|
322
322
|
*/
|
|
323
323
|
async reloadVersionValues(meta, changeSets, options) {
|
|
324
|
-
const reloadProps = meta.versionProperty && !this
|
|
324
|
+
const reloadProps = meta.versionProperty && !this.#usesReturningStatement ? [meta.properties[meta.versionProperty]] : [];
|
|
325
325
|
if (changeSets[0].type === ChangeSetType.CREATE) {
|
|
326
326
|
for (const prop of meta.props) {
|
|
327
327
|
if (prop.persist === false) {
|
|
@@ -350,7 +350,7 @@ export class ChangeSetPersister {
|
|
|
350
350
|
});
|
|
351
351
|
});
|
|
352
352
|
// reload generated columns
|
|
353
|
-
if (!this
|
|
353
|
+
if (!this.#usesReturningStatement) {
|
|
354
354
|
meta.props.filter(prop => prop.generated && !prop.primary).forEach(prop => reloadProps.push(prop));
|
|
355
355
|
reloadProps.push(...returning);
|
|
356
356
|
}
|
|
@@ -363,19 +363,19 @@ export class ChangeSetPersister {
|
|
|
363
363
|
const pks = changeSets.map(cs => {
|
|
364
364
|
const val = helper(cs.entity).getPrimaryKey(true);
|
|
365
365
|
if (Utils.isPlainObject(val)) {
|
|
366
|
-
return Utils.getCompositeKeyValue(val, meta, false, this
|
|
366
|
+
return Utils.getCompositeKeyValue(val, meta, false, this.#platform);
|
|
367
367
|
}
|
|
368
368
|
return val;
|
|
369
369
|
});
|
|
370
370
|
options = this.prepareOptions(meta, options, {
|
|
371
371
|
fields: Utils.unique(reloadProps.map(prop => prop.name)),
|
|
372
372
|
});
|
|
373
|
-
const data = await this
|
|
373
|
+
const data = await this.#driver.find(meta.class, { [pk]: { $in: pks } }, options);
|
|
374
374
|
const map = new Map();
|
|
375
|
-
data.forEach(item => map.set(Utils.getCompositeKeyHash(item, meta, false, this
|
|
375
|
+
data.forEach(item => map.set(Utils.getCompositeKeyHash(item, meta, false, this.#platform, true), item));
|
|
376
376
|
for (const changeSet of changeSets) {
|
|
377
377
|
const data = map.get(helper(changeSet.entity).getSerializedPrimaryKey());
|
|
378
|
-
this
|
|
378
|
+
this.#hydrator.hydrate(changeSet.entity, meta, data, this.#factory, 'full', false, true);
|
|
379
379
|
Object.assign(changeSet.payload, data); // merge to the changeset payload, so it gets saved to the entity snapshot
|
|
380
380
|
}
|
|
381
381
|
}
|
|
@@ -431,17 +431,17 @@ export class ChangeSetPersister {
|
|
|
431
431
|
* We do need to map to the change set payload too, as it will be used in the originalEntityData for new entities.
|
|
432
432
|
*/
|
|
433
433
|
mapReturnedValues(entity, payload, row, meta, upsert = false) {
|
|
434
|
-
if ((!this
|
|
434
|
+
if ((!this.#usesReturningStatement && !upsert) || !row || !Utils.hasObjectKeys(row)) {
|
|
435
435
|
return;
|
|
436
436
|
}
|
|
437
|
-
const mapped = this
|
|
437
|
+
const mapped = this.#comparator.mapResult(meta, row);
|
|
438
438
|
if (entity) {
|
|
439
|
-
this
|
|
439
|
+
this.#hydrator.hydrate(entity, meta, mapped, this.#factory, 'full', false, true);
|
|
440
440
|
}
|
|
441
441
|
if (upsert) {
|
|
442
442
|
for (const prop of meta.props) {
|
|
443
443
|
if (prop.customType && prop.name in mapped) {
|
|
444
|
-
mapped[prop.name] = prop.customType.convertToJSValue(mapped[prop.name], this
|
|
444
|
+
mapped[prop.name] = prop.customType.convertToJSValue(mapped[prop.name], this.#platform);
|
|
445
445
|
}
|
|
446
446
|
}
|
|
447
447
|
}
|
|
@@ -26,10 +26,7 @@ export interface Edge {
|
|
|
26
26
|
* @internal
|
|
27
27
|
*/
|
|
28
28
|
export declare class CommitOrderCalculator {
|
|
29
|
-
|
|
30
|
-
private nodes;
|
|
31
|
-
/** Volatile variable holding calculated nodes during sorting process. */
|
|
32
|
-
private sortedNodeList;
|
|
29
|
+
#private;
|
|
33
30
|
/**
|
|
34
31
|
* Checks for node existence in graph.
|
|
35
32
|
*/
|