@mikro-orm/sql 7.1.15-dev.15 → 7.1.15-dev.16
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/AbstractSqlDriver.js +33 -4
- package/package.json +2 -2
- package/query/QueryBuilder.js +2 -0
package/AbstractSqlDriver.js
CHANGED
|
@@ -915,8 +915,11 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
915
915
|
if (!options.upsert && options.unionWhere?.length) {
|
|
916
916
|
where = (await this.applyUnionWhere(meta, where, options, true));
|
|
917
917
|
}
|
|
918
|
-
|
|
919
|
-
|
|
918
|
+
if (options.upsert && meta.tptParent) {
|
|
919
|
+
res = await this.nativeUpdateMany(entityName, [where], [data], options);
|
|
920
|
+
}
|
|
921
|
+
else if (Utils.hasObjectKeys(data) || (meta.inheritanceType === 'tpt' && meta.ownsVersionProperty())) {
|
|
922
|
+
// a TPT table declaring the version property is bumped even when only other tables of the hierarchy changed
|
|
920
923
|
const qb = this.createQueryBuilder(entityName, options.ctx, 'write', options.convertCustomTypes, options.loggerContext).withSchema(this.getSchemaName(meta, options));
|
|
921
924
|
qb.setAbortOptions(pickAbortOptions(options));
|
|
922
925
|
if (options.upsert) {
|
|
@@ -958,13 +961,38 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
958
961
|
options.convertCustomTypes ??= true;
|
|
959
962
|
const meta = this.metadata.get(entityName);
|
|
960
963
|
if (options.upsert) {
|
|
964
|
+
if (meta.tptParent) {
|
|
965
|
+
// TPT parent tables go first, the PK they provide is the conflict target of this table
|
|
966
|
+
await this.nativeUpdateMany(meta.tptParent.class, where, data, options);
|
|
967
|
+
for (const [i, row] of data.entries()) {
|
|
968
|
+
if (meta.primaryKeys.some(pk => row[pk] == null)) {
|
|
969
|
+
const found = await this.findOne(meta.tptParent.class, where[i], {
|
|
970
|
+
fields: meta.primaryKeys,
|
|
971
|
+
ctx: options.ctx,
|
|
972
|
+
connectionType: 'write',
|
|
973
|
+
schema: options.schema,
|
|
974
|
+
});
|
|
975
|
+
meta.primaryKeys.forEach(pk => (row[pk] = found?.[pk]));
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
options = { ...options, onConflictFields: meta.primaryKeys, onConflictWhere: undefined };
|
|
979
|
+
}
|
|
961
980
|
const uniqueFields = options.onConflictFields ??
|
|
962
981
|
(Utils.isPlainObject(where[0])
|
|
963
982
|
? Object.keys(where[0]).flatMap(key => Utils.splitPrimaryKeys(key))
|
|
964
983
|
: meta.primaryKeys);
|
|
965
984
|
const qb = this.createQueryBuilder(entityName, options.ctx, 'write', options.convertCustomTypes, options.loggerContext).withSchema(this.getSchemaName(meta, options));
|
|
966
985
|
qb.setAbortOptions(pickAbortOptions(options));
|
|
967
|
-
|
|
986
|
+
let returning = getOnConflictReturningFields(meta, data[0], uniqueFields, options);
|
|
987
|
+
if (meta.inheritanceType === 'tpt') {
|
|
988
|
+
// each TPT table only carries its own columns, the entity is reloaded instead of mapping the returned rows
|
|
989
|
+
const own = (key) => meta.primaryKeys.includes(key) ||
|
|
990
|
+
this.getTableProps(meta).some(prop => prop.name === key.split('.')[0]);
|
|
991
|
+
data = data.map(row => Object.fromEntries(Object.entries(row).filter(([key]) => own(key))));
|
|
992
|
+
options.onConflictMergeFields = options.onConflictMergeFields?.filter(f => own(f));
|
|
993
|
+
options.onConflictExcludeFields = options.onConflictExcludeFields?.filter(f => own(f));
|
|
994
|
+
returning = [];
|
|
995
|
+
}
|
|
968
996
|
qb.insert(data)
|
|
969
997
|
.onConflict(uniqueFields)
|
|
970
998
|
.returning(returning);
|
|
@@ -978,7 +1006,8 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
978
1006
|
if (options.onConflictWhere) {
|
|
979
1007
|
qb.where(options.onConflictWhere);
|
|
980
1008
|
}
|
|
981
|
-
|
|
1009
|
+
const res = await this.rethrow(qb.execute('run', false));
|
|
1010
|
+
return meta.inheritanceType === 'tpt' ? { ...res, row: undefined, rows: [] } : res;
|
|
982
1011
|
}
|
|
983
1012
|
const collections = options.processCollections ? data.map(d => this.extractManyToMany(meta, d)) : [];
|
|
984
1013
|
const keys = new Set();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/sql",
|
|
3
|
-
"version": "7.1.15-dev.
|
|
3
|
+
"version": "7.1.15-dev.16",
|
|
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",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"@mikro-orm/core": "^7.1.14"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"@mikro-orm/core": "7.1.15-dev.
|
|
56
|
+
"@mikro-orm/core": "7.1.15-dev.16"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|
|
59
59
|
"node": ">= 22.17.0"
|
package/query/QueryBuilder.js
CHANGED
|
@@ -904,6 +904,8 @@ export class QueryBuilder {
|
|
|
904
904
|
if (this.type === QueryType.INSERT) {
|
|
905
905
|
const returningProps = meta.hydrateProps
|
|
906
906
|
.filter(prop => prop.returning || (prop.persist !== false && ((prop.primary && prop.autoincrement) || prop.defaultRaw)))
|
|
907
|
+
// a TPT table can only return its own columns
|
|
908
|
+
.filter(prop => meta.inheritanceType !== 'tpt' || prop.primary || meta.ownProps.some(p => p.name === prop.name))
|
|
907
909
|
.filter(prop => !data || !(prop.name in data));
|
|
908
910
|
if (returningProps.length > 0) {
|
|
909
911
|
qb.returning(Utils.flatten(returningProps.map(prop => prop.fieldNames)));
|