@mikro-orm/sql 7.3.0-dev.4 → 7.3.0-dev.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/sql",
3
- "version": "7.3.0-dev.4",
3
+ "version": "7.3.0-dev.5",
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.2.1"
54
54
  },
55
55
  "peerDependencies": {
56
- "@mikro-orm/core": "7.3.0-dev.4"
56
+ "@mikro-orm/core": "7.3.0-dev.5"
57
57
  },
58
58
  "engines": {
59
59
  "node": ">= 22.17.0"
@@ -29,7 +29,7 @@ export class CriteriaNode {
29
29
  }
30
30
  for (const k of pks) {
31
31
  const [name, target] = QueryHelper.splitPolymorphicKey(k);
32
- this.prop = meta.props.find(prop => (prop.name === name && (!target || !!prop.polymorphTargets?.some(t => t.className === target))) ||
32
+ this.prop = meta.props.find(prop => (prop.name === name && (!target || QueryHelper.findTargetMetas(prop, k).length > 0)) ||
33
33
  (prop.fieldNames?.length === 1 && prop.fieldNames[0] === k && prop.persist !== false));
34
34
  const isProp = this.prop || meta.props.find(prop => (prop.fieldNames || []).includes(k));
35
35
  // do not validate if the key is prefixed or type casted (e.g. `k::text`)
@@ -52,7 +52,7 @@ export class CriteriaNodeFactory {
52
52
  const rawField = RawQueryFragment.isKnownFragmentSymbol(key);
53
53
  const prop = rawField ? null : meta?.properties[QueryHelper.splitPolymorphicKey(key)[0]];
54
54
  const target = rawField ? undefined : QueryHelper.findTargetMeta(prop, key);
55
- const childEntity = prop && prop.kind !== ReferenceKind.SCALAR ? (target ?? prop.targetMeta).class : entityName;
55
+ const childEntity = prop && prop.kind !== ReferenceKind.SCALAR && target ? target.class : entityName;
56
56
  const isNotEmbedded = rawField || prop?.kind !== ReferenceKind.EMBEDDED;
57
57
  const val = payload[key];
58
58
  if (isNotEmbedded && prop?.customType instanceof JsonType) {
@@ -5,6 +5,8 @@ import type { ICriteriaNodeProcessOptions, IQueryBuilder } from '../typings.js';
5
5
  */
6
6
  export declare class ObjectCriteriaNode<T extends object> extends CriteriaNode<T> {
7
7
  process(qb: IQueryBuilder<T>, options?: ICriteriaNodeProcessOptions): any;
8
+ /** Orders by the first non-null value of the property across the joined polymorphic targets. */
9
+ private processPolymorphicOrderBy;
8
10
  isStrict(): boolean;
9
11
  unwrap(): any;
10
12
  willAutoJoin(qb: IQueryBuilder<T>, alias?: string, options?: ICriteriaNodeProcessOptions): boolean;
@@ -1,4 +1,4 @@
1
- import { ALIAS_REPLACEMENT, GroupOperator, QueryFlag, raw, RawQueryFragment, ReferenceKind, Utils, } from '@mikro-orm/core';
1
+ import { ALIAS_REPLACEMENT, GroupOperator, QueryFlag, QueryHelper, raw, RawQueryFragment, ReferenceKind, Utils, } from '@mikro-orm/core';
2
2
  import { CriteriaNode } from './CriteriaNode.js';
3
3
  import { JoinType, QueryType } from './enums.js';
4
4
  const COLLECTION_OPERATORS = ['$some', '$none', '$every', '$size', '$all'];
@@ -7,6 +7,10 @@ const COLLECTION_OPERATORS = ['$some', '$none', '$every', '$size', '$all'];
7
7
  */
8
8
  export class ObjectCriteriaNode extends CriteriaNode {
9
9
  process(qb, options) {
10
+ const targets = this.isPolymorphicBranch() ? QueryHelper.findTargetMetas(this.prop, this.key) : [];
11
+ if (options?.type === 'orderBy' && targets.length > 1) {
12
+ return this.processPolymorphicOrderBy(qb, targets, options);
13
+ }
10
14
  const matchPopulateJoins = options?.matchPopulateJoins ||
11
15
  (this.prop && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(this.prop.kind));
12
16
  const nestedAlias = qb.getAliasForJoinPath(this.getPath(options), { ...options, matchPopulateJoins });
@@ -150,12 +154,31 @@ export class ObjectCriteriaNode extends CriteriaNode {
150
154
  return o;
151
155
  }, {});
152
156
  // the target is left joined, so its condition must only match rows that point to it
153
- if (this.isPolymorphicBranch() && alias) {
157
+ if (this.isPolymorphicBranch() && alias && options?.type !== 'orderBy') {
154
158
  const pk = this.metadata.find(this.entityName).primaryKeys[0];
155
159
  this.inlineCondition(`${alias}.${pk}`, ret, { $ne: null });
156
160
  }
157
161
  return ret;
158
162
  }
163
+ /** Orders by the first non-null value of the property across the joined polymorphic targets. */
164
+ processPolymorphicOrderBy(qb, targets, options) {
165
+ const ownerAlias = options.alias || qb.alias;
166
+ const aliases = targets.map(target => {
167
+ const path = `${this.parent.getPath()}.${this.prop.name}[${target.className}]`;
168
+ const alias = qb.getAliasForJoinPath(path, { ...options, matchPopulateJoins: true });
169
+ if (alias) {
170
+ return alias;
171
+ }
172
+ const newAlias = qb.getNextAlias(target.class);
173
+ qb.addPolymorphicJoin(this.prop, target, ownerAlias, newAlias, JoinType.leftJoin, path);
174
+ return newAlias;
175
+ });
176
+ return Utils.getObjectQueryKeys(this.payload).reduce((o, field) => {
177
+ const columns = targets.map((target, i) => `${aliases[i]}.${target.properties[field].fieldNames[0]}`);
178
+ o[raw(`coalesce(${columns.map(() => '??').join(', ')})`, columns)] = this.payload[field].payload;
179
+ return o;
180
+ }, {});
181
+ }
159
182
  isStrict() {
160
183
  return (this.strict ||
161
184
  Utils.getObjectQueryKeys(this.payload).some(key => {