@mikro-orm/core 7.0.0-dev.2 → 7.0.0-dev.200
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 +111 -61
- package/EntityManager.js +346 -300
- 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 +47 -17
- package/entity/BaseEntity.d.ts +2 -2
- package/entity/BaseEntity.js +0 -3
- package/entity/Collection.d.ts +95 -31
- package/entity/Collection.js +444 -102
- package/entity/EntityAssigner.d.ts +1 -1
- package/entity/EntityAssigner.js +26 -18
- package/entity/EntityFactory.d.ts +13 -1
- package/entity/EntityFactory.js +88 -54
- package/entity/EntityHelper.d.ts +2 -2
- package/entity/EntityHelper.js +38 -15
- package/entity/EntityLoader.d.ts +8 -7
- package/entity/EntityLoader.js +134 -80
- package/entity/EntityRepository.d.ts +24 -4
- package/entity/EntityRepository.js +8 -2
- package/entity/Reference.d.ts +9 -12
- package/entity/Reference.js +34 -9
- package/entity/WrappedEntity.d.ts +2 -7
- package/entity/WrappedEntity.js +3 -8
- package/entity/defineEntity.d.ts +585 -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 +22 -6
- 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/events/EventSubscriber.d.ts +3 -1
- package/hydration/Hydrator.js +1 -2
- package/hydration/ObjectHydrator.d.ts +4 -4
- package/hydration/ObjectHydrator.js +53 -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 +26 -26
- package/metadata/EntitySchema.js +82 -51
- package/metadata/MetadataDiscovery.d.ts +7 -10
- package/metadata/MetadataDiscovery.js +408 -335
- 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 +100 -42
- 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 +19 -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 +9 -6
- package/types/BigIntType.js +4 -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 +300 -140
- package/typings.js +62 -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 +77 -35
- 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 +199 -106
- package/utils/AbstractSchemaGenerator.d.ts +5 -5
- package/utils/AbstractSchemaGenerator.js +22 -17
- package/utils/AsyncContext.d.ts +6 -0
- package/utils/AsyncContext.js +42 -0
- package/utils/Configuration.d.ts +779 -207
- package/utils/Configuration.js +146 -190
- package/utils/ConfigurationLoader.d.ts +1 -54
- package/utils/ConfigurationLoader.js +1 -352
- package/utils/Cursor.d.ts +3 -6
- package/utils/Cursor.js +27 -11
- package/utils/DataloaderUtils.d.ts +15 -5
- package/utils/DataloaderUtils.js +65 -17
- package/utils/EntityComparator.d.ts +13 -9
- package/utils/EntityComparator.js +164 -89
- package/utils/QueryHelper.d.ts +14 -6
- package/utils/QueryHelper.js +88 -26
- package/utils/RawQueryFragment.d.ts +48 -25
- package/utils/RawQueryFragment.js +67 -66
- 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 -120
- package/utils/Utils.js +104 -375
- 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 -29
- package/decorators/Embeddable.d.ts +0 -8
- package/decorators/Embeddable.js +0 -11
- package/decorators/Embedded.d.ts +0 -18
- package/decorators/Embedded.js +0 -18
- package/decorators/Entity.d.ts +0 -18
- package/decorators/Entity.js +0 -13
- 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 -5
- package/decorators/Formula.js +0 -15
- package/decorators/Indexed.d.ts +0 -17
- 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 -30
- 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 -24
- package/decorators/OneToOne.js +0 -7
- package/decorators/PrimaryKey.d.ts +0 -9
- 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 -395
- package/entity/EntityValidator.d.ts +0 -19
- package/entity/EntityValidator.js +0 -150
- 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
package/typings.js
CHANGED
|
@@ -3,6 +3,7 @@ import { Reference } from './entity/Reference.js';
|
|
|
3
3
|
import { EntityHelper } from './entity/EntityHelper.js';
|
|
4
4
|
import { Utils } from './utils/Utils.js';
|
|
5
5
|
import { EntityComparator } from './utils/EntityComparator.js';
|
|
6
|
+
import { BaseEntity } from './entity/BaseEntity.js';
|
|
6
7
|
export const EntityRepositoryType = Symbol('EntityRepositoryType');
|
|
7
8
|
export const PrimaryKeyProp = Symbol('PrimaryKeyProp');
|
|
8
9
|
export const OptionalProps = Symbol('OptionalProps');
|
|
@@ -25,38 +26,60 @@ export class EntityMetadata {
|
|
|
25
26
|
this.referencingProperties = [];
|
|
26
27
|
this.concurrencyCheckKeys = new Set();
|
|
27
28
|
Object.assign(this, meta);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
const name = meta.className ?? meta.name;
|
|
30
|
+
if (!this.class && name) {
|
|
31
|
+
const Class = this.extends === BaseEntity
|
|
32
|
+
? ({ [name]: class extends BaseEntity {
|
|
33
|
+
} })[name]
|
|
34
|
+
: ({ [name]: class {
|
|
35
|
+
} })[name];
|
|
36
|
+
this.class = Class;
|
|
32
37
|
}
|
|
38
|
+
}
|
|
39
|
+
addProperty(prop) {
|
|
33
40
|
this.properties[prop.name] = prop;
|
|
34
41
|
this.propertyOrder.set(prop.name, this.props.length);
|
|
35
|
-
|
|
36
|
-
if (sync) {
|
|
37
|
-
this.sync();
|
|
38
|
-
}
|
|
42
|
+
this.sync();
|
|
39
43
|
}
|
|
40
44
|
removeProperty(name, sync = true) {
|
|
41
45
|
delete this.properties[name];
|
|
42
46
|
this.propertyOrder.delete(name);
|
|
43
|
-
/* v8 ignore next 3 */
|
|
44
47
|
if (sync) {
|
|
45
48
|
this.sync();
|
|
46
49
|
}
|
|
47
50
|
}
|
|
48
|
-
getPrimaryProps() {
|
|
49
|
-
|
|
51
|
+
getPrimaryProps(flatten = false) {
|
|
52
|
+
const pks = this.primaryKeys.map(pk => this.properties[pk]);
|
|
53
|
+
if (flatten) {
|
|
54
|
+
return pks.flatMap(pk => {
|
|
55
|
+
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(pk.kind)) {
|
|
56
|
+
return pk.targetMeta.getPrimaryProps(true);
|
|
57
|
+
}
|
|
58
|
+
return [pk];
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return pks;
|
|
50
62
|
}
|
|
51
63
|
getPrimaryProp() {
|
|
52
64
|
return this.properties[this.primaryKeys[0]];
|
|
53
65
|
}
|
|
66
|
+
createColumnMappingObject() {
|
|
67
|
+
return Object.values(this.properties).reduce((o, prop) => {
|
|
68
|
+
if (prop.fieldNames) {
|
|
69
|
+
o[prop.name] = prop.fieldNames[0];
|
|
70
|
+
}
|
|
71
|
+
return o;
|
|
72
|
+
}, {});
|
|
73
|
+
}
|
|
54
74
|
get tableName() {
|
|
55
75
|
return this.collection;
|
|
56
76
|
}
|
|
57
77
|
set tableName(name) {
|
|
58
78
|
this.collection = name;
|
|
59
79
|
}
|
|
80
|
+
get uniqueName() {
|
|
81
|
+
return this.tableName + '_' + this._id;
|
|
82
|
+
}
|
|
60
83
|
sync(initIndexes = false, config) {
|
|
61
84
|
this.root ??= this;
|
|
62
85
|
const props = Object.values(this.properties).sort((a, b) => this.propertyOrder.get(a.name) - this.propertyOrder.get(b.name));
|
|
@@ -66,23 +89,32 @@ export class EntityMetadata {
|
|
|
66
89
|
this.uniqueProps = this.props.filter(prop => prop.unique);
|
|
67
90
|
this.getterProps = this.props.filter(prop => prop.getter);
|
|
68
91
|
this.comparableProps = this.props.filter(prop => EntityComparator.isComparable(prop, this));
|
|
92
|
+
this.validateProps = this.props.filter(prop => {
|
|
93
|
+
if (prop.inherited || (prop.persist === false && prop.userDefined !== false)) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
return prop.kind === ReferenceKind.SCALAR && ['string', 'number', 'boolean', 'Date'].includes(prop.type);
|
|
97
|
+
});
|
|
69
98
|
this.hydrateProps = this.props.filter(prop => {
|
|
70
99
|
// `prop.userDefined` is either `undefined` or `false`
|
|
71
100
|
const discriminator = this.root.discriminatorColumn === prop.name && prop.userDefined === false;
|
|
72
101
|
// even if we don't have a setter, do not ignore value from database!
|
|
73
|
-
const onlyGetter = prop.getter && !prop.setter;
|
|
102
|
+
const onlyGetter = prop.getter && !prop.setter && prop.persist === false;
|
|
74
103
|
return !prop.inherited && prop.hydrate !== false && !discriminator && !prop.embedded && !onlyGetter;
|
|
75
104
|
});
|
|
76
|
-
this.trackingProps = this.hydrateProps
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
105
|
+
this.trackingProps = this.hydrateProps.filter(prop => {
|
|
106
|
+
return !prop.getter && !prop.setter && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind);
|
|
107
|
+
});
|
|
108
|
+
this.selfReferencing = this.relations.some(prop => {
|
|
109
|
+
return this.root.uniqueName === prop.targetMeta?.root.uniqueName;
|
|
110
|
+
});
|
|
81
111
|
this.hasUniqueProps = this.uniques.length + this.uniqueProps.length > 0;
|
|
82
|
-
this
|
|
112
|
+
// If `view` is set, this is a database view entity (not a virtual entity).
|
|
113
|
+
// Virtual entities evaluate expressions at query time, view entities create actual database views.
|
|
114
|
+
this.virtual = !!this.expression && !this.view;
|
|
83
115
|
if (config) {
|
|
84
116
|
for (const prop of this.props) {
|
|
85
|
-
if (prop.enum && !prop.nativeEnumName && prop.items?.every(item =>
|
|
117
|
+
if (prop.enum && !prop.nativeEnumName && prop.items?.every(item => typeof item === 'string')) {
|
|
86
118
|
const name = config.getNamingStrategy().indexName(this.tableName, prop.fieldNames, 'check');
|
|
87
119
|
const exists = this.checks.findIndex(check => check.name === name);
|
|
88
120
|
if (exists !== -1) {
|
|
@@ -102,15 +134,14 @@ export class EntityMetadata {
|
|
|
102
134
|
for (const hook of Utils.keys(this.hooks)) {
|
|
103
135
|
this.hooks[hook] = Utils.removeDuplicates(this.hooks[hook]);
|
|
104
136
|
}
|
|
105
|
-
if (this.virtual) {
|
|
137
|
+
if (this.virtual || this.view) {
|
|
106
138
|
this.readonly = true;
|
|
107
139
|
}
|
|
108
140
|
if (initIndexes && this.name) {
|
|
109
141
|
this.props.forEach(prop => this.initIndexes(prop));
|
|
110
142
|
}
|
|
111
143
|
this.definedProperties = this.trackingProps.reduce((o, prop) => {
|
|
112
|
-
const
|
|
113
|
-
const isReference = [ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind) && (prop.inversedBy || prop.mappedBy) && !prop.mapToPk;
|
|
144
|
+
const isReference = (prop.inversedBy || prop.mappedBy) && !prop.mapToPk;
|
|
114
145
|
if (isReference) {
|
|
115
146
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
116
147
|
const meta = this;
|
|
@@ -123,13 +154,13 @@ export class EntityMetadata {
|
|
|
123
154
|
const hydrator = wrapped.hydrator;
|
|
124
155
|
const entity = Reference.unwrapReference(val ?? wrapped.__data[prop.name]);
|
|
125
156
|
const old = Reference.unwrapReference(wrapped.__data[prop.name]);
|
|
157
|
+
if (old && old !== entity && prop.kind === ReferenceKind.MANY_TO_ONE && prop.inversedBy && old[prop.inversedBy]) {
|
|
158
|
+
old[prop.inversedBy].removeWithoutPropagation(this);
|
|
159
|
+
}
|
|
126
160
|
wrapped.__data[prop.name] = Reference.wrapReference(val, prop);
|
|
127
161
|
// when propagation from inside hydration, we set the FK to the entity data immediately
|
|
128
162
|
if (val && hydrator.isRunning() && wrapped.__originalEntityData && prop.owner) {
|
|
129
|
-
wrapped.__originalEntityData[prop.name] = Utils.getPrimaryKeyValues(val, prop.targetMeta
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
wrapped.__touched = !hydrator.isRunning();
|
|
163
|
+
wrapped.__originalEntityData[prop.name] = Utils.getPrimaryKeyValues(val, prop.targetMeta, true);
|
|
133
164
|
}
|
|
134
165
|
EntityHelper.propagate(meta, entity, this, prop, Reference.unwrapReference(val), old);
|
|
135
166
|
},
|
|
@@ -137,23 +168,6 @@ export class EntityMetadata {
|
|
|
137
168
|
configurable: true,
|
|
138
169
|
};
|
|
139
170
|
}
|
|
140
|
-
if (prop.inherited || prop.primary || isCollection || prop.persist === false || prop.trackChanges === false || isReference || prop.embedded) {
|
|
141
|
-
return o;
|
|
142
|
-
}
|
|
143
|
-
o[prop.name] = {
|
|
144
|
-
get() {
|
|
145
|
-
return this.__helper.__data[prop.name];
|
|
146
|
-
},
|
|
147
|
-
set(val) {
|
|
148
|
-
if (typeof val === 'object' && !!val && '__raw' in val) {
|
|
149
|
-
val.assign();
|
|
150
|
-
}
|
|
151
|
-
this.__helper.__data[prop.name] = val;
|
|
152
|
-
this.__helper.__touched = !this.__helper.hydrator.isRunning();
|
|
153
|
-
},
|
|
154
|
-
enumerable: true,
|
|
155
|
-
configurable: true,
|
|
156
|
-
};
|
|
157
171
|
return o;
|
|
158
172
|
}, { __gettersDefined: { value: true, enumerable: false } });
|
|
159
173
|
}
|
|
@@ -175,7 +189,7 @@ export class EntityMetadata {
|
|
|
175
189
|
this.indexes.push({ properties: prop.name });
|
|
176
190
|
prop.index = false;
|
|
177
191
|
}
|
|
178
|
-
/* v8 ignore next
|
|
192
|
+
/* v8 ignore next */
|
|
179
193
|
if (owner && prop.fieldNames.length > 1 && prop.unique) {
|
|
180
194
|
this.uniques.push({ properties: prop.name });
|
|
181
195
|
prop.unique = false;
|
|
@@ -185,4 +199,8 @@ export class EntityMetadata {
|
|
|
185
199
|
clone() {
|
|
186
200
|
return this;
|
|
187
201
|
}
|
|
202
|
+
/** @ignore */
|
|
203
|
+
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
204
|
+
return `[${this.constructor.name}<${this.className}>]`;
|
|
205
|
+
}
|
|
188
206
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { inspect } from 'node:util';
|
|
2
1
|
import type { EntityData, EntityMetadata, EntityDictionary, Primary } from '../typings.js';
|
|
3
2
|
export declare class ChangeSet<T extends object> {
|
|
4
3
|
entity: T;
|
|
@@ -10,13 +9,10 @@ export declare class ChangeSet<T extends object> {
|
|
|
10
9
|
constructor(entity: T, type: ChangeSetType, payload: EntityDictionary<T>, meta: EntityMetadata<T>);
|
|
11
10
|
getPrimaryKey(object?: boolean): Primary<T> | null;
|
|
12
11
|
getSerializedPrimaryKey(): string | null;
|
|
13
|
-
/** @ignore */
|
|
14
|
-
[inspect.custom](depth?: number): string;
|
|
15
12
|
}
|
|
16
13
|
export interface ChangeSet<T> {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
collection: string;
|
|
14
|
+
meta: EntityMetadata<T>;
|
|
15
|
+
rootMeta: EntityMetadata<T>;
|
|
20
16
|
schema?: string;
|
|
21
17
|
type: ChangeSetType;
|
|
22
18
|
entity: T;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { inspect } from 'node:util';
|
|
2
1
|
import { helper } from '../entity/wrap.js';
|
|
3
2
|
import { Utils } from '../utils/Utils.js';
|
|
3
|
+
import { inspect } from '../logging/inspect.js';
|
|
4
4
|
export class ChangeSet {
|
|
5
5
|
entity;
|
|
6
6
|
type;
|
|
@@ -13,9 +13,8 @@ export class ChangeSet {
|
|
|
13
13
|
this.type = type;
|
|
14
14
|
this.payload = payload;
|
|
15
15
|
this.meta = meta;
|
|
16
|
-
this.
|
|
17
|
-
this.
|
|
18
|
-
this.collection = meta.root.collection;
|
|
16
|
+
this.meta = meta;
|
|
17
|
+
this.rootMeta = meta.root;
|
|
19
18
|
this.schema = helper(entity).__schema ?? meta.root.schema;
|
|
20
19
|
}
|
|
21
20
|
getPrimaryKey(object = false) {
|
|
@@ -46,7 +45,7 @@ export class ChangeSet {
|
|
|
46
45
|
return this.serializedPrimaryKey;
|
|
47
46
|
}
|
|
48
47
|
/** @ignore */
|
|
49
|
-
[inspect.custom](depth = 2) {
|
|
48
|
+
[Symbol.for('nodejs.util.inspect.custom')](depth = 2) {
|
|
50
49
|
const object = { ...this };
|
|
51
50
|
const hidden = ['meta', 'serializedPrimaryKey'];
|
|
52
51
|
hidden.forEach(k => delete object[k]);
|
|
@@ -2,19 +2,17 @@ import { type Configuration } from '../utils/Configuration.js';
|
|
|
2
2
|
import type { MetadataStorage } from '../metadata/MetadataStorage.js';
|
|
3
3
|
import type { AnyEntity } from '../typings.js';
|
|
4
4
|
import { ChangeSet } from './ChangeSet.js';
|
|
5
|
-
import { type EntityValidator } from '../entity/EntityValidator.js';
|
|
6
5
|
import { type Collection } from '../entity/Collection.js';
|
|
7
6
|
import type { Platform } from '../platforms/Platform.js';
|
|
8
7
|
import type { EntityManager } from '../EntityManager.js';
|
|
9
8
|
export declare class ChangeSetComputer {
|
|
10
|
-
private readonly validator;
|
|
11
9
|
private readonly collectionUpdates;
|
|
12
10
|
private readonly metadata;
|
|
13
11
|
private readonly platform;
|
|
14
12
|
private readonly config;
|
|
15
13
|
private readonly em;
|
|
16
14
|
private readonly comparator;
|
|
17
|
-
constructor(
|
|
15
|
+
constructor(collectionUpdates: Set<Collection<AnyEntity>>, metadata: MetadataStorage, platform: Platform, config: Configuration, em: EntityManager);
|
|
18
16
|
computeChangeSet<T extends object>(entity: T): ChangeSet<T> | null;
|
|
19
17
|
/**
|
|
20
18
|
* Traverses entity graph and executes `onCreate` and `onUpdate` methods, assigning the values to given properties.
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { Utils } from '../utils/Utils.js';
|
|
2
2
|
import { ChangeSet, ChangeSetType } from './ChangeSet.js';
|
|
3
3
|
import { helper } from '../entity/wrap.js';
|
|
4
|
+
import { validateEntity } from '../entity/validators.js';
|
|
4
5
|
import { ReferenceKind } from '../enums.js';
|
|
5
6
|
export class ChangeSetComputer {
|
|
6
|
-
validator;
|
|
7
7
|
collectionUpdates;
|
|
8
8
|
metadata;
|
|
9
9
|
platform;
|
|
10
10
|
config;
|
|
11
11
|
em;
|
|
12
12
|
comparator;
|
|
13
|
-
constructor(
|
|
14
|
-
this.validator = validator;
|
|
13
|
+
constructor(collectionUpdates, metadata, platform, config, em) {
|
|
15
14
|
this.collectionUpdates = collectionUpdates;
|
|
16
15
|
this.metadata = metadata;
|
|
17
16
|
this.platform = platform;
|
|
@@ -20,7 +19,7 @@ export class ChangeSetComputer {
|
|
|
20
19
|
this.comparator = this.config.getComparator(this.metadata);
|
|
21
20
|
}
|
|
22
21
|
computeChangeSet(entity) {
|
|
23
|
-
const meta = this.metadata.get(entity.constructor
|
|
22
|
+
const meta = this.metadata.get(entity.constructor);
|
|
24
23
|
if (meta.readonly) {
|
|
25
24
|
return null;
|
|
26
25
|
}
|
|
@@ -34,20 +33,21 @@ export class ChangeSetComputer {
|
|
|
34
33
|
this.processPropertyInitializers(entity, prop, type, map);
|
|
35
34
|
}
|
|
36
35
|
}
|
|
37
|
-
if (type === ChangeSetType.UPDATE && !wrapped.__initialized
|
|
38
|
-
|
|
36
|
+
if (type === ChangeSetType.UPDATE && !wrapped.__initialized) {
|
|
37
|
+
const data = this.comparator.prepareEntity(entity);
|
|
38
|
+
if (Utils.equals(data, wrapped.__originalEntityData)) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
39
41
|
}
|
|
40
42
|
const changeSet = new ChangeSet(entity, type, this.computePayload(entity), meta);
|
|
41
43
|
changeSet.originalEntity = wrapped.__originalEntityData;
|
|
42
|
-
if (this.config.get('validate')) {
|
|
43
|
-
this.validator.validate(changeSet.entity, changeSet.payload, meta);
|
|
44
|
-
}
|
|
45
44
|
for (const prop of meta.relations.filter(prop => prop.persist !== false || prop.userDefined === false)) {
|
|
46
45
|
this.processProperty(changeSet, prop);
|
|
47
46
|
}
|
|
48
47
|
if (changeSet.type === ChangeSetType.UPDATE && !Utils.hasObjectKeys(changeSet.payload)) {
|
|
49
48
|
return null;
|
|
50
49
|
}
|
|
50
|
+
validateEntity(changeSet.entity, meta);
|
|
51
51
|
// Execute `onCreate` and `onUpdate` on properties recursively, saves `onUpdate` results
|
|
52
52
|
// to the `map` as we want to apply those only if something else changed.
|
|
53
53
|
if (type === ChangeSetType.UPDATE) {
|
|
@@ -91,7 +91,7 @@ export class ChangeSetComputer {
|
|
|
91
91
|
computePayload(entity, ignoreUndefined = false) {
|
|
92
92
|
const data = this.comparator.prepareEntity(entity);
|
|
93
93
|
const wrapped = helper(entity);
|
|
94
|
-
const entityName = wrapped.__meta.
|
|
94
|
+
const entityName = wrapped.__meta.class;
|
|
95
95
|
const originalEntityData = wrapped.__originalEntityData;
|
|
96
96
|
if (!wrapped.__initialized) {
|
|
97
97
|
for (const prop of wrapped.__meta.primaryKeys) {
|
|
@@ -132,7 +132,16 @@ export class ChangeSetComputer {
|
|
|
132
132
|
const targets = Utils.unwrapProperty(changeSet.entity, changeSet.meta, prop);
|
|
133
133
|
targets.forEach(([target, idx]) => {
|
|
134
134
|
if (!target.__helper.hasPrimaryKey()) {
|
|
135
|
-
|
|
135
|
+
// When targetKey is set, use that property value instead of the PK identifier
|
|
136
|
+
let value = prop.targetKey ? target[prop.targetKey] : target.__helper.__identifier;
|
|
137
|
+
/* v8 ignore next */
|
|
138
|
+
if (prop.targetKey && prop.targetMeta) {
|
|
139
|
+
const targetProp = prop.targetMeta.properties[prop.targetKey];
|
|
140
|
+
if (targetProp?.customType) {
|
|
141
|
+
value = targetProp.customType.convertToDatabaseValue(value, this.platform, { mode: 'serialization' });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
Utils.setPayloadProperty(changeSet.payload, changeSet.meta, prop, value, idx);
|
|
136
145
|
}
|
|
137
146
|
});
|
|
138
147
|
}
|
|
@@ -141,9 +150,13 @@ export class ChangeSetComputer {
|
|
|
141
150
|
if (!target.isDirty() && changeSet.type !== ChangeSetType.CREATE) {
|
|
142
151
|
return;
|
|
143
152
|
}
|
|
144
|
-
|
|
153
|
+
if (target.isDirty()) {
|
|
154
|
+
this.collectionUpdates.add(target);
|
|
155
|
+
}
|
|
145
156
|
if (prop.owner && !this.platform.usesPivotTable()) {
|
|
146
|
-
changeSet.payload[prop.name] = target.getItems(false).map((item) =>
|
|
157
|
+
changeSet.payload[prop.name] = target.getItems(false).map((item) => {
|
|
158
|
+
return item.__helper.__identifier ?? item.__helper.getPrimaryKey();
|
|
159
|
+
});
|
|
147
160
|
}
|
|
148
161
|
}
|
|
149
162
|
}
|
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
import type { MetadataStorage } from '../metadata/MetadataStorage.js';
|
|
2
2
|
import type { Dictionary, EntityDictionary, EntityMetadata, IHydrator } from '../typings.js';
|
|
3
3
|
import { type EntityFactory } from '../entity/EntityFactory.js';
|
|
4
|
-
import { type EntityValidator } from '../entity/EntityValidator.js';
|
|
5
4
|
import { type ChangeSet } from './ChangeSet.js';
|
|
6
5
|
import { type Configuration } from '../utils/Configuration.js';
|
|
7
6
|
import type { DriverMethodOptions, IDatabaseDriver } from '../drivers/IDatabaseDriver.js';
|
|
7
|
+
import type { EntityManager } from '../EntityManager.js';
|
|
8
8
|
export declare class ChangeSetPersister {
|
|
9
9
|
private readonly driver;
|
|
10
10
|
private readonly metadata;
|
|
11
11
|
private readonly hydrator;
|
|
12
12
|
private readonly factory;
|
|
13
|
-
private readonly validator;
|
|
14
13
|
private readonly config;
|
|
14
|
+
private readonly em;
|
|
15
15
|
private readonly platform;
|
|
16
16
|
private readonly comparator;
|
|
17
17
|
private readonly usesReturningStatement;
|
|
18
|
-
constructor(driver: IDatabaseDriver, metadata: MetadataStorage, hydrator: IHydrator, factory: EntityFactory,
|
|
18
|
+
constructor(driver: IDatabaseDriver, metadata: MetadataStorage, hydrator: IHydrator, factory: EntityFactory, config: Configuration, em: EntityManager);
|
|
19
19
|
executeInserts<T extends object>(changeSets: ChangeSet<T>[], options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
|
|
20
20
|
executeUpdates<T extends object>(changeSets: ChangeSet<T>[], batched: boolean, options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
|
|
21
21
|
executeDeletes<T extends object>(changeSets: ChangeSet<T>[], options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
|
|
22
22
|
private runForEachSchema;
|
|
23
|
+
private validateRequired;
|
|
23
24
|
private processProperties;
|
|
24
25
|
private persistNewEntity;
|
|
25
26
|
private persistNewEntities;
|
|
26
|
-
private
|
|
27
|
+
private prepareOptions;
|
|
27
28
|
private persistNewEntitiesBatch;
|
|
28
29
|
private persistManagedEntity;
|
|
29
30
|
private persistManagedEntities;
|