@mikro-orm/knex 5.8.11-dev.1 → 5.8.11-dev.11

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/knex",
3
- "version": "5.8.11-dev.1",
3
+ "version": "5.8.11-dev.11",
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",
@@ -66,9 +66,9 @@
66
66
  "@mikro-orm/core": "^5.8.10"
67
67
  },
68
68
  "peerDependencies": {
69
- "@mikro-orm/core": "5.8.11-dev.1",
70
- "@mikro-orm/entity-generator": "5.8.11-dev.1",
71
- "@mikro-orm/migrations": "5.8.11-dev.1",
69
+ "@mikro-orm/core": "5.8.11-dev.11",
70
+ "@mikro-orm/entity-generator": "5.8.11-dev.11",
71
+ "@mikro-orm/migrations": "5.8.11-dev.11",
72
72
  "better-sqlite3": "*",
73
73
  "mssql": "*",
74
74
  "mysql": "*",
@@ -473,7 +473,8 @@ class QueryBuilder {
473
473
  if (cached?.data) {
474
474
  return cached.data;
475
475
  }
476
- const type = this.connectionType || (method === 'run' ? 'write' : 'read');
476
+ const write = method === 'run' || !this.platform.getConfig().get('preferReadReplicas');
477
+ const type = this.connectionType || (write ? 'write' : 'read');
477
478
  const res = await this.driver.getConnection(type).execute(query.sql, query.bindings, method, this.context);
478
479
  const meta = this.mainAlias.metadata;
479
480
  if (!options.mapResults || !meta) {
@@ -689,6 +690,12 @@ class QueryBuilder {
689
690
  }
690
691
  prepareFields(fields, type = 'where') {
691
692
  const ret = [];
693
+ const getFieldName = (name) => {
694
+ if (type === 'groupBy') {
695
+ return this.helper.mapper(name, this.type, undefined, null);
696
+ }
697
+ return this.helper.mapper(name, this.type);
698
+ };
692
699
  fields.forEach(field => {
693
700
  if (!core_1.Utils.isString(field)) {
694
701
  return ret.push(field);
@@ -705,19 +712,18 @@ class QueryBuilder {
705
712
  }
706
713
  if (prop?.embedded) {
707
714
  const name = this._aliases[a] ? `${a}.${prop.fieldNames[0]}` : prop.fieldNames[0];
708
- const fieldName = this.helper.mapper(name, this.type);
709
- ret.push(fieldName);
715
+ ret.push(getFieldName(name));
710
716
  return;
711
717
  }
712
718
  if (prop?.reference === core_1.ReferenceType.EMBEDDED) {
713
719
  if (prop.object) {
714
- ret.push(this.helper.mapper(prop.fieldNames[0], this.type));
720
+ ret.push(getFieldName(prop.fieldNames[0]));
715
721
  }
716
722
  else {
717
723
  const nest = (prop) => {
718
724
  for (const childProp of Object.values(prop.embeddedProps)) {
719
725
  if (childProp.fieldNames) {
720
- ret.push(this.helper.mapper(childProp.fieldNames[0], this.type));
726
+ ret.push(getFieldName(childProp.fieldNames[0]));
721
727
  }
722
728
  else {
723
729
  nest(childProp);
@@ -729,10 +735,10 @@ class QueryBuilder {
729
735
  return;
730
736
  }
731
737
  if (prop && prop.fieldNames.length > 1) {
732
- ret.push(...prop.fieldNames.map(f => this.helper.mapper(f, this.type)));
738
+ ret.push(...prop.fieldNames.map(f => getFieldName(f)));
733
739
  return;
734
740
  }
735
- ret.push(this.helper.mapper(field, this.type));
741
+ ret.push(getFieldName(field));
736
742
  });
737
743
  const meta = this.mainAlias.metadata;
738
744
  /* istanbul ignore next */
@@ -29,7 +29,11 @@ class QueryBuilderHelper {
29
29
  for (const p of fields) {
30
30
  const [a, f] = this.splitField(p);
31
31
  const prop = this.getProperty(f, a);
32
- if (prop) {
32
+ const fkIdx2 = prop?.fieldNames.findIndex(name => name === f) ?? -1;
33
+ if (fkIdx2 !== -1) {
34
+ parts.push(this.mapper(a !== this.alias ? `${a}.${prop.fieldNames[fkIdx2]}` : prop.fieldNames[fkIdx2], type, value, alias));
35
+ }
36
+ else if (prop) {
33
37
  parts.push(...prop.fieldNames.map(f => this.mapper(a !== this.alias ? `${a}.${f}` : f, type, value, alias)));
34
38
  }
35
39
  else {
@@ -53,9 +57,11 @@ class QueryBuilderHelper {
53
57
  const customExpression = QueryBuilderHelper.isCustomExpression(field, !!alias);
54
58
  const [a, f] = this.splitField(field);
55
59
  const prop = this.getProperty(f, a);
60
+ const fkIdx2 = prop?.fieldNames.findIndex(name => name === f) ?? -1;
61
+ const fkIdx = fkIdx2 === -1 ? 0 : fkIdx2;
56
62
  // embeddable nested path instead of a regular property with table alias, reset alias
57
63
  if (prop?.name === a && prop.embeddedProps[f]) {
58
- return this.alias + '.' + prop.fieldNames[0];
64
+ return this.alias + '.' + prop.fieldNames[fkIdx];
59
65
  }
60
66
  const noPrefix = prop && prop.persist === false;
61
67
  if (prop?.fieldNameRaw) {
@@ -68,16 +74,24 @@ class QueryBuilderHelper {
68
74
  return this.knex.raw(`${prop.formula(alias2)}${as}`);
69
75
  }
70
76
  if (prop?.hasConvertToJSValueSQL) {
71
- const prefixed = this.prefix(field, isTableNameAliasRequired, true);
72
- const valueSQL = prop.customType.convertToJSValueSQL(prefixed, this.platform);
77
+ let valueSQL;
78
+ if (prop.fieldNames.length > 1 && fkIdx !== -1) {
79
+ const fk = prop.targetMeta.getPrimaryProps()[fkIdx];
80
+ const prefixed = this.prefix(field, isTableNameAliasRequired, true, fkIdx);
81
+ valueSQL = fk.customType.convertToJSValueSQL(prefixed, this.platform);
82
+ }
83
+ else {
84
+ const prefixed = this.prefix(field, isTableNameAliasRequired, true);
85
+ valueSQL = prop.customType.convertToJSValueSQL(prefixed, this.platform);
86
+ }
73
87
  if (alias === null) {
74
88
  return this.knex.raw(valueSQL);
75
89
  }
76
- return this.knex.raw(`${valueSQL} as ${this.platform.quoteIdentifier(alias ?? prop.fieldNames[0])}`);
90
+ return this.knex.raw(`${valueSQL} as ${this.platform.quoteIdentifier(alias ?? prop.fieldNames[fkIdx])}`);
77
91
  }
78
92
  // do not wrap custom expressions
79
93
  if (!customExpression) {
80
- ret = this.prefix(field);
94
+ ret = this.prefix(field, false, false, fkIdx);
81
95
  }
82
96
  if (alias) {
83
97
  ret += ' as ' + alias;
@@ -529,11 +543,11 @@ class QueryBuilderHelper {
529
543
  const re = hasAlias ? /[ ?<>=()'"`:]|^\d/ : /[?<>=()'"`:]|^\d/;
530
544
  return !!field.match(re);
531
545
  }
532
- prefix(field, always = false, quote = false) {
546
+ prefix(field, always = false, quote = false, idx) {
533
547
  let ret;
534
548
  if (!this.isPrefixed(field)) {
535
549
  const alias = always ? (quote ? this.alias : this.platform.quoteIdentifier(this.alias)) + '.' : '';
536
- const fieldName = this.fieldName(field, this.alias, always);
550
+ const fieldName = this.fieldName(field, this.alias, always, idx);
537
551
  if (QueryBuilderHelper.isCustomExpression(fieldName)) {
538
552
  return fieldName;
539
553
  }
@@ -542,7 +556,7 @@ class QueryBuilderHelper {
542
556
  else {
543
557
  const [a, ...rest] = field.split('.');
544
558
  const f = rest.join('.');
545
- ret = a + '.' + this.fieldName(f, a);
559
+ ret = a + '.' + this.fieldName(f, a, always, idx);
546
560
  }
547
561
  if (quote) {
548
562
  return this.platform.quoteIdentifier(ret);
@@ -568,7 +582,7 @@ class QueryBuilderHelper {
568
582
  isPrefixed(field) {
569
583
  return !!field.match(/[\w`"[\]]+\./);
570
584
  }
571
- fieldName(field, alias, always) {
585
+ fieldName(field, alias, always, idx = 0) {
572
586
  const prop = this.getProperty(field, alias);
573
587
  if (!prop) {
574
588
  return field;
@@ -586,7 +600,7 @@ class QueryBuilderHelper {
586
600
  return prop.fieldNameRaw;
587
601
  }
588
602
  /* istanbul ignore next */
589
- return prop.fieldNames?.[0] ?? field;
603
+ return prop.fieldNames?.[idx] ?? field;
590
604
  }
591
605
  getProperty(field, alias) {
592
606
  const entityName = this.aliasMap[alias]?.entityName || this.entityName;
@@ -604,7 +618,13 @@ class QueryBuilderHelper {
604
618
  return nest(prop);
605
619
  }
606
620
  }
607
- return meta?.properties[field];
621
+ if (meta) {
622
+ if (meta.properties[field]) {
623
+ return meta.properties[field];
624
+ }
625
+ return meta.relations.find(prop => prop.fieldNames?.some(name => field === name));
626
+ }
627
+ return undefined;
608
628
  }
609
629
  isTableNameAliasRequired(type) {
610
630
  return [enums_1.QueryType.SELECT, enums_1.QueryType.COUNT].includes(type ?? enums_1.QueryType.SELECT);