@mikro-orm/core 7.1.0-dev.8 → 7.1.0
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 +70 -5
- package/EntityManager.js +175 -23
- package/README.md +2 -1
- package/connections/Connection.d.ts +67 -1
- package/connections/Connection.js +64 -0
- package/drivers/IDatabaseDriver.d.ts +30 -6
- package/entity/BaseEntity.d.ts +68 -1
- package/entity/BaseEntity.js +18 -0
- package/entity/Collection.d.ts +4 -1
- package/entity/Collection.js +15 -4
- package/entity/EntityAssigner.js +8 -0
- package/entity/EntityFactory.js +5 -3
- package/entity/EntityLoader.d.ts +8 -1
- package/entity/EntityLoader.js +97 -29
- package/entity/EntityRepository.d.ts +12 -2
- package/entity/EntityRepository.js +12 -0
- package/entity/Reference.d.ts +42 -1
- package/entity/Reference.js +9 -0
- package/entity/defineEntity.d.ts +69 -16
- package/entity/defineEntity.js +17 -0
- package/entity/utils.js +4 -5
- package/enums.d.ts +8 -1
- package/index.d.ts +1 -1
- package/metadata/EntitySchema.js +18 -0
- package/metadata/MetadataDiscovery.d.ts +1 -0
- package/metadata/MetadataDiscovery.js +79 -15
- package/metadata/MetadataValidator.d.ts +26 -0
- package/metadata/MetadataValidator.js +228 -1
- package/metadata/Routine.d.ts +74 -0
- package/metadata/Routine.js +140 -0
- package/metadata/index.d.ts +1 -0
- package/metadata/index.js +1 -0
- package/metadata/types.d.ts +75 -8
- package/package.json +1 -1
- package/platforms/Platform.d.ts +13 -3
- package/platforms/Platform.js +51 -6
- package/serialization/EntitySerializer.js +4 -3
- package/typings.d.ts +323 -21
- package/typings.js +32 -12
- package/unit-of-work/UnitOfWork.js +43 -5
- package/utils/AbstractMigrator.d.ts +9 -4
- package/utils/AbstractMigrator.js +60 -28
- package/utils/AbstractSchemaGenerator.d.ts +1 -1
- package/utils/AbstractSchemaGenerator.js +4 -1
- package/utils/Configuration.d.ts +30 -0
- package/utils/Configuration.js +45 -0
- package/utils/DataloaderUtils.d.ts +10 -1
- package/utils/DataloaderUtils.js +78 -0
- package/utils/EntityComparator.js +1 -1
- package/utils/TransactionManager.js +2 -0
- package/utils/Utils.js +1 -1
- package/utils/index.d.ts +1 -0
- package/utils/index.js +1 -0
- package/utils/partition-utils.d.ts +17 -0
- package/utils/partition-utils.js +79 -0
- package/utils/upsert-utils.d.ts +2 -0
- package/utils/upsert-utils.js +26 -1
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
function normalizeIdentifierSegment(segment) {
|
|
2
|
+
const trimmed = segment.trim();
|
|
3
|
+
if (trimmed.length >= 2 && trimmed.startsWith('"') && trimmed.endsWith('"')) {
|
|
4
|
+
return trimmed.slice(1, -1).replaceAll('""', '"');
|
|
5
|
+
}
|
|
6
|
+
return trimmed.toLowerCase();
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Normalize a partition name for collision detection. Mirrors PostgreSQL identifier
|
|
10
|
+
* resolution: unquoted segments fold to lower case, quoted segments preserve case and
|
|
11
|
+
* un-escape embedded `""`. Returns a canonical `schema.name` form so both schema-qualified
|
|
12
|
+
* and bare names compare consistently (`.name` vs `schema.name` stay distinguishable).
|
|
13
|
+
*
|
|
14
|
+
* `Part_1`, `part_1`, and `"part_1"` all normalize to the same value, catching collisions
|
|
15
|
+
* that would otherwise only surface as runtime PG "relation already exists" errors.
|
|
16
|
+
*/
|
|
17
|
+
export function normalizePartitionNameForComparison(name) {
|
|
18
|
+
const trimmed = name.trim();
|
|
19
|
+
let depth = 0;
|
|
20
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
21
|
+
const ch = trimmed[i];
|
|
22
|
+
if (ch === '"') {
|
|
23
|
+
if (trimmed[i + 1] === '"') {
|
|
24
|
+
i++;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
depth = depth === 0 ? 1 : 0;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (ch === '.' && depth === 0) {
|
|
31
|
+
return `${normalizeIdentifierSegment(trimmed.slice(0, i))}.${normalizeIdentifierSegment(trimmed.slice(i + 1))}`;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return `.${normalizeIdentifierSegment(trimmed)}`;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Split a comma-list of identifiers, respecting double-quoted identifiers (which may contain
|
|
38
|
+
* commas and use `""` to escape embedded quotes). Returns `null` when the input is not a clean
|
|
39
|
+
* comma-list of identifiers (e.g. contains function calls or literals), so callers treat it
|
|
40
|
+
* as an opaque expression.
|
|
41
|
+
*/
|
|
42
|
+
export function splitCommaSeparatedIdentifiers(value) {
|
|
43
|
+
const segments = [];
|
|
44
|
+
let buffer = '';
|
|
45
|
+
let inQuote = false;
|
|
46
|
+
for (let i = 0; i < value.length; i++) {
|
|
47
|
+
const ch = value[i];
|
|
48
|
+
if (ch === '"') {
|
|
49
|
+
if (inQuote && value[i + 1] === '"') {
|
|
50
|
+
buffer += '""';
|
|
51
|
+
i++;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
inQuote = !inQuote;
|
|
55
|
+
buffer += ch;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (!inQuote) {
|
|
59
|
+
if (ch === ',') {
|
|
60
|
+
segments.push(buffer);
|
|
61
|
+
buffer = '';
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (!/[\w.\s]/.test(ch)) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
buffer += ch;
|
|
69
|
+
}
|
|
70
|
+
if (inQuote) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
segments.push(buffer);
|
|
74
|
+
const trimmed = segments.map(s => s.trim());
|
|
75
|
+
if (trimmed.some(s => s === '')) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
return trimmed;
|
|
79
|
+
}
|
package/utils/upsert-utils.d.ts
CHANGED
|
@@ -10,3 +10,5 @@ export declare function getWhereCondition<T extends object>(meta: EntityMetadata
|
|
|
10
10
|
where: FilterQuery<T>;
|
|
11
11
|
propIndex: number | false;
|
|
12
12
|
};
|
|
13
|
+
/** @internal */
|
|
14
|
+
export declare function resetUntouchedCollections<Entity extends object>(meta: EntityMetadata<Entity>, entity: Entity): void;
|
package/utils/upsert-utils.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { isRaw } from '../utils/RawQueryFragment.js';
|
|
2
2
|
import { Utils } from './Utils.js';
|
|
3
|
+
import { ReferenceKind } from '../enums.js';
|
|
4
|
+
import { Collection } from '../entity/Collection.js';
|
|
5
|
+
import { helper } from '../entity/wrap.js';
|
|
3
6
|
function expandEmbeddedProperties(prop, key) {
|
|
4
7
|
if (prop.object) {
|
|
5
8
|
return [prop.name];
|
|
@@ -52,7 +55,9 @@ export function getOnConflictFields(meta, data, uniqueFields, options) {
|
|
|
52
55
|
});
|
|
53
56
|
}
|
|
54
57
|
const keys = Object.keys(data).flatMap(f => {
|
|
55
|
-
|
|
58
|
+
// skip explicitly listed unique fields; for raw onConflictFields we can't introspect the
|
|
59
|
+
// fragment, so merge all data keys (the user is responsible for not corrupting them).
|
|
60
|
+
if (Array.isArray(uniqueFields) && uniqueFields.includes(f)) {
|
|
56
61
|
return [];
|
|
57
62
|
}
|
|
58
63
|
const prop = meta?.properties[f];
|
|
@@ -142,3 +147,23 @@ export function getWhereCondition(meta, onConflictFields, data, where) {
|
|
|
142
147
|
}
|
|
143
148
|
return { where, propIndex };
|
|
144
149
|
}
|
|
150
|
+
/** @internal */
|
|
151
|
+
export function resetUntouchedCollections(meta, entity) {
|
|
152
|
+
// for entities passed in via `em.create()` and then upserted, collection-kind relations
|
|
153
|
+
// were initialized as empty-but-initialized by the hydrator (newEntity=true). once the
|
|
154
|
+
// upsert resolves the entity to a possibly existing row, that state is stale and would
|
|
155
|
+
// cause `em.populate()` to skip those collections. replace them with a fresh
|
|
156
|
+
// uninitialized collection so populate can load them.
|
|
157
|
+
if (helper(entity).__originalEntityData) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
for (const prop of meta.relations) {
|
|
161
|
+
if (prop.kind !== ReferenceKind.MANY_TO_MANY && prop.kind !== ReferenceKind.ONE_TO_MANY) {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
const collection = entity[prop.name];
|
|
165
|
+
if (Utils.isCollection(collection) && collection.isInitialized() && !collection.isDirty()) {
|
|
166
|
+
Collection.create(entity, prop.name, undefined, false);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|