@mikro-orm/knex 6.0.0-dev.109 → 6.0.0-dev.110

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.
@@ -148,7 +148,10 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
148
148
  return null;
149
149
  }
150
150
  if (qb) {
151
+ // here we map the aliased results (cartesian product) to an object graph
151
152
  this.mapJoinedProps(ret, meta, populate, qb, ret, map);
153
+ // we need to remove the cycles from the mapped values
154
+ core_1.Utils.removeCycles(ret, meta);
152
155
  }
153
156
  return ret;
154
157
  }
@@ -163,7 +166,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
163
166
  const meta2 = this.metadata.find(relation.type);
164
167
  const path = parentJoinPath ? `${parentJoinPath}.${relation.name}` : `${meta.name}.${relation.name}`;
165
168
  const relationAlias = qb.getAliasForJoinPath(path);
166
- const relationPojo = {};
169
+ let relationPojo = {};
167
170
  // If the primary key value for the relation is null, we know we haven't joined to anything
168
171
  // and therefore we don't return any record (since all values would be null)
169
172
  const hasPK = meta2.primaryKeys.every(pk => meta2.properties[pk].fieldNames.every(name => {
@@ -179,6 +182,17 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
179
182
  return;
180
183
  }
181
184
  const tz = this.platform.getTimezone();
185
+ meta2.props
186
+ .filter(prop => prop.persist === false && prop.fieldNames)
187
+ .forEach(prop => {
188
+ if (prop.fieldNames.length > 1) { // composite keys
189
+ relationPojo[prop.name] = prop.fieldNames.map(name => root[`${relationAlias}__${name}`]);
190
+ }
191
+ else {
192
+ const alias = `${relationAlias}__${prop.fieldNames[0]}`;
193
+ relationPojo[prop.name] = root[alias];
194
+ }
195
+ });
182
196
  meta2.props
183
197
  .filter(prop => this.platform.shouldHaveColumn(prop, p.children || []))
184
198
  .forEach(prop => {
@@ -197,7 +211,18 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
197
211
  delete root[alias];
198
212
  }
199
213
  });
200
- const key = `${meta.name}-${(core_1.Utils.getCompositeKeyHash(result, meta))}`;
214
+ const key = `${meta.name}-${core_1.Utils.getCompositeKeyHash(result, meta)}`;
215
+ const key2 = `${meta2.name}-${core_1.Utils.getCompositeKeyHash(relationPojo, meta2)}`;
216
+ if (map[key2]) {
217
+ const old = map[key2];
218
+ core_1.Utils.keys(relationPojo)
219
+ .filter(k => relationPojo[k] != null)
220
+ .forEach(k => old[k] = relationPojo[k]);
221
+ relationPojo = old;
222
+ }
223
+ else {
224
+ map[key2] = relationPojo;
225
+ }
201
226
  if (map[key]) {
202
227
  result[relation.name] = map[key][relation.name];
203
228
  }
@@ -299,16 +324,14 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
299
324
  const keys = [];
300
325
  props.forEach(prop => {
301
326
  if (prop.fieldNames.length > 1) {
302
- const param = [...row[prop.name] ?? prop.fieldNames.map(() => null)];
303
- const key = (row[prop.name] ?? prop.fieldNames).map(() => '?');
327
+ const param = core_1.Utils.flatten([...row[prop.name] ?? prop.fieldNames.map(() => null)]);
328
+ const key = param.map(() => '?');
304
329
  prop.fieldNames.forEach((field, idx) => {
305
- if (duplicates.includes(field)) {
306
- param.splice(idx, 1);
307
- key.splice(idx, 1);
330
+ if (!duplicates.includes(field)) {
331
+ params.push(param[idx]);
332
+ keys.push(key[idx]);
308
333
  }
309
334
  });
310
- params.push(...param);
311
- keys.push(...key);
312
335
  }
313
336
  else if (prop.customType && 'convertToDatabaseValueSQL' in prop.customType && !this.platform.isRaw(row[prop.name])) {
314
337
  keys.push(prop.customType.convertToDatabaseValueSQL('?', this.platform));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/knex",
3
- "version": "6.0.0-dev.109",
3
+ "version": "6.0.0-dev.110",
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
  "main": "index.js",
6
6
  "module": "index.mjs",
@@ -63,9 +63,9 @@
63
63
  "sqlstring": "2.3.3"
64
64
  },
65
65
  "devDependencies": {
66
- "@mikro-orm/core": "^5.8.3"
66
+ "@mikro-orm/core": "^5.8.5"
67
67
  },
68
68
  "peerDependencies": {
69
- "@mikro-orm/core": "~6.0.0-dev.109"
69
+ "@mikro-orm/core": "6.0.0-dev.110"
70
70
  }
71
71
  }
@@ -1,5 +1,5 @@
1
1
  import type { Knex } from 'knex';
2
- import { LockMode, type Dictionary, type EntityData, type EntityKey, type EntityMetadata, type EntityProperty, type FlatQueryOrderMap, type QBFilterQuery } from '@mikro-orm/core';
2
+ import { type Dictionary, type EntityData, type EntityKey, type EntityMetadata, type EntityProperty, type FlatQueryOrderMap, LockMode, type QBFilterQuery } from '@mikro-orm/core';
3
3
  import { QueryType } from './enums';
4
4
  import type { Field, JoinOptions } from '../typings';
5
5
  import type { AbstractSqlDriver } from '../AbstractSqlDriver';
@@ -171,8 +171,13 @@ class QueryBuilderHelper {
171
171
  }
172
172
  if (!join.subquery) {
173
173
  join.primaryKeys.forEach((primaryKey, idx) => {
174
- const left = `${join.ownerAlias}.${primaryKey}`;
175
174
  const right = `${join.alias}.${join.joinColumns[idx]}`;
175
+ if (join.prop.formula) {
176
+ const left = join.prop.formula(join.ownerAlias);
177
+ conditions.push(`${left} = ${this.knex.ref(right)}`);
178
+ return;
179
+ }
180
+ const left = join.prop.kind === core_1.ReferenceKind.SCALAR && join.prop.persist === false ? primaryKey : `${join.ownerAlias}.${primaryKey}`;
176
181
  conditions.push(`${this.knex.ref(left)} = ${this.knex.ref(right)}`);
177
182
  });
178
183
  }
@@ -81,8 +81,8 @@ class DatabaseTable {
81
81
  unsigned: prop.unsigned && this.platform.isNumericColumn(mappedType),
82
82
  autoincrement: prop.autoincrement ?? primary,
83
83
  primary,
84
+ nullable: this.columns[field]?.nullable ?? !!prop.nullable,
84
85
  nativeEnumName: prop.nativeEnumName,
85
- nullable: !!prop.nullable,
86
86
  length: prop.length,
87
87
  precision: prop.precision,
88
88
  scale: prop.scale,