@mikro-orm/core 7.2.2-dev.6 → 7.2.2-dev.7
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.js +7 -4
- package/entity/defineEntity.d.ts +1 -1
- package/entity/defineEntity.js +1 -1
- package/metadata/MetadataDiscovery.d.ts +2 -0
- package/metadata/MetadataDiscovery.js +11 -0
- package/metadata/types.d.ts +1 -1
- package/package.json +1 -1
- package/utils/Utils.js +1 -1
- package/utils/upsert-utils.d.ts +2 -1
- package/utils/upsert-utils.js +9 -5
package/EntityManager.js
CHANGED
|
@@ -994,13 +994,14 @@ export class EntityManager {
|
|
|
994
994
|
});
|
|
995
995
|
const uniqueFields = options.onConflictFields ??
|
|
996
996
|
(Utils.isPlainObject(where) ? Object.keys(where) : meta.primaryKeys);
|
|
997
|
-
const
|
|
997
|
+
const platform = this.getPlatform();
|
|
998
|
+
const returning = getOnConflictReturningFields(meta, data, uniqueFields, options, platform);
|
|
998
999
|
if (options.onConflictWhere && !ret.row) {
|
|
999
1000
|
returning.push(...Object.keys(data));
|
|
1000
1001
|
}
|
|
1001
1002
|
if (options.onConflictAction === 'ignore' ||
|
|
1002
1003
|
!helper(entity).hasPrimaryKey() ||
|
|
1003
|
-
(returning.length > 0 && !(
|
|
1004
|
+
(returning.length > 0 && !((platform.usesReturningStatement() || platform.usesOutputStatement()) && ret.row))) {
|
|
1004
1005
|
const where = {};
|
|
1005
1006
|
if (Array.isArray(uniqueFields)) {
|
|
1006
1007
|
for (const prop of uniqueFields) {
|
|
@@ -1230,11 +1231,13 @@ export class EntityManager {
|
|
|
1230
1231
|
// (onConflictWhere can suppress writes, leaving some rows out)
|
|
1231
1232
|
// oxfmt-ignore
|
|
1232
1233
|
const uniqueFields = options.onConflictFields ?? (Utils.isPlainObject(allWhere[0]) ? Object.keys(allWhere[0]).flatMap(key => Utils.splitPrimaryKeys(key)) : meta.primaryKeys);
|
|
1233
|
-
const
|
|
1234
|
+
const platform = this.getPlatform();
|
|
1235
|
+
const returning = getOnConflictReturningFields(meta, data[0], uniqueFields, options, platform);
|
|
1234
1236
|
if (options.onConflictWhere && res.rows?.length !== allData.length) {
|
|
1235
1237
|
returning.push(...meta.comparableProps.filter(p => !p.lazy && !p.embeddable).map(p => p.name));
|
|
1236
1238
|
}
|
|
1237
|
-
const reloadFields = returning.length > 0 &&
|
|
1239
|
+
const reloadFields = returning.length > 0 &&
|
|
1240
|
+
!((platform.usesReturningStatement() || platform.usesOutputStatement()) && res.rows?.length === data.length);
|
|
1238
1241
|
if (options.onConflictAction === 'ignore' || (!res.rows?.length && loadPK.size > 0) || reloadFields) {
|
|
1239
1242
|
const unique = meta.hydrateProps.filter(p => !p.lazy).map(p => p.name);
|
|
1240
1243
|
const add = new Set(propIndex !== false && propIndex >= 0
|
package/entity/defineEntity.d.ts
CHANGED
|
@@ -267,7 +267,7 @@ export declare class UniversalPropertyOptionsBuilder<in out Value, in out Option
|
|
|
267
267
|
autoincrement: false;
|
|
268
268
|
}, IncludeKeys>, IncludeKeys>;
|
|
269
269
|
/**
|
|
270
|
-
* Add the property to the `returning`
|
|
270
|
+
* Add the property to the `returning` clause of inserts, updates and upserts, reloading the database value into the entity.
|
|
271
271
|
*/
|
|
272
272
|
returning(returning?: boolean): Pick<UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>, IncludeKeys>;
|
|
273
273
|
/**
|
package/entity/defineEntity.js
CHANGED
|
@@ -88,7 +88,7 @@ export class UniversalPropertyOptionsBuilder {
|
|
|
88
88
|
return this.assignOptions({ autoincrement });
|
|
89
89
|
}
|
|
90
90
|
/**
|
|
91
|
-
* Add the property to the `returning`
|
|
91
|
+
* Add the property to the `returning` clause of inserts, updates and upserts, reloading the database value into the entity.
|
|
92
92
|
*/
|
|
93
93
|
returning(returning = true) {
|
|
94
94
|
return this.assignOptions({ returning });
|
|
@@ -128,6 +128,8 @@ export declare class MetadataDiscovery {
|
|
|
128
128
|
private initRelation;
|
|
129
129
|
/** Resolves the `through` option of a virtual to-one relation into a read-only formula property. */
|
|
130
130
|
private initThroughRelation;
|
|
131
|
+
/** `returning` is only honoured for physical columns that can be hydrated back into the entity. */
|
|
132
|
+
private initReturning;
|
|
131
133
|
private initColumnType;
|
|
132
134
|
private getMappedType;
|
|
133
135
|
private getPrefix;
|
|
@@ -174,6 +174,7 @@ export class MetadataDiscovery {
|
|
|
174
174
|
this.initRelation(p);
|
|
175
175
|
this.initThroughRelation(m, p);
|
|
176
176
|
this.initColumnType(p);
|
|
177
|
+
this.initReturning(p);
|
|
177
178
|
});
|
|
178
179
|
forEachProp((m, p) => this.initIndexes(m, p));
|
|
179
180
|
filtered.forEach(meta => this.autoWireBidirectionalProperties(meta));
|
|
@@ -2129,6 +2130,16 @@ export class MetadataDiscovery {
|
|
|
2129
2130
|
prop.persist = false;
|
|
2130
2131
|
prop.formula = columns => this.#platform.getThroughRelationFormula(prop, columns);
|
|
2131
2132
|
}
|
|
2133
|
+
/** `returning` is only honoured for physical columns that can be hydrated back into the entity. */
|
|
2134
|
+
initReturning(prop) {
|
|
2135
|
+
const owning = prop.kind === ReferenceKind.SCALAR ||
|
|
2136
|
+
prop.kind === ReferenceKind.MANY_TO_ONE ||
|
|
2137
|
+
(prop.kind === ReferenceKind.ONE_TO_ONE && prop.owner) ||
|
|
2138
|
+
(prop.kind === ReferenceKind.EMBEDDED && prop.object);
|
|
2139
|
+
if (prop.returning && (!owning || prop.persist === false || prop.hydrate === false || prop.formula)) {
|
|
2140
|
+
prop.returning = false;
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2132
2143
|
initColumnType(prop) {
|
|
2133
2144
|
this.initUnsigned(prop);
|
|
2134
2145
|
// Get the target properties for FK relations - use targetKey property if specified, otherwise PKs
|
package/metadata/types.d.ts
CHANGED
|
@@ -175,7 +175,7 @@ export interface PropertyOptions<Owner> {
|
|
|
175
175
|
*/
|
|
176
176
|
autoincrement?: boolean;
|
|
177
177
|
/**
|
|
178
|
-
* Add the property to the `returning`
|
|
178
|
+
* Add the property to the `returning` clause of inserts, updates and upserts, reloading the database value into the entity.
|
|
179
179
|
*/
|
|
180
180
|
returning?: boolean;
|
|
181
181
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
|
-
"version": "7.2.2-dev.
|
|
3
|
+
"version": "7.2.2-dev.7",
|
|
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",
|
package/utils/Utils.js
CHANGED
|
@@ -153,7 +153,7 @@ export function parseJsonSafe(value) {
|
|
|
153
153
|
/** Collection of general-purpose utility methods used throughout the ORM. */
|
|
154
154
|
export class Utils {
|
|
155
155
|
static PK_SEPARATOR = '~~~';
|
|
156
|
-
static #ORM_VERSION = '7.2.2-dev.
|
|
156
|
+
static #ORM_VERSION = '7.2.2-dev.7';
|
|
157
157
|
/** Default session variable name backing an RLS filter argument (`current_setting('mikro.<filter>.<arg>')`). */
|
|
158
158
|
static getRlsSettingName(filterName, argName) {
|
|
159
159
|
return `mikro.${filterName}.${argName}`;
|
package/utils/upsert-utils.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { EntityData, EntityKey, EntityMetadata, FilterQuery } from '../typings.js';
|
|
2
2
|
import type { UpsertOptions } from '../drivers/IDatabaseDriver.js';
|
|
3
3
|
import { type Raw } from '../utils/RawQueryFragment.js';
|
|
4
|
+
import type { Platform } from '../platforms/Platform.js';
|
|
4
5
|
/** @internal */
|
|
5
6
|
export declare function getOnConflictFields<T>(meta: EntityMetadata<T> | undefined, data: EntityData<T>, uniqueFields: (keyof T)[] | Raw, options: UpsertOptions<T>): (keyof T)[];
|
|
6
7
|
/**
|
|
@@ -12,7 +13,7 @@ export declare function getOnConflictFields<T>(meta: EntityMetadata<T> | undefin
|
|
|
12
13
|
*/
|
|
13
14
|
export declare function getOnCreateGeneratedFields<T extends object>(meta: EntityMetadata<T>, data: T | EntityData<T>): EntityKey<T>[];
|
|
14
15
|
/** @internal */
|
|
15
|
-
export declare function getOnConflictReturningFields<T, P extends string>(meta: EntityMetadata<T> | undefined, data: EntityData<T>, uniqueFields: (keyof T)[] | Raw, options: UpsertOptions<T, P
|
|
16
|
+
export declare function getOnConflictReturningFields<T, P extends string>(meta: EntityMetadata<T> | undefined, data: EntityData<T>, uniqueFields: (keyof T)[] | Raw, options: UpsertOptions<T, P>, platform?: Platform): (keyof T)[] | '*';
|
|
16
17
|
/** @internal */
|
|
17
18
|
export declare function getWhereCondition<T extends object>(meta: EntityMetadata<T>, onConflictFields: (keyof T)[] | Raw | undefined, data: EntityData<T>, where: FilterQuery<T>): {
|
|
18
19
|
where: FilterQuery<T>;
|
package/utils/upsert-utils.js
CHANGED
|
@@ -89,11 +89,15 @@ export function getOnCreateGeneratedFields(meta, data) {
|
|
|
89
89
|
.map(prop => prop.name);
|
|
90
90
|
}
|
|
91
91
|
/** @internal */
|
|
92
|
-
export function getOnConflictReturningFields(meta, data, uniqueFields, options) {
|
|
92
|
+
export function getOnConflictReturningFields(meta, data, uniqueFields, options, platform) {
|
|
93
93
|
/* v8 ignore next */
|
|
94
94
|
if (!meta) {
|
|
95
95
|
return '*';
|
|
96
96
|
}
|
|
97
|
+
// props with explicit `returning` hint are reloaded even when supplied, as the database might normalize them
|
|
98
|
+
const returning = platform?.usesReturningStatement() || platform?.usesOutputStatement()
|
|
99
|
+
? meta.props.filter(p => p.returning).map(p => p.name)
|
|
100
|
+
: [];
|
|
97
101
|
const keys = meta.comparableProps
|
|
98
102
|
.filter(p => {
|
|
99
103
|
if (p.lazy || p.embeddable) {
|
|
@@ -112,17 +116,17 @@ export function getOnConflictReturningFields(meta, data, uniqueFields, options)
|
|
|
112
116
|
keys.push(meta.versionProperty);
|
|
113
117
|
}
|
|
114
118
|
if (options.onConflictAction === 'ignore') {
|
|
115
|
-
return keys;
|
|
119
|
+
return Utils.unique([...keys, ...returning]);
|
|
116
120
|
}
|
|
117
121
|
if (options.onConflictMergeFields) {
|
|
118
122
|
const onConflictMergeFields = expandFields(meta, options.onConflictMergeFields);
|
|
119
|
-
return keys.filter(key => !onConflictMergeFields.includes(key));
|
|
123
|
+
return Utils.unique([...keys.filter(key => !onConflictMergeFields.includes(key)), ...returning]);
|
|
120
124
|
}
|
|
121
125
|
if (options.onConflictExcludeFields) {
|
|
122
126
|
const onConflictExcludeFields = expandFields(meta, options.onConflictExcludeFields);
|
|
123
|
-
return [...
|
|
127
|
+
return Utils.unique([...keys, ...onConflictExcludeFields, ...returning]);
|
|
124
128
|
}
|
|
125
|
-
return keys.filter(key => !(key in data));
|
|
129
|
+
return Utils.unique([...keys.filter(key => !(key in data)), ...returning]);
|
|
126
130
|
}
|
|
127
131
|
function getPropertyValue(obj, key) {
|
|
128
132
|
if (!key.includes('.')) {
|