@mikro-orm/knex 6.0.0-dev.124 → 6.0.0-dev.126

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.
@@ -117,12 +117,14 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
117
117
  }
118
118
  async wrapVirtualExpressionInSubquery(meta, expression, where, options, type) {
119
119
  const qb = this.createQueryBuilder(meta.className, options?.ctx, options.connectionType, options.convertCustomTypes)
120
- .limit(options?.limit, options?.offset)
121
120
  .indexHint(options.indexHint)
122
121
  .comment(options.comments)
123
122
  .hintComment(options.hintComments);
124
- if (options.orderBy) {
125
- qb.orderBy(options.orderBy);
123
+ if (type !== query_1.QueryType.COUNT) {
124
+ qb.limit(options?.limit, options?.offset);
125
+ if (options.orderBy) {
126
+ qb.orderBy(options.orderBy);
127
+ }
126
128
  }
127
129
  qb.where(where);
128
130
  const kqb = qb.getKnexQuery().clear('select');
@@ -709,7 +711,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
709
711
  joinedProps(meta, populate) {
710
712
  return populate.filter(p => {
711
713
  const prop = meta.properties[p.field] || {};
712
- return (p.strategy || prop.strategy || this.config.get('loadStrategy')) === core_1.LoadStrategy.JOINED && prop.kind !== core_1.ReferenceKind.SCALAR;
714
+ return (p.strategy || prop.strategy || this.config.get('loadStrategy')) === core_1.LoadStrategy.JOINED && ![core_1.ReferenceKind.SCALAR, core_1.ReferenceKind.EMBEDDED].includes(prop.kind);
713
715
  });
714
716
  }
715
717
  /**
@@ -771,7 +773,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
771
773
  const tableAlias = qb.getNextAlias(prop.name);
772
774
  const field = parentTableAlias ? `${parentTableAlias}.${prop.name}` : prop.name;
773
775
  const path = parentJoinPath ? `${parentJoinPath}.${prop.name}` : `${meta.name}.${prop.name}`;
774
- qb.join(field, tableAlias, {}, 'leftJoin', path);
776
+ qb.join(field, tableAlias, {}, query_1.JoinType.leftJoin, path);
775
777
  const childExplicitFields = explicitFields?.filter(f => core_1.Utils.isPlainObject(f)).map(o => o[prop.name])[0] || [];
776
778
  explicitFields?.forEach(f => {
777
779
  if (typeof f === 'string' && f.startsWith(`${prop.name}.`)) {
package/index.mjs CHANGED
@@ -99,6 +99,7 @@ export const Index = mod.Index;
99
99
  export const IntegerType = mod.IntegerType;
100
100
  export const InvalidFieldNameException = mod.InvalidFieldNameException;
101
101
  export const IsolationLevel = mod.IsolationLevel;
102
+ export const JoinType = mod.JoinType;
102
103
  export const JsonProperty = mod.JsonProperty;
103
104
  export const JsonType = mod.JsonType;
104
105
  export const Knex = mod.Knex;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/knex",
3
- "version": "6.0.0-dev.124",
3
+ "version": "6.0.0-dev.126",
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.9.0"
66
+ "@mikro-orm/core": "^5.9.2"
67
67
  },
68
68
  "peerDependencies": {
69
- "@mikro-orm/core": "6.0.0-dev.124"
69
+ "@mikro-orm/core": "6.0.0-dev.126"
70
70
  }
71
71
  }
@@ -130,11 +130,11 @@ class ObjectCriteriaNode extends CriteriaNode_1.CriteriaNode {
130
130
  const operator = core_1.Utils.isPlainObject(this.payload) && Object.keys(this.payload).every(k => core_1.Utils.isOperator(k, false));
131
131
  const field = `${alias}.${this.prop.name}`;
132
132
  if (this.prop.kind === core_1.ReferenceKind.MANY_TO_MANY && (scalar || operator)) {
133
- qb.join(field, nestedAlias, undefined, 'pivotJoin', this.getPath());
133
+ qb.join(field, nestedAlias, undefined, enums_1.JoinType.pivotJoin, this.getPath());
134
134
  }
135
135
  else {
136
136
  const prev = qb._fields?.slice();
137
- qb.join(field, nestedAlias, undefined, 'leftJoin', this.getPath());
137
+ qb.join(field, nestedAlias, undefined, enums_1.JoinType.leftJoin, this.getPath());
138
138
  qb._fields = prev;
139
139
  }
140
140
  return nestedAlias;
@@ -2,7 +2,7 @@
2
2
  import { inspect } from 'util';
3
3
  import type { Knex } from 'knex';
4
4
  import { type AnyEntity, type ConnectionType, type Dictionary, type EntityData, type EntityName, type EntityProperty, type FlushMode, type GroupOperator, LockMode, type LoggingOptions, type MetadataStorage, type ObjectQuery, PopulateHint, type PopulateOptions, type QBFilterQuery, type QBQueryOrderMap, QueryFlag, type QueryResult, type RequiredEntityData } from '@mikro-orm/core';
5
- import { QueryType } from './enums';
5
+ import { QueryType, JoinType } from './enums';
6
6
  import type { AbstractSqlDriver } from '../AbstractSqlDriver';
7
7
  import { type Alias, QueryBuilderHelper } from './QueryBuilderHelper';
8
8
  import type { SqlEntityManager } from '../SqlEntityManager';
@@ -96,12 +96,16 @@ export declare class QueryBuilder<T extends object = AnyEntity> {
96
96
  delete(cond?: QBFilterQuery): DeleteQueryBuilder<T>;
97
97
  truncate(): TruncateQueryBuilder<T>;
98
98
  count(field?: string | string[], distinct?: boolean): CountQueryBuilder<T>;
99
- join(field: string | Knex.QueryBuilder | QueryBuilder<any>, alias: string, cond?: QBFilterQuery, type?: 'leftJoin' | 'innerJoin' | 'pivotJoin', path?: string, schema?: string): this;
99
+ join(field: string | Knex.QueryBuilder | QueryBuilder<any>, alias: string, cond?: QBFilterQuery, type?: JoinType, path?: string, schema?: string): this;
100
100
  innerJoin(field: string | Knex.QueryBuilder | QueryBuilder<any>, alias: string, cond?: QBFilterQuery, schema?: string): this;
101
+ innerJoinLateral(field: string | Knex.QueryBuilder | QueryBuilder<any>, alias: string, cond?: QBFilterQuery, schema?: string): this;
101
102
  leftJoin(field: string | Knex.QueryBuilder | QueryBuilder<any>, alias: string, cond?: QBFilterQuery, schema?: string): this;
102
- joinAndSelect(field: string | [field: string, qb: Knex.QueryBuilder | QueryBuilder<any>], alias: string, cond?: QBFilterQuery, type?: 'leftJoin' | 'innerJoin' | 'pivotJoin', path?: string, fields?: string[], schema?: string): SelectQueryBuilder<T>;
103
+ leftJoinLateral(field: string | Knex.QueryBuilder | QueryBuilder<any>, alias: string, cond?: QBFilterQuery, schema?: string): this;
104
+ joinAndSelect(field: string | [field: string, qb: Knex.QueryBuilder | QueryBuilder<any>], alias: string, cond?: QBFilterQuery, type?: JoinType, path?: string, fields?: string[], schema?: string): SelectQueryBuilder<T>;
103
105
  leftJoinAndSelect(field: string | [field: string, qb: Knex.QueryBuilder | QueryBuilder<any>], alias: string, cond?: QBFilterQuery, fields?: string[], schema?: string): SelectQueryBuilder<T>;
106
+ leftJoinLateralAndSelect(field: string | [field: string, qb: Knex.QueryBuilder | QueryBuilder<any>], alias: string, cond?: QBFilterQuery, fields?: string[], schema?: string): SelectQueryBuilder<T>;
104
107
  innerJoinAndSelect(field: string | [field: string, qb: Knex.QueryBuilder | QueryBuilder<any>], alias: string, cond?: QBFilterQuery, fields?: string[], schema?: string): SelectQueryBuilder<T>;
108
+ innerJoinLateralAndSelect(field: string | [field: string, qb: Knex.QueryBuilder | QueryBuilder<any>], alias: string, cond?: QBFilterQuery, fields?: string[], schema?: string): SelectQueryBuilder<T>;
105
109
  protected getFieldsForJoinedLoad(prop: EntityProperty<T>, alias: string, explicitFields?: string[]): Field<T>[];
106
110
  withSubQuery(subQuery: Knex.QueryBuilder, alias: string): this;
107
111
  where(cond: QBFilterQuery<T>, operator?: keyof typeof GroupOperator): this;
@@ -154,18 +154,25 @@ class QueryBuilder {
154
154
  }
155
155
  return this.init(enums_1.QueryType.COUNT);
156
156
  }
157
- join(field, alias, cond = {}, type = 'innerJoin', path, schema) {
157
+ join(field, alias, cond = {}, type = enums_1.JoinType.innerJoin, path, schema) {
158
158
  this.joinReference(field, alias, cond, type, path, schema);
159
159
  return this;
160
160
  }
161
161
  innerJoin(field, alias, cond = {}, schema) {
162
- this.join(field, alias, cond, 'innerJoin', undefined, schema);
162
+ this.join(field, alias, cond, enums_1.JoinType.innerJoin, undefined, schema);
163
+ return this;
164
+ }
165
+ innerJoinLateral(field, alias, cond = {}, schema) {
166
+ this.join(field, alias, cond, enums_1.JoinType.innerJoinLateral, undefined, schema);
163
167
  return this;
164
168
  }
165
169
  leftJoin(field, alias, cond = {}, schema) {
166
- return this.join(field, alias, cond, 'leftJoin', undefined, schema);
170
+ return this.join(field, alias, cond, enums_1.JoinType.leftJoin, undefined, schema);
171
+ }
172
+ leftJoinLateral(field, alias, cond = {}, schema) {
173
+ return this.join(field, alias, cond, enums_1.JoinType.leftJoinLateral, undefined, schema);
167
174
  }
168
- joinAndSelect(field, alias, cond = {}, type = 'innerJoin', path, fields, schema) {
175
+ joinAndSelect(field, alias, cond = {}, type = enums_1.JoinType.innerJoin, path, fields, schema) {
169
176
  if (!this.type) {
170
177
  this.select('*');
171
178
  }
@@ -174,7 +181,7 @@ class QueryBuilder {
174
181
  subquery = field[1] instanceof QueryBuilder ? field[1].getFormattedQuery() : field[1].toString();
175
182
  field = field[0];
176
183
  }
177
- const prop = this.joinReference(field, alias, cond, type, path, schema);
184
+ const prop = this.joinReference(field, alias, cond, type, path, schema, subquery);
178
185
  const [fromAlias] = this.helper.splitField(field);
179
186
  if (subquery) {
180
187
  this._joins[`${fromAlias}.${prop.name}#${alias}`].subquery = subquery;
@@ -192,10 +199,16 @@ class QueryBuilder {
192
199
  return this;
193
200
  }
194
201
  leftJoinAndSelect(field, alias, cond = {}, fields, schema) {
195
- return this.joinAndSelect(field, alias, cond, 'leftJoin', undefined, fields, schema);
202
+ return this.joinAndSelect(field, alias, cond, enums_1.JoinType.leftJoin, undefined, fields, schema);
203
+ }
204
+ leftJoinLateralAndSelect(field, alias, cond = {}, fields, schema) {
205
+ return this.joinAndSelect(field, alias, cond, enums_1.JoinType.leftJoinLateral, undefined, fields, schema);
196
206
  }
197
207
  innerJoinAndSelect(field, alias, cond = {}, fields, schema) {
198
- return this.joinAndSelect(field, alias, cond, 'innerJoin', undefined, fields, schema);
208
+ return this.joinAndSelect(field, alias, cond, enums_1.JoinType.innerJoin, undefined, fields, schema);
209
+ }
210
+ innerJoinLateralAndSelect(field, alias, cond = {}, fields, schema) {
211
+ return this.joinAndSelect(field, alias, cond, enums_1.JoinType.innerJoinLateral, undefined, fields, schema);
199
212
  }
200
213
  getFieldsForJoinedLoad(prop, alias, explicitFields) {
201
214
  const fields = [];
@@ -685,7 +698,7 @@ class QueryBuilder {
685
698
  }
686
699
  return qb;
687
700
  }
688
- joinReference(field, alias, cond, type, path, schema) {
701
+ joinReference(field, alias, cond, type, path, schema, subquery) {
689
702
  this.ensureNotFinalized();
690
703
  if (typeof field === 'object') {
691
704
  const prop = {
@@ -708,6 +721,9 @@ class QueryBuilder {
708
721
  };
709
722
  return prop;
710
723
  }
724
+ if (!subquery && type.includes('lateral')) {
725
+ throw new Error(`Lateral join can be used only with a sub-query.`);
726
+ }
711
727
  const [fromAlias, fromField] = this.helper.splitField(field);
712
728
  const q = (str) => `'${str}'`;
713
729
  if (!this._aliases[fromAlias]) {
@@ -735,7 +751,7 @@ class QueryBuilder {
735
751
  }
736
752
  else if (prop.kind === core_1.ReferenceKind.MANY_TO_MANY) {
737
753
  let pivotAlias = alias;
738
- if (type !== 'pivotJoin') {
754
+ if (type !== enums_1.JoinType.pivotJoin) {
739
755
  const oldPivotAlias = this.getAliasForJoinPath(path + '[pivot]');
740
756
  pivotAlias = oldPivotAlias ?? this.getNextAlias(prop.pivotEntity);
741
757
  aliasedName = `${fromAlias}.${prop.name}#${pivotAlias}`;
@@ -948,7 +964,7 @@ class QueryBuilder {
948
964
  const prop = meta.properties[fromField];
949
965
  const alias = this.getNextAlias(prop.pivotEntity ?? prop.type);
950
966
  const aliasedName = `${fromAlias}.${prop.name}#${alias}`;
951
- this._joins[aliasedName] = this.helper.joinOneToReference(prop, this.mainAlias.aliasName, alias, 'leftJoin');
967
+ this._joins[aliasedName] = this.helper.joinOneToReference(prop, this.mainAlias.aliasName, alias, enums_1.JoinType.leftJoin);
952
968
  this._populateMap[aliasedName] = this._joins[aliasedName].alias;
953
969
  }
954
970
  });
@@ -1,6 +1,6 @@
1
1
  import type { Knex } from 'knex';
2
2
  import { type Dictionary, type EntityData, type EntityKey, type EntityMetadata, type EntityProperty, type FlatQueryOrderMap, LockMode, type QBFilterQuery } from '@mikro-orm/core';
3
- import { QueryType } from './enums';
3
+ import { JoinType, QueryType } from './enums';
4
4
  import type { Field, JoinOptions } from '../typings';
5
5
  import type { AbstractSqlDriver } from '../AbstractSqlDriver';
6
6
  /**
@@ -19,9 +19,9 @@ export declare class QueryBuilderHelper {
19
19
  mapper(field: string | Knex.Raw, type?: QueryType): string;
20
20
  mapper(field: string | Knex.Raw, type?: QueryType, value?: any, alias?: string | null): string;
21
21
  processData(data: Dictionary, convertCustomTypes: boolean, multi?: boolean): any;
22
- joinOneToReference(prop: EntityProperty, ownerAlias: string, alias: string, type: 'leftJoin' | 'innerJoin' | 'pivotJoin', cond?: Dictionary, schema?: string): JoinOptions;
23
- joinManyToOneReference(prop: EntityProperty, ownerAlias: string, alias: string, type: 'leftJoin' | 'innerJoin' | 'pivotJoin', cond?: Dictionary, schema?: string): JoinOptions;
24
- joinManyToManyReference(prop: EntityProperty, ownerAlias: string, alias: string, pivotAlias: string, type: 'leftJoin' | 'innerJoin' | 'pivotJoin', cond: Dictionary, path: string, schema?: string): Dictionary<JoinOptions>;
22
+ joinOneToReference(prop: EntityProperty, ownerAlias: string, alias: string, type: JoinType, cond?: Dictionary, schema?: string): JoinOptions;
23
+ joinManyToOneReference(prop: EntityProperty, ownerAlias: string, alias: string, type: JoinType, cond?: Dictionary, schema?: string): JoinOptions;
24
+ joinManyToManyReference(prop: EntityProperty, ownerAlias: string, alias: string, pivotAlias: string, type: JoinType, cond: Dictionary, path: string, schema?: string): Dictionary<JoinOptions>;
25
25
  processJoins(qb: Knex.QueryBuilder, joins: Dictionary<JoinOptions>, schema?: string): void;
26
26
  private processJoinClause;
27
27
  private wrapQueryGroup;
@@ -165,7 +165,7 @@ class QueryBuilderHelper {
165
165
  path: path.endsWith('[pivot]') ? path : `${path}[pivot]`,
166
166
  },
167
167
  };
168
- if (type === 'pivotJoin') {
168
+ if (type === enums_1.JoinType.pivotJoin) {
169
169
  return ret;
170
170
  }
171
171
  const prop2 = prop.owner ? pivotMeta.relations[1] : pivotMeta.relations[0];
@@ -178,7 +178,7 @@ class QueryBuilderHelper {
178
178
  processJoins(qb, joins, schema) {
179
179
  Object.values(joins).forEach(join => {
180
180
  let table = join.table;
181
- const method = join.type === 'innerJoin' ? 'inner join' : 'left join';
181
+ const method = join.type === enums_1.JoinType.pivotJoin ? 'left join' : join.type;
182
182
  const conditions = [];
183
183
  const params = [];
184
184
  schema = join.schema && join.schema !== '*' ? join.schema : schema;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ScalarCriteriaNode = void 0;
4
4
  const core_1 = require("@mikro-orm/core");
5
5
  const CriteriaNode_1 = require("./CriteriaNode");
6
+ const enums_1 = require("./enums");
6
7
  /**
7
8
  * @internal
8
9
  */
@@ -13,7 +14,7 @@ class ScalarCriteriaNode extends CriteriaNode_1.CriteriaNode {
13
14
  const parentPath = this.parent.getPath(); // the parent is always there, otherwise `shouldJoin` would return `false`
14
15
  const nestedAlias = qb.getAliasForJoinPath(path) || qb.getNextAlias(this.prop?.pivotTable ?? this.entityName);
15
16
  const field = `${alias}.${this.prop.name}`;
16
- const type = this.prop.kind === core_1.ReferenceKind.MANY_TO_MANY ? 'pivotJoin' : 'leftJoin';
17
+ const type = this.prop.kind === core_1.ReferenceKind.MANY_TO_MANY ? enums_1.JoinType.pivotJoin : enums_1.JoinType.leftJoin;
17
18
  qb.join(field, nestedAlias, undefined, type, path);
18
19
  // select the owner as virtual property when joining from 1:1 inverse side, but only if the parent is root entity
19
20
  if (this.prop.kind === core_1.ReferenceKind.ONE_TO_ONE && !parentPath.includes('.')) {
package/query/enums.d.ts CHANGED
@@ -6,3 +6,10 @@ export declare enum QueryType {
6
6
  UPDATE = "UPDATE",
7
7
  DELETE = "DELETE"
8
8
  }
9
+ export declare enum JoinType {
10
+ leftJoin = "left join",
11
+ innerJoin = "inner join",
12
+ pivotJoin = "pivot join",
13
+ innerJoinLateral = "inner join lateral",
14
+ leftJoinLateral = "left join lateral"
15
+ }
package/query/enums.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.QueryType = void 0;
3
+ exports.JoinType = exports.QueryType = void 0;
4
4
  var QueryType;
5
5
  (function (QueryType) {
6
6
  QueryType["TRUNCATE"] = "TRUNCATE";
@@ -10,3 +10,11 @@ var QueryType;
10
10
  QueryType["UPDATE"] = "UPDATE";
11
11
  QueryType["DELETE"] = "DELETE";
12
12
  })(QueryType || (exports.QueryType = QueryType = {}));
13
+ var JoinType;
14
+ (function (JoinType) {
15
+ JoinType["leftJoin"] = "left join";
16
+ JoinType["innerJoin"] = "inner join";
17
+ JoinType["pivotJoin"] = "pivot join";
18
+ JoinType["innerJoinLateral"] = "inner join lateral";
19
+ JoinType["leftJoinLateral"] = "left join lateral";
20
+ })(JoinType || (exports.JoinType = JoinType = {}));
package/typings.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { Knex } from 'knex';
2
2
  import type { CheckCallback, Dictionary, EntityProperty, GroupOperator, RawQueryFragment, QBFilterQuery, QueryOrderMap, Type } from '@mikro-orm/core';
3
- import type { QueryType } from './query/enums';
3
+ import type { JoinType, QueryType } from './query/enums';
4
4
  import type { DatabaseSchema, DatabaseTable } from './schema';
5
5
  export interface Table {
6
6
  table_name: string;
@@ -15,7 +15,7 @@ export type Field<T> = AnyString | keyof T | RawQueryFragment | KnexStringRef |
15
15
  export interface JoinOptions {
16
16
  table: string;
17
17
  schema?: string;
18
- type: 'leftJoin' | 'innerJoin' | 'pivotJoin';
18
+ type: JoinType;
19
19
  alias: string;
20
20
  ownerAlias: string;
21
21
  inverseAlias?: string;
@@ -125,7 +125,7 @@ export interface IQueryBuilder<T> {
125
125
  delete(cond?: QBFilterQuery): this;
126
126
  truncate(): this;
127
127
  count(field?: string | string[], distinct?: boolean): this;
128
- join(field: string, alias: string, cond?: QBFilterQuery, type?: 'leftJoin' | 'innerJoin' | 'pivotJoin', path?: string): this;
128
+ join(field: string, alias: string, cond?: QBFilterQuery, type?: JoinType, path?: string): this;
129
129
  leftJoin(field: string, alias: string, cond?: QBFilterQuery): this;
130
130
  joinAndSelect(field: string, alias: string, cond?: QBFilterQuery): this;
131
131
  leftJoinAndSelect(field: string, alias: string, cond?: QBFilterQuery, fields?: string[]): this;