@mikro-orm/core 7.0.0-dev.21 → 7.0.0-dev.211
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 +99 -57
- package/EntityManager.js +302 -276
- package/MikroORM.d.ts +44 -35
- package/MikroORM.js +103 -143
- package/README.md +3 -2
- package/cache/FileCacheAdapter.d.ts +1 -1
- package/cache/FileCacheAdapter.js +8 -7
- package/cache/GeneratedCacheAdapter.d.ts +0 -1
- package/cache/GeneratedCacheAdapter.js +0 -2
- package/cache/index.d.ts +0 -1
- package/cache/index.js +0 -1
- package/connections/Connection.d.ts +16 -7
- package/connections/Connection.js +23 -14
- package/drivers/DatabaseDriver.d.ts +25 -16
- package/drivers/DatabaseDriver.js +80 -35
- package/drivers/IDatabaseDriver.d.ts +44 -17
- package/entity/BaseEntity.d.ts +2 -2
- package/entity/BaseEntity.js +0 -3
- package/entity/Collection.d.ts +94 -29
- package/entity/Collection.js +434 -97
- package/entity/EntityAssigner.d.ts +1 -1
- package/entity/EntityAssigner.js +26 -18
- package/entity/EntityFactory.d.ts +13 -1
- package/entity/EntityFactory.js +84 -53
- package/entity/EntityHelper.d.ts +2 -2
- package/entity/EntityHelper.js +40 -15
- package/entity/EntityLoader.d.ts +6 -6
- package/entity/EntityLoader.js +119 -82
- package/entity/EntityRepository.d.ts +24 -4
- package/entity/EntityRepository.js +8 -2
- package/entity/Reference.d.ts +6 -5
- package/entity/Reference.js +34 -9
- package/entity/WrappedEntity.d.ts +2 -7
- package/entity/WrappedEntity.js +3 -8
- package/entity/defineEntity.d.ts +594 -0
- package/entity/defineEntity.js +533 -0
- package/entity/index.d.ts +3 -2
- package/entity/index.js +3 -2
- package/entity/utils.d.ts +7 -0
- package/entity/utils.js +16 -4
- package/entity/validators.d.ts +11 -0
- package/entity/validators.js +65 -0
- package/enums.d.ts +21 -5
- package/enums.js +15 -1
- package/errors.d.ts +23 -9
- package/errors.js +59 -21
- package/events/EventManager.d.ts +2 -1
- package/events/EventManager.js +19 -11
- package/hydration/Hydrator.js +1 -2
- package/hydration/ObjectHydrator.d.ts +4 -4
- package/hydration/ObjectHydrator.js +52 -33
- package/index.d.ts +2 -2
- package/index.js +1 -2
- package/logging/DefaultLogger.d.ts +1 -1
- package/logging/DefaultLogger.js +1 -0
- package/logging/SimpleLogger.d.ts +1 -1
- package/logging/colors.d.ts +1 -1
- package/logging/colors.js +7 -6
- package/logging/index.d.ts +1 -0
- package/logging/index.js +1 -0
- package/logging/inspect.d.ts +2 -0
- package/logging/inspect.js +11 -0
- package/metadata/EntitySchema.d.ts +40 -23
- package/metadata/EntitySchema.js +81 -34
- package/metadata/MetadataDiscovery.d.ts +7 -10
- package/metadata/MetadataDiscovery.js +391 -331
- package/metadata/MetadataProvider.d.ts +11 -2
- package/metadata/MetadataProvider.js +46 -2
- package/metadata/MetadataStorage.d.ts +13 -11
- package/metadata/MetadataStorage.js +70 -37
- package/metadata/MetadataValidator.d.ts +17 -9
- package/metadata/MetadataValidator.js +97 -40
- package/metadata/discover-entities.d.ts +5 -0
- package/metadata/discover-entities.js +40 -0
- package/metadata/index.d.ts +1 -1
- package/metadata/index.js +1 -1
- package/metadata/types.d.ts +502 -0
- package/metadata/types.js +1 -0
- package/naming-strategy/AbstractNamingStrategy.d.ts +12 -4
- package/naming-strategy/AbstractNamingStrategy.js +14 -2
- package/naming-strategy/EntityCaseNamingStrategy.d.ts +3 -3
- package/naming-strategy/EntityCaseNamingStrategy.js +6 -5
- package/naming-strategy/MongoNamingStrategy.d.ts +3 -3
- package/naming-strategy/MongoNamingStrategy.js +6 -6
- package/naming-strategy/NamingStrategy.d.ts +24 -4
- package/naming-strategy/UnderscoreNamingStrategy.d.ts +3 -3
- package/naming-strategy/UnderscoreNamingStrategy.js +6 -6
- package/not-supported.d.ts +2 -0
- package/not-supported.js +4 -0
- package/package.json +18 -11
- package/platforms/ExceptionConverter.js +1 -1
- package/platforms/Platform.d.ts +7 -13
- package/platforms/Platform.js +20 -43
- package/serialization/EntitySerializer.d.ts +5 -0
- package/serialization/EntitySerializer.js +47 -27
- package/serialization/EntityTransformer.js +28 -18
- package/serialization/SerializationContext.d.ts +6 -6
- package/serialization/SerializationContext.js +16 -13
- package/types/ArrayType.d.ts +1 -1
- package/types/ArrayType.js +2 -3
- package/types/BigIntType.d.ts +8 -6
- package/types/BigIntType.js +1 -1
- package/types/BlobType.d.ts +0 -1
- package/types/BlobType.js +0 -3
- package/types/BooleanType.d.ts +2 -1
- package/types/BooleanType.js +3 -0
- package/types/DecimalType.d.ts +6 -4
- package/types/DecimalType.js +3 -3
- package/types/DoubleType.js +2 -2
- package/types/EnumArrayType.js +1 -2
- package/types/JsonType.d.ts +1 -1
- package/types/JsonType.js +7 -2
- package/types/TinyIntType.js +1 -1
- package/types/Type.d.ts +2 -4
- package/types/Type.js +3 -3
- package/types/Uint8ArrayType.d.ts +0 -1
- package/types/Uint8ArrayType.js +1 -4
- package/types/index.d.ts +1 -1
- package/typings.d.ts +290 -137
- package/typings.js +59 -44
- package/unit-of-work/ChangeSet.d.ts +2 -6
- package/unit-of-work/ChangeSet.js +4 -5
- package/unit-of-work/ChangeSetComputer.d.ts +1 -3
- package/unit-of-work/ChangeSetComputer.js +26 -13
- package/unit-of-work/ChangeSetPersister.d.ts +5 -4
- package/unit-of-work/ChangeSetPersister.js +70 -34
- package/unit-of-work/CommitOrderCalculator.d.ts +12 -10
- package/unit-of-work/CommitOrderCalculator.js +13 -13
- package/unit-of-work/IdentityMap.d.ts +12 -0
- package/unit-of-work/IdentityMap.js +39 -1
- package/unit-of-work/UnitOfWork.d.ts +23 -3
- package/unit-of-work/UnitOfWork.js +175 -98
- package/utils/AbstractSchemaGenerator.d.ts +5 -5
- package/utils/AbstractSchemaGenerator.js +18 -16
- package/utils/AsyncContext.d.ts +6 -0
- package/utils/AsyncContext.js +42 -0
- package/utils/Configuration.d.ts +785 -207
- package/utils/Configuration.js +147 -190
- package/utils/ConfigurationLoader.d.ts +1 -54
- package/utils/ConfigurationLoader.js +1 -352
- package/utils/Cursor.d.ts +0 -3
- package/utils/Cursor.js +27 -11
- package/utils/DataloaderUtils.d.ts +15 -5
- package/utils/DataloaderUtils.js +64 -30
- package/utils/EntityComparator.d.ts +13 -9
- package/utils/EntityComparator.js +101 -42
- package/utils/QueryHelper.d.ts +14 -6
- package/utils/QueryHelper.js +87 -25
- package/utils/RawQueryFragment.d.ts +48 -25
- package/utils/RawQueryFragment.js +66 -70
- package/utils/RequestContext.js +2 -2
- package/utils/TransactionContext.js +2 -2
- package/utils/TransactionManager.d.ts +65 -0
- package/utils/TransactionManager.js +223 -0
- package/utils/Utils.d.ts +13 -126
- package/utils/Utils.js +100 -391
- package/utils/clone.js +8 -23
- package/utils/env-vars.d.ts +7 -0
- package/utils/env-vars.js +97 -0
- package/utils/fs-utils.d.ts +32 -0
- package/utils/fs-utils.js +178 -0
- package/utils/index.d.ts +2 -1
- package/utils/index.js +2 -1
- package/utils/upsert-utils.d.ts +9 -4
- package/utils/upsert-utils.js +55 -4
- package/decorators/Check.d.ts +0 -3
- package/decorators/Check.js +0 -13
- package/decorators/CreateRequestContext.d.ts +0 -3
- package/decorators/CreateRequestContext.js +0 -32
- package/decorators/Embeddable.d.ts +0 -8
- package/decorators/Embeddable.js +0 -11
- package/decorators/Embedded.d.ts +0 -12
- package/decorators/Embedded.js +0 -18
- package/decorators/Entity.d.ts +0 -18
- package/decorators/Entity.js +0 -12
- package/decorators/Enum.d.ts +0 -9
- package/decorators/Enum.js +0 -16
- package/decorators/Filter.d.ts +0 -2
- package/decorators/Filter.js +0 -8
- package/decorators/Formula.d.ts +0 -4
- package/decorators/Formula.js +0 -15
- package/decorators/Indexed.d.ts +0 -19
- package/decorators/Indexed.js +0 -20
- package/decorators/ManyToMany.d.ts +0 -40
- package/decorators/ManyToMany.js +0 -14
- package/decorators/ManyToOne.d.ts +0 -32
- package/decorators/ManyToOne.js +0 -14
- package/decorators/OneToMany.d.ts +0 -28
- package/decorators/OneToMany.js +0 -17
- package/decorators/OneToOne.d.ts +0 -26
- package/decorators/OneToOne.js +0 -7
- package/decorators/PrimaryKey.d.ts +0 -8
- package/decorators/PrimaryKey.js +0 -20
- package/decorators/Property.d.ts +0 -250
- package/decorators/Property.js +0 -32
- package/decorators/Transactional.d.ts +0 -13
- package/decorators/Transactional.js +0 -28
- package/decorators/hooks.d.ts +0 -16
- package/decorators/hooks.js +0 -47
- package/decorators/index.d.ts +0 -17
- package/decorators/index.js +0 -17
- package/entity/ArrayCollection.d.ts +0 -116
- package/entity/ArrayCollection.js +0 -402
- package/entity/EntityValidator.d.ts +0 -19
- package/entity/EntityValidator.js +0 -150
- package/exports.d.ts +0 -24
- package/exports.js +0 -23
- package/metadata/ReflectMetadataProvider.d.ts +0 -8
- package/metadata/ReflectMetadataProvider.js +0 -44
- package/utils/resolveContextProvider.d.ts +0 -10
- package/utils/resolveContextProvider.js +0 -28
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
1
|
import { Collection } from '../entity/Collection.js';
|
|
3
2
|
import { EntityHelper } from '../entity/EntityHelper.js';
|
|
4
3
|
import { helper } from '../entity/wrap.js';
|
|
@@ -13,8 +12,9 @@ import { Cascade, DeferMode, EventType, LockMode, ReferenceKind } from '../enums
|
|
|
13
12
|
import { OptimisticLockError, ValidationError } from '../errors.js';
|
|
14
13
|
import { TransactionEventBroadcaster } from '../events/TransactionEventBroadcaster.js';
|
|
15
14
|
import { IdentityMap } from './IdentityMap.js';
|
|
15
|
+
import { createAsyncContext } from '../utils/AsyncContext.js';
|
|
16
16
|
// to deal with validation for flush inside flush hooks and `Promise.all`
|
|
17
|
-
const insideFlush =
|
|
17
|
+
const insideFlush = createAsyncContext();
|
|
18
18
|
export class UnitOfWork {
|
|
19
19
|
em;
|
|
20
20
|
/** map of references to managed entities */
|
|
@@ -42,8 +42,8 @@ export class UnitOfWork {
|
|
|
42
42
|
this.identityMap = new IdentityMap(this.platform.getDefaultSchemaName());
|
|
43
43
|
this.eventManager = this.em.getEventManager();
|
|
44
44
|
this.comparator = this.em.getComparator();
|
|
45
|
-
this.changeSetComputer = new ChangeSetComputer(this.
|
|
46
|
-
this.changeSetPersister = new ChangeSetPersister(this.em.getDriver(), this.metadata, this.em.config.getHydrator(this.metadata), this.em.getEntityFactory(), this.em.
|
|
45
|
+
this.changeSetComputer = new ChangeSetComputer(this.collectionUpdates, this.metadata, this.platform, this.em.config, this.em);
|
|
46
|
+
this.changeSetPersister = new ChangeSetPersister(this.em.getDriver(), this.metadata, this.em.config.getHydrator(this.metadata), this.em.getEntityFactory(), this.em.config, this.em);
|
|
47
47
|
}
|
|
48
48
|
merge(entity, visited) {
|
|
49
49
|
const wrapped = helper(entity);
|
|
@@ -61,10 +61,43 @@ export class UnitOfWork {
|
|
|
61
61
|
// as there can be some entity with already changed state that is not yet flushed
|
|
62
62
|
if (wrapped.__initialized && (!visited || !wrapped.__originalEntityData)) {
|
|
63
63
|
wrapped.__originalEntityData = this.comparator.prepareEntity(entity);
|
|
64
|
-
wrapped.__touched = false;
|
|
65
64
|
}
|
|
66
65
|
this.cascade(entity, Cascade.MERGE, visited ?? new Set());
|
|
67
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Entity data can wary in its shape, e.g. we might get a deep relation graph with joined strategy, but for diffing,
|
|
69
|
+
* we need to normalize the shape, so relation values are only raw FKs. This method handles that.
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
72
|
+
normalizeEntityData(meta, data) {
|
|
73
|
+
const forceUndefined = this.em.config.get('forceUndefined');
|
|
74
|
+
for (const key of Utils.keys(data)) {
|
|
75
|
+
const prop = meta.properties[key];
|
|
76
|
+
if (!prop) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(data[prop.name])) {
|
|
80
|
+
data[prop.name] = Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta, true);
|
|
81
|
+
}
|
|
82
|
+
else if (prop.kind === ReferenceKind.EMBEDDED && !prop.object && Utils.isPlainObject(data[prop.name])) {
|
|
83
|
+
for (const p of prop.targetMeta.props) {
|
|
84
|
+
/* v8 ignore next */
|
|
85
|
+
const prefix = prop.prefix === false ? '' : prop.prefix === true ? prop.name + '_' : prop.prefix;
|
|
86
|
+
data[prefix + p.name] = data[prop.name][p.name];
|
|
87
|
+
}
|
|
88
|
+
data[prop.name] = Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta, true);
|
|
89
|
+
}
|
|
90
|
+
if (prop.hydrate === false && prop.customType?.ensureComparable(meta, prop)) {
|
|
91
|
+
const converted = prop.customType.convertToJSValue(data[key], this.platform, { key, mode: 'hydration', force: true });
|
|
92
|
+
data[key] = prop.customType.convertToDatabaseValue(converted, this.platform, { key, mode: 'hydration' });
|
|
93
|
+
}
|
|
94
|
+
if (forceUndefined) {
|
|
95
|
+
if (data[key] === null) {
|
|
96
|
+
data[key] = undefined;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
68
101
|
/**
|
|
69
102
|
* @internal
|
|
70
103
|
*/
|
|
@@ -82,31 +115,14 @@ export class UnitOfWork {
|
|
|
82
115
|
wrapped.__em ??= this.em;
|
|
83
116
|
wrapped.__managed = true;
|
|
84
117
|
if (data && (options?.refresh || !wrapped.__originalEntityData)) {
|
|
118
|
+
this.normalizeEntityData(wrapped.__meta, data);
|
|
85
119
|
for (const key of Utils.keys(data)) {
|
|
86
120
|
const prop = wrapped.__meta.properties[key];
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
wrapped.__loadedProperties.add(key);
|
|
91
|
-
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(data[prop.name])) {
|
|
92
|
-
data[prop.name] = Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta.primaryKeys, true);
|
|
93
|
-
}
|
|
94
|
-
else if (prop.kind === ReferenceKind.EMBEDDED && !prop.object && Utils.isPlainObject(data[prop.name])) {
|
|
95
|
-
for (const p of prop.targetMeta.props) {
|
|
96
|
-
/* v8 ignore next */
|
|
97
|
-
const prefix = prop.prefix === false ? '' : prop.prefix === true ? prop.name + '_' : prop.prefix;
|
|
98
|
-
data[prefix + p.name] = data[prop.name][p.name];
|
|
99
|
-
}
|
|
100
|
-
data[prop.name] = Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta.primaryKeys, true);
|
|
101
|
-
}
|
|
102
|
-
if (forceUndefined) {
|
|
103
|
-
if (data[key] === null) {
|
|
104
|
-
data[key] = undefined;
|
|
105
|
-
}
|
|
121
|
+
if (prop) {
|
|
122
|
+
wrapped.__loadedProperties.add(key);
|
|
106
123
|
}
|
|
107
124
|
}
|
|
108
125
|
wrapped.__originalEntityData = data;
|
|
109
|
-
wrapped.__touched = false;
|
|
110
126
|
}
|
|
111
127
|
return entity;
|
|
112
128
|
}
|
|
@@ -125,7 +141,7 @@ export class UnitOfWork {
|
|
|
125
141
|
/**
|
|
126
142
|
* Returns entity from the identity map. For composite keys, you need to pass an array of PKs in the same order as they are defined in `meta.primaryKeys`.
|
|
127
143
|
*/
|
|
128
|
-
getById(entityName, id, schema) {
|
|
144
|
+
getById(entityName, id, schema, convertCustomTypes) {
|
|
129
145
|
if (id == null || (Array.isArray(id) && id.length === 0)) {
|
|
130
146
|
return undefined;
|
|
131
147
|
}
|
|
@@ -135,7 +151,16 @@ export class UnitOfWork {
|
|
|
135
151
|
hash = '' + id;
|
|
136
152
|
}
|
|
137
153
|
else {
|
|
138
|
-
|
|
154
|
+
let keys = Array.isArray(id) ? Utils.flatten(id) : [id];
|
|
155
|
+
keys = meta.getPrimaryProps(true).map((p, i) => {
|
|
156
|
+
if (!convertCustomTypes && p.customType) {
|
|
157
|
+
return p.customType.convertToDatabaseValue(keys[i], this.platform, {
|
|
158
|
+
key: p.name,
|
|
159
|
+
mode: 'hydration',
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
return keys[i];
|
|
163
|
+
});
|
|
139
164
|
hash = Utils.getPrimaryKeyHash(keys);
|
|
140
165
|
}
|
|
141
166
|
schema ??= meta.schema ?? this.em.config.getSchema();
|
|
@@ -144,6 +169,40 @@ export class UnitOfWork {
|
|
|
144
169
|
}
|
|
145
170
|
return this.identityMap.getByHash(meta, hash);
|
|
146
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* Returns entity from the identity map by an alternate key (non-PK property).
|
|
174
|
+
* @param convertCustomTypes - If true, the value is in database format and will be converted to JS format for lookup.
|
|
175
|
+
* If false (default), the value is assumed to be in JS format already.
|
|
176
|
+
*/
|
|
177
|
+
getByKey(entityName, key, value, schema, convertCustomTypes) {
|
|
178
|
+
const meta = this.metadata.find(entityName).root;
|
|
179
|
+
schema ??= meta.schema ?? this.em.config.getSchema();
|
|
180
|
+
const prop = meta.properties[key];
|
|
181
|
+
// Convert from DB format to JS format if needed
|
|
182
|
+
if (convertCustomTypes && prop?.customType) {
|
|
183
|
+
value = prop.customType.convertToJSValue(value, this.platform, { mode: 'hydration' });
|
|
184
|
+
}
|
|
185
|
+
const hash = this.identityMap.getKeyHash(key, '' + value, schema);
|
|
186
|
+
return this.identityMap.getByHash(meta, hash);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Stores an entity in the identity map under an alternate key (non-PK property).
|
|
190
|
+
* Also sets the property value on the entity.
|
|
191
|
+
* @param convertCustomTypes - If true, the value is in database format and will be converted to JS format.
|
|
192
|
+
* If false (default), the value is assumed to be in JS format already.
|
|
193
|
+
*/
|
|
194
|
+
storeByKey(entity, key, value, schema, convertCustomTypes) {
|
|
195
|
+
const meta = entity.__meta.root;
|
|
196
|
+
schema ??= meta.schema ?? this.em.config.getSchema();
|
|
197
|
+
const prop = meta.properties[key];
|
|
198
|
+
// Convert from DB format to JS format if needed
|
|
199
|
+
if (convertCustomTypes && prop?.customType) {
|
|
200
|
+
value = prop.customType.convertToJSValue(value, this.platform, { mode: 'hydration' });
|
|
201
|
+
}
|
|
202
|
+
// Set the property on the entity
|
|
203
|
+
entity[key] = value;
|
|
204
|
+
this.identityMap.storeByKey(entity, key, '' + value, schema);
|
|
205
|
+
}
|
|
147
206
|
tryGetById(entityName, where, schema, strict = true) {
|
|
148
207
|
const pk = Utils.extractPK(where, this.metadata.find(entityName), strict);
|
|
149
208
|
if (!pk) {
|
|
@@ -182,13 +241,11 @@ export class UnitOfWork {
|
|
|
182
241
|
if (insideFlush.getStore()) {
|
|
183
242
|
return false;
|
|
184
243
|
}
|
|
185
|
-
if (this.queuedActions.has(meta.
|
|
244
|
+
if (this.queuedActions.has(meta.class) || this.queuedActions.has(meta.root.class)) {
|
|
186
245
|
return true;
|
|
187
246
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
return true;
|
|
191
|
-
}
|
|
247
|
+
if (meta.discriminatorMap && Object.values(meta.discriminatorMap).some(v => this.queuedActions.has(v))) {
|
|
248
|
+
return true;
|
|
192
249
|
}
|
|
193
250
|
return false;
|
|
194
251
|
}
|
|
@@ -209,7 +266,6 @@ export class UnitOfWork {
|
|
|
209
266
|
this.changeSets.set(entity, cs);
|
|
210
267
|
this.persistStack.delete(entity);
|
|
211
268
|
wrapped.__originalEntityData = this.comparator.prepareEntity(entity);
|
|
212
|
-
wrapped.__touched = false;
|
|
213
269
|
}
|
|
214
270
|
recomputeSingleChangeSet(entity) {
|
|
215
271
|
const changeSet = this.changeSets.get(entity);
|
|
@@ -220,7 +276,6 @@ export class UnitOfWork {
|
|
|
220
276
|
if (cs && !this.checkUniqueProps(cs)) {
|
|
221
277
|
Object.assign(changeSet.payload, cs.payload);
|
|
222
278
|
helper(entity).__originalEntityData = this.comparator.prepareEntity(entity);
|
|
223
|
-
helper(entity).__touched = false;
|
|
224
279
|
}
|
|
225
280
|
}
|
|
226
281
|
persist(entity, visited, options = {}) {
|
|
@@ -230,7 +285,7 @@ export class UnitOfWork {
|
|
|
230
285
|
}
|
|
231
286
|
const wrapped = helper(entity);
|
|
232
287
|
this.persistStack.add(entity);
|
|
233
|
-
this.queuedActions.add(wrapped.__meta.
|
|
288
|
+
this.queuedActions.add(wrapped.__meta.class);
|
|
234
289
|
this.removeStack.delete(entity);
|
|
235
290
|
if (!wrapped.__managed && wrapped.hasPrimaryKey()) {
|
|
236
291
|
this.identityMap.store(entity);
|
|
@@ -243,7 +298,7 @@ export class UnitOfWork {
|
|
|
243
298
|
// allow removing not managed entities if they are not part of the persist stack
|
|
244
299
|
if (helper(entity).__managed || !this.persistStack.has(entity)) {
|
|
245
300
|
this.removeStack.add(entity);
|
|
246
|
-
this.queuedActions.add(helper(entity).__meta.
|
|
301
|
+
this.queuedActions.add(helper(entity).__meta.class);
|
|
247
302
|
}
|
|
248
303
|
else {
|
|
249
304
|
this.persistStack.delete(entity);
|
|
@@ -303,17 +358,21 @@ export class UnitOfWork {
|
|
|
303
358
|
cs.entity.__helper.__processing = true;
|
|
304
359
|
}
|
|
305
360
|
await this.eventManager.dispatchEvent(EventType.onFlush, { em: this.em, uow: this });
|
|
361
|
+
this.filterCollectionUpdates();
|
|
306
362
|
// nothing to do, do not start transaction
|
|
307
363
|
if (this.changeSets.size === 0 && this.collectionUpdates.size === 0 && this.extraUpdates.size === 0) {
|
|
308
|
-
|
|
364
|
+
await this.eventManager.dispatchEvent(EventType.afterFlush, { em: this.em, uow: this });
|
|
365
|
+
return;
|
|
309
366
|
}
|
|
310
367
|
const groups = this.getChangeSetGroups();
|
|
311
368
|
const platform = this.em.getPlatform();
|
|
312
369
|
const runInTransaction = !this.em.isInTransaction() && platform.supportsTransactions() && this.em.config.get('implicitTransactions');
|
|
313
370
|
if (runInTransaction) {
|
|
371
|
+
const loggerContext = Utils.merge({ id: this.em._id }, this.em.getLoggerContext({ disableContextResolution: true }));
|
|
314
372
|
await this.em.getConnection('write').transactional(trx => this.persistToDatabase(groups, trx), {
|
|
315
373
|
ctx: oldTx,
|
|
316
374
|
eventBroadcaster: new TransactionEventBroadcaster(this.em),
|
|
375
|
+
loggerContext,
|
|
317
376
|
});
|
|
318
377
|
}
|
|
319
378
|
else {
|
|
@@ -330,10 +389,10 @@ export class UnitOfWork {
|
|
|
330
389
|
}
|
|
331
390
|
}
|
|
332
391
|
async lock(entity, options) {
|
|
333
|
-
if (!this.getById(entity.constructor
|
|
392
|
+
if (!this.getById(entity.constructor, helper(entity).__primaryKeys, helper(entity).__schema)) {
|
|
334
393
|
throw ValidationError.entityNotManaged(entity);
|
|
335
394
|
}
|
|
336
|
-
const meta = this.metadata.find(entity.constructor
|
|
395
|
+
const meta = this.metadata.find(entity.constructor);
|
|
337
396
|
if (options.lockMode === LockMode.OPTIMISTIC) {
|
|
338
397
|
await this.lockOptimistic(entity, meta, options.lockVersion);
|
|
339
398
|
}
|
|
@@ -357,7 +416,7 @@ export class UnitOfWork {
|
|
|
357
416
|
if (Utils.isCollection(rel)) {
|
|
358
417
|
rel.removeWithoutPropagation(entity);
|
|
359
418
|
}
|
|
360
|
-
else if (rel && (prop.mapToPk ? helper(this.em.getReference(prop.
|
|
419
|
+
else if (rel && (prop.mapToPk ? helper(this.em.getReference(prop.targetMeta.class, rel)).getSerializedPrimaryKey() === serializedPK : rel === entity)) {
|
|
361
420
|
if (prop.formula) {
|
|
362
421
|
delete referrer[prop.name];
|
|
363
422
|
}
|
|
@@ -369,7 +428,6 @@ export class UnitOfWork {
|
|
|
369
428
|
}
|
|
370
429
|
delete wrapped.__identifier;
|
|
371
430
|
delete wrapped.__originalEntityData;
|
|
372
|
-
wrapped.__touched = false;
|
|
373
431
|
wrapped.__managed = false;
|
|
374
432
|
}
|
|
375
433
|
computeChangeSets() {
|
|
@@ -379,14 +437,14 @@ export class UnitOfWork {
|
|
|
379
437
|
this.cascade(entity, Cascade.REMOVE, visited);
|
|
380
438
|
}
|
|
381
439
|
visited.clear();
|
|
382
|
-
for (const entity of this.persistStack) {
|
|
383
|
-
this.cascade(entity, Cascade.PERSIST, visited, { checkRemoveStack: true });
|
|
384
|
-
}
|
|
385
440
|
for (const entity of this.identityMap) {
|
|
386
441
|
if (!this.removeStack.has(entity) && !this.persistStack.has(entity) && !this.orphanRemoveStack.has(entity)) {
|
|
387
442
|
this.cascade(entity, Cascade.PERSIST, visited, { checkRemoveStack: true });
|
|
388
443
|
}
|
|
389
444
|
}
|
|
445
|
+
for (const entity of this.persistStack) {
|
|
446
|
+
this.cascade(entity, Cascade.PERSIST, visited, { checkRemoveStack: true });
|
|
447
|
+
}
|
|
390
448
|
visited.clear();
|
|
391
449
|
for (const entity of this.persistStack) {
|
|
392
450
|
this.findNewEntities(entity, visited);
|
|
@@ -400,24 +458,24 @@ export class UnitOfWork {
|
|
|
400
458
|
const inserts = {};
|
|
401
459
|
for (const cs of this.changeSets.values()) {
|
|
402
460
|
if (cs.type === ChangeSetType.CREATE) {
|
|
403
|
-
inserts[cs.meta.
|
|
404
|
-
inserts[cs.meta.
|
|
461
|
+
inserts[cs.meta.uniqueName] ??= [];
|
|
462
|
+
inserts[cs.meta.uniqueName].push(cs);
|
|
405
463
|
}
|
|
406
464
|
}
|
|
407
465
|
for (const cs of this.changeSets.values()) {
|
|
408
466
|
if (cs.type === ChangeSetType.UPDATE) {
|
|
409
|
-
this.findEarlyUpdates(cs, inserts[cs.meta.
|
|
467
|
+
this.findEarlyUpdates(cs, inserts[cs.meta.uniqueName]);
|
|
410
468
|
}
|
|
411
469
|
}
|
|
412
470
|
for (const entity of this.removeStack) {
|
|
413
471
|
const wrapped = helper(entity);
|
|
414
|
-
/* v8 ignore next
|
|
472
|
+
/* v8 ignore next */
|
|
415
473
|
if (wrapped.__processing) {
|
|
416
474
|
continue;
|
|
417
475
|
}
|
|
418
476
|
const deletePkHash = [wrapped.getSerializedPrimaryKey(), ...this.expandUniqueProps(entity)];
|
|
419
477
|
let type = ChangeSetType.DELETE;
|
|
420
|
-
for (const cs of inserts[wrapped.__meta.
|
|
478
|
+
for (const cs of inserts[wrapped.__meta.uniqueName] ?? []) {
|
|
421
479
|
if (deletePkHash.some(hash => hash === cs.getSerializedPrimaryKey() || this.expandUniqueProps(cs.entity).find(child => hash === child))) {
|
|
422
480
|
type = ChangeSetType.DELETE_EARLY;
|
|
423
481
|
}
|
|
@@ -436,7 +494,7 @@ export class UnitOfWork {
|
|
|
436
494
|
}
|
|
437
495
|
for (const cs of this.changeSets.values()) {
|
|
438
496
|
for (const prop of props) {
|
|
439
|
-
if (prop.name in cs.payload && cs.
|
|
497
|
+
if (prop.name in cs.payload && cs.rootMeta === changeSet.rootMeta && cs.type === changeSet.type) {
|
|
440
498
|
conflicts = true;
|
|
441
499
|
if (changeSet.payload[prop.name] == null) {
|
|
442
500
|
type = ChangeSetType.UPDATE_EARLY;
|
|
@@ -455,9 +513,10 @@ export class UnitOfWork {
|
|
|
455
513
|
}
|
|
456
514
|
scheduleOrphanRemoval(entity, visited) {
|
|
457
515
|
if (entity) {
|
|
458
|
-
helper(entity)
|
|
516
|
+
const wrapped = helper(entity);
|
|
517
|
+
wrapped.__em = this.em;
|
|
459
518
|
this.orphanRemoveStack.add(entity);
|
|
460
|
-
this.queuedActions.add(
|
|
519
|
+
this.queuedActions.add(wrapped.__meta.class);
|
|
461
520
|
this.cascade(entity, Cascade.SCHEDULE_ORPHAN_REMOVAL, visited);
|
|
462
521
|
}
|
|
463
522
|
}
|
|
@@ -606,7 +665,7 @@ export class UnitOfWork {
|
|
|
606
665
|
const copy = this.comparator.prepareEntity(changeSet.entity);
|
|
607
666
|
await this.eventManager.dispatchEvent(type, { entity: changeSet.entity, meta, em: this.em, changeSet });
|
|
608
667
|
const current = this.comparator.prepareEntity(changeSet.entity);
|
|
609
|
-
const diff = this.comparator.diffEntities(changeSet.
|
|
668
|
+
const diff = this.comparator.diffEntities(changeSet.meta.class, copy, current);
|
|
610
669
|
Object.assign(changeSet.payload, diff);
|
|
611
670
|
const wrapped = helper(changeSet.entity);
|
|
612
671
|
if (wrapped.__identifier) {
|
|
@@ -701,7 +760,7 @@ export class UnitOfWork {
|
|
|
701
760
|
if (!meta.versionProperty) {
|
|
702
761
|
throw OptimisticLockError.notVersioned(meta);
|
|
703
762
|
}
|
|
704
|
-
if (
|
|
763
|
+
if (typeof version === 'undefined') {
|
|
705
764
|
return;
|
|
706
765
|
}
|
|
707
766
|
const wrapped = helper(entity);
|
|
@@ -715,26 +774,26 @@ export class UnitOfWork {
|
|
|
715
774
|
}
|
|
716
775
|
fixMissingReference(entity, prop) {
|
|
717
776
|
const reference = entity[prop.name];
|
|
718
|
-
const
|
|
719
|
-
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) &&
|
|
720
|
-
if (!Utils.isEntity(
|
|
721
|
-
entity[prop.name] = this.em.getReference(prop.
|
|
777
|
+
const target = Reference.unwrapReference(reference);
|
|
778
|
+
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && target && !prop.mapToPk) {
|
|
779
|
+
if (!Utils.isEntity(target)) {
|
|
780
|
+
entity[prop.name] = this.em.getReference(prop.targetMeta.class, target, { wrapped: !!prop.ref });
|
|
722
781
|
}
|
|
723
|
-
else if (!helper(
|
|
724
|
-
const pk = helper(
|
|
725
|
-
entity[prop.name] = this.em.getReference(prop.
|
|
782
|
+
else if (!helper(target).__initialized && !helper(target).__em) {
|
|
783
|
+
const pk = helper(target).getPrimaryKey();
|
|
784
|
+
entity[prop.name] = this.em.getReference(prop.targetMeta.class, pk, { wrapped: !!prop.ref });
|
|
726
785
|
}
|
|
727
786
|
}
|
|
728
|
-
// perf: set the `Collection._property` to skip the getter, as it can be slow when there
|
|
729
|
-
if (Utils.isCollection(
|
|
730
|
-
|
|
787
|
+
// perf: set the `Collection._property` to skip the getter, as it can be slow when there are a lot of relations
|
|
788
|
+
if (Utils.isCollection(target)) {
|
|
789
|
+
target.property = prop;
|
|
731
790
|
}
|
|
732
791
|
const isCollection = [ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind);
|
|
733
|
-
if (isCollection && Array.isArray(
|
|
792
|
+
if (isCollection && Array.isArray(target)) {
|
|
734
793
|
const collection = new Collection(entity);
|
|
735
794
|
collection.property = prop;
|
|
736
795
|
entity[prop.name] = collection;
|
|
737
|
-
collection.set(
|
|
796
|
+
collection.set(target);
|
|
738
797
|
}
|
|
739
798
|
}
|
|
740
799
|
async persistToDatabase(groups, ctx) {
|
|
@@ -744,30 +803,30 @@ export class UnitOfWork {
|
|
|
744
803
|
const commitOrder = this.getCommitOrder();
|
|
745
804
|
const commitOrderReversed = [...commitOrder].reverse();
|
|
746
805
|
// early delete - when we recreate entity in the same UoW, we need to issue those delete queries before inserts
|
|
747
|
-
for (const
|
|
748
|
-
await this.commitDeleteChangeSets(groups[ChangeSetType.DELETE_EARLY].get(
|
|
806
|
+
for (const meta of commitOrderReversed) {
|
|
807
|
+
await this.commitDeleteChangeSets(groups[ChangeSetType.DELETE_EARLY].get(meta) ?? [], ctx);
|
|
749
808
|
}
|
|
750
809
|
// early update - when we recreate entity in the same UoW, we need to issue those delete queries before inserts
|
|
751
|
-
for (const
|
|
752
|
-
await this.commitUpdateChangeSets(groups[ChangeSetType.UPDATE_EARLY].get(
|
|
810
|
+
for (const meta of commitOrder) {
|
|
811
|
+
await this.commitUpdateChangeSets(groups[ChangeSetType.UPDATE_EARLY].get(meta) ?? [], ctx);
|
|
753
812
|
}
|
|
754
813
|
// extra updates
|
|
755
814
|
await this.commitExtraUpdates(ChangeSetType.UPDATE_EARLY, ctx);
|
|
756
815
|
// create
|
|
757
|
-
for (const
|
|
758
|
-
await this.commitCreateChangeSets(groups[ChangeSetType.CREATE].get(
|
|
816
|
+
for (const meta of commitOrder) {
|
|
817
|
+
await this.commitCreateChangeSets(groups[ChangeSetType.CREATE].get(meta) ?? [], ctx);
|
|
759
818
|
}
|
|
760
819
|
// update
|
|
761
|
-
for (const
|
|
762
|
-
await this.commitUpdateChangeSets(groups[ChangeSetType.UPDATE].get(
|
|
820
|
+
for (const meta of commitOrder) {
|
|
821
|
+
await this.commitUpdateChangeSets(groups[ChangeSetType.UPDATE].get(meta) ?? [], ctx);
|
|
763
822
|
}
|
|
764
823
|
// extra updates
|
|
765
824
|
await this.commitExtraUpdates(ChangeSetType.UPDATE, ctx);
|
|
766
825
|
// collection updates
|
|
767
826
|
await this.commitCollectionUpdates(ctx);
|
|
768
827
|
// delete - entity deletions need to be in reverse commit order
|
|
769
|
-
for (const
|
|
770
|
-
await this.commitDeleteChangeSets(groups[ChangeSetType.DELETE].get(
|
|
828
|
+
for (const meta of commitOrderReversed) {
|
|
829
|
+
await this.commitDeleteChangeSets(groups[ChangeSetType.DELETE].get(meta) ?? [], ctx);
|
|
771
830
|
}
|
|
772
831
|
// take snapshots of all persisted collections
|
|
773
832
|
const visited = new Set();
|
|
@@ -803,7 +862,7 @@ export class UnitOfWork {
|
|
|
803
862
|
if (Utils.isCollection(ref)) {
|
|
804
863
|
ref.getItems(false).some(item => {
|
|
805
864
|
const cs = this.changeSets.get(Reference.unwrapReference(item));
|
|
806
|
-
const isScheduledForInsert = cs
|
|
865
|
+
const isScheduledForInsert = cs?.type === ChangeSetType.CREATE && !cs.persisted;
|
|
807
866
|
if (isScheduledForInsert) {
|
|
808
867
|
this.scheduleExtraUpdate(changeSet, [prop]);
|
|
809
868
|
return true;
|
|
@@ -812,7 +871,7 @@ export class UnitOfWork {
|
|
|
812
871
|
});
|
|
813
872
|
}
|
|
814
873
|
const cs = this.changeSets.get(Reference.unwrapReference(ref));
|
|
815
|
-
const isScheduledForInsert = cs
|
|
874
|
+
const isScheduledForInsert = cs?.type === ChangeSetType.CREATE && !cs.persisted;
|
|
816
875
|
if (isScheduledForInsert) {
|
|
817
876
|
this.scheduleExtraUpdate(changeSet, [prop]);
|
|
818
877
|
}
|
|
@@ -841,9 +900,16 @@ export class UnitOfWork {
|
|
|
841
900
|
}
|
|
842
901
|
await this.changeSetPersister.executeUpdates(changeSets, batched, { ctx });
|
|
843
902
|
for (const changeSet of changeSets) {
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
903
|
+
const wrapped = helper(changeSet.entity);
|
|
904
|
+
wrapped.__originalEntityData = this.comparator.prepareEntity(changeSet.entity);
|
|
905
|
+
if (!wrapped.__initialized) {
|
|
906
|
+
for (const prop of changeSet.meta.relations) {
|
|
907
|
+
if ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop.kind) && changeSet.entity[prop.name] == null) {
|
|
908
|
+
changeSet.entity[prop.name] = Collection.create(changeSet.entity, prop.name, undefined, wrapped.isInitialized());
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
wrapped.__initialized = true;
|
|
912
|
+
}
|
|
847
913
|
await this.runHooks(EventType.afterUpdate, changeSet);
|
|
848
914
|
}
|
|
849
915
|
}
|
|
@@ -886,23 +952,34 @@ export class UnitOfWork {
|
|
|
886
952
|
}
|
|
887
953
|
}
|
|
888
954
|
async commitCollectionUpdates(ctx) {
|
|
889
|
-
|
|
955
|
+
this.filterCollectionUpdates();
|
|
956
|
+
const loggerContext = Utils.merge({ id: this.em._id }, this.em.getLoggerContext({ disableContextResolution: true }));
|
|
957
|
+
await this.em.getDriver().syncCollections(this.collectionUpdates, {
|
|
958
|
+
ctx,
|
|
959
|
+
schema: this.em.schema,
|
|
960
|
+
loggerContext,
|
|
961
|
+
});
|
|
890
962
|
for (const coll of this.collectionUpdates) {
|
|
963
|
+
coll.takeSnapshot();
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
filterCollectionUpdates() {
|
|
967
|
+
for (const coll of this.collectionUpdates) {
|
|
968
|
+
let skip = true;
|
|
891
969
|
if (coll.property.owner || coll.getItems(false).filter(item => !item.__helper.__initialized).length > 0) {
|
|
892
970
|
if (this.platform.usesPivotTable()) {
|
|
893
|
-
|
|
971
|
+
skip = false;
|
|
894
972
|
}
|
|
895
973
|
}
|
|
896
974
|
else if (coll.property.kind === ReferenceKind.ONE_TO_MANY && coll.getSnapshot() === undefined) {
|
|
897
|
-
|
|
975
|
+
skip = false;
|
|
898
976
|
}
|
|
899
977
|
else if (coll.property.kind === ReferenceKind.MANY_TO_MANY && !coll.property.owner) {
|
|
900
|
-
|
|
978
|
+
skip = false;
|
|
979
|
+
}
|
|
980
|
+
if (skip) {
|
|
981
|
+
this.collectionUpdates.delete(coll);
|
|
901
982
|
}
|
|
902
|
-
}
|
|
903
|
-
await this.em.getDriver().syncCollections(collectionUpdates, { ctx, schema: this.em.schema });
|
|
904
|
-
for (const coll of this.collectionUpdates) {
|
|
905
|
-
coll.takeSnapshot();
|
|
906
983
|
}
|
|
907
984
|
}
|
|
908
985
|
/**
|
|
@@ -918,10 +995,10 @@ export class UnitOfWork {
|
|
|
918
995
|
};
|
|
919
996
|
for (const cs of this.changeSets.values()) {
|
|
920
997
|
const group = groups[cs.type];
|
|
921
|
-
const classGroup = group.get(cs.
|
|
998
|
+
const classGroup = group.get(cs.rootMeta) ?? [];
|
|
922
999
|
classGroup.push(cs);
|
|
923
|
-
if (!group.has(cs.
|
|
924
|
-
group.set(cs.
|
|
1000
|
+
if (!group.has(cs.rootMeta)) {
|
|
1001
|
+
group.set(cs.rootMeta, classGroup);
|
|
925
1002
|
}
|
|
926
1003
|
}
|
|
927
1004
|
return groups;
|
|
@@ -929,14 +1006,14 @@ export class UnitOfWork {
|
|
|
929
1006
|
getCommitOrder() {
|
|
930
1007
|
const calc = new CommitOrderCalculator();
|
|
931
1008
|
const set = new Set();
|
|
932
|
-
this.changeSets.forEach(cs => set.add(cs.
|
|
933
|
-
set.forEach(
|
|
934
|
-
for (const
|
|
935
|
-
for (const prop of
|
|
936
|
-
calc.discoverProperty(prop,
|
|
1009
|
+
this.changeSets.forEach(cs => set.add(cs.rootMeta));
|
|
1010
|
+
set.forEach(meta => calc.addNode(meta._id));
|
|
1011
|
+
for (const meta of set) {
|
|
1012
|
+
for (const prop of meta.relations) {
|
|
1013
|
+
calc.discoverProperty(prop, meta._id);
|
|
937
1014
|
}
|
|
938
1015
|
}
|
|
939
|
-
return calc.sort();
|
|
1016
|
+
return calc.sort().map(id => this.metadata.getById(id));
|
|
940
1017
|
}
|
|
941
1018
|
resetTransaction(oldTx) {
|
|
942
1019
|
if (oldTx) {
|
|
@@ -10,18 +10,18 @@ export declare abstract class AbstractSchemaGenerator<D extends IDatabaseDriver>
|
|
|
10
10
|
protected readonly platform: ReturnType<D['getPlatform']>;
|
|
11
11
|
protected readonly connection: ReturnType<D['getConnection']>;
|
|
12
12
|
constructor(em: D | D[typeof EntityManagerType]);
|
|
13
|
-
|
|
13
|
+
create(options?: CreateSchemaOptions): Promise<void>;
|
|
14
14
|
/**
|
|
15
15
|
* Returns true if the database was created.
|
|
16
16
|
*/
|
|
17
17
|
ensureDatabase(options?: EnsureDatabaseOptions): Promise<boolean>;
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
refresh(options?: RefreshDatabaseOptions): Promise<void>;
|
|
19
|
+
clear(options?: ClearDatabaseOptions): Promise<void>;
|
|
20
20
|
protected clearIdentityMap(): void;
|
|
21
21
|
getCreateSchemaSQL(options?: CreateSchemaOptions): Promise<string>;
|
|
22
|
-
|
|
22
|
+
drop(options?: DropSchemaOptions): Promise<void>;
|
|
23
23
|
getDropSchemaSQL(options?: Omit<DropSchemaOptions, 'dropDb'>): Promise<string>;
|
|
24
|
-
|
|
24
|
+
update(options?: UpdateSchemaOptions): Promise<void>;
|
|
25
25
|
getUpdateSchemaSQL(options?: UpdateSchemaOptions): Promise<string>;
|
|
26
26
|
getUpdateSchemaMigrationSQL(options?: UpdateSchemaOptions): Promise<{
|
|
27
27
|
up: string;
|
|
@@ -15,7 +15,7 @@ export class AbstractSchemaGenerator {
|
|
|
15
15
|
this.platform = this.driver.getPlatform();
|
|
16
16
|
this.connection = this.driver.getConnection();
|
|
17
17
|
}
|
|
18
|
-
async
|
|
18
|
+
async create(options) {
|
|
19
19
|
this.notImplemented();
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
@@ -24,7 +24,7 @@ export class AbstractSchemaGenerator {
|
|
|
24
24
|
async ensureDatabase(options) {
|
|
25
25
|
this.notImplemented();
|
|
26
26
|
}
|
|
27
|
-
async
|
|
27
|
+
async refresh(options) {
|
|
28
28
|
if (options?.dropDb) {
|
|
29
29
|
const name = this.config.get('dbName');
|
|
30
30
|
await this.dropDatabase(name);
|
|
@@ -32,20 +32,22 @@ export class AbstractSchemaGenerator {
|
|
|
32
32
|
}
|
|
33
33
|
else {
|
|
34
34
|
await this.ensureDatabase();
|
|
35
|
-
await this.
|
|
35
|
+
await this.drop(options);
|
|
36
36
|
}
|
|
37
37
|
if (options?.createSchema !== false) {
|
|
38
|
-
await this.
|
|
38
|
+
await this.create(options);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
-
async
|
|
41
|
+
async clear(options) {
|
|
42
42
|
for (const meta of this.getOrderedMetadata(options?.schema).reverse()) {
|
|
43
|
-
await this.driver.nativeDelete(meta.
|
|
43
|
+
await this.driver.nativeDelete(meta.class, {}, options);
|
|
44
|
+
}
|
|
45
|
+
if (options?.clearIdentityMap ?? true) {
|
|
46
|
+
this.clearIdentityMap();
|
|
44
47
|
}
|
|
45
|
-
this.clearIdentityMap();
|
|
46
48
|
}
|
|
47
49
|
clearIdentityMap() {
|
|
48
|
-
/* v8 ignore next
|
|
50
|
+
/* v8 ignore next */
|
|
49
51
|
if (!this.em) {
|
|
50
52
|
return;
|
|
51
53
|
}
|
|
@@ -57,13 +59,13 @@ export class AbstractSchemaGenerator {
|
|
|
57
59
|
async getCreateSchemaSQL(options) {
|
|
58
60
|
this.notImplemented();
|
|
59
61
|
}
|
|
60
|
-
async
|
|
62
|
+
async drop(options) {
|
|
61
63
|
this.notImplemented();
|
|
62
64
|
}
|
|
63
65
|
async getDropSchemaSQL(options) {
|
|
64
66
|
this.notImplemented();
|
|
65
67
|
}
|
|
66
|
-
async
|
|
68
|
+
async update(options) {
|
|
67
69
|
this.notImplemented();
|
|
68
70
|
}
|
|
69
71
|
async getUpdateSchemaSQL(options) {
|
|
@@ -88,21 +90,21 @@ export class AbstractSchemaGenerator {
|
|
|
88
90
|
this.notImplemented();
|
|
89
91
|
}
|
|
90
92
|
getOrderedMetadata(schema) {
|
|
91
|
-
const metadata =
|
|
92
|
-
const isRootEntity = meta.root.
|
|
93
|
+
const metadata = [...this.metadata.getAll().values()].filter(meta => {
|
|
94
|
+
const isRootEntity = meta.root.class === meta.class;
|
|
93
95
|
return isRootEntity && !meta.embeddable && !meta.virtual;
|
|
94
96
|
});
|
|
95
97
|
const calc = new CommitOrderCalculator();
|
|
96
|
-
metadata.forEach(meta => calc.addNode(meta.root.
|
|
98
|
+
metadata.forEach(meta => calc.addNode(meta.root._id));
|
|
97
99
|
let meta = metadata.pop();
|
|
98
100
|
while (meta) {
|
|
99
|
-
for (const prop of meta.
|
|
100
|
-
calc.discoverProperty(prop, meta.root.
|
|
101
|
+
for (const prop of meta.relations) {
|
|
102
|
+
calc.discoverProperty(prop, meta.root._id);
|
|
101
103
|
}
|
|
102
104
|
meta = metadata.pop();
|
|
103
105
|
}
|
|
104
106
|
return calc.sort()
|
|
105
|
-
.map(cls => this.metadata.
|
|
107
|
+
.map(cls => this.metadata.getById(cls))
|
|
106
108
|
.filter(meta => {
|
|
107
109
|
const targetSchema = meta.schema ?? this.config.get('schema', this.platform.getDefaultSchemaName());
|
|
108
110
|
return schema ? [schema, '*'].includes(targetSchema) : meta.schema !== '*';
|