@mikro-orm/knex 6.0.0-dev.75 → 6.0.0-dev.76

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.
@@ -93,14 +93,14 @@ class AbstractSqlConnection extends core_1.Connection {
93
93
  }
94
94
  const formatted = this.platform.formatQuery(queryOrKnex, params);
95
95
  const sql = this.getSql(queryOrKnex, formatted, logging);
96
- const res = await this.executeQuery(sql, () => {
96
+ return this.executeQuery(sql, async () => {
97
97
  const query = this.getKnex().raw(formatted);
98
98
  if (ctx) {
99
99
  query.transacting(ctx);
100
100
  }
101
- return query;
101
+ const res = await query;
102
+ return this.transformRawResult(res, method);
102
103
  }, { query: queryOrKnex, params, ...logging });
103
- return this.transformRawResult(res, method);
104
104
  }
105
105
  /**
106
106
  * Execute raw SQL queries from file
@@ -55,7 +55,7 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
55
55
  }): ConnectionType;
56
56
  protected extractManyToMany<T>(entityName: string, data: EntityDictionary<T>): EntityData<T>;
57
57
  protected processManyToMany<T extends object>(meta: EntityMetadata<T> | undefined, pks: Primary<T>[], collections: EntityData<T>, clear: boolean, options?: DriverMethodOptions): Promise<void>;
58
- protected updateCollectionDiff<T extends object, O extends object>(meta: EntityMetadata<O>, prop: EntityProperty<T>, pks: Primary<O>[], deleteDiff: Primary<T>[][] | boolean, insertDiff: Primary<T>[][], options?: DriverMethodOptions & {
58
+ protected updateCollectionDiff<T extends object, O extends object>(meta: EntityMetadata<O>, prop: EntityProperty<O>, pks: Primary<O>[], deleteDiff: Primary<T>[][] | boolean, insertDiff: Primary<T>[][], options?: DriverMethodOptions & {
59
59
  ownerSchema?: string;
60
60
  }): Promise<void>;
61
61
  lockPessimistic<T extends object>(entity: T, options: LockOptions): Promise<void>;
@@ -350,7 +350,8 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
350
350
  /* istanbul ignore next */
351
351
  qb.insert(data)
352
352
  .onConflict(uniqueFields.map(p => meta?.properties[p]?.fieldNames[0] ?? p))
353
- .merge(core_1.Utils.keys(data).filter(f => !uniqueFields.includes(f)));
353
+ .merge(core_1.Utils.keys(data).filter(f => !uniqueFields.includes(f)))
354
+ .returning(meta?.comparableProps.filter(p => !p.lazy && !(p.name in data)).map(p => p.name) ?? '*');
354
355
  }
355
356
  else {
356
357
  qb.update(data).where(where);
@@ -370,8 +371,9 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
370
371
  const uniqueFields = core_1.Utils.isPlainObject(where[0]) ? Object.keys(where[0]) : meta.primaryKeys;
371
372
  const qb = this.createQueryBuilder(entityName, options.ctx, 'write', options.convertCustomTypes).withSchema(this.getSchemaName(meta, options));
372
373
  qb.insert(data)
373
- .onConflict(uniqueFields.map(p => meta?.properties[p]?.fieldNames[0] ?? p))
374
- .merge(Object.keys(data[0]).filter(f => !uniqueFields.includes(f)));
374
+ .onConflict(uniqueFields.map(p => meta.properties[p]?.fieldNames[0] ?? p))
375
+ .merge(Object.keys(data[0]).filter(f => !uniqueFields.includes(f)))
376
+ .returning(meta.comparableProps.filter(p => !p.lazy && !(p.name in data[0])).map(p => p.name) ?? '*');
375
377
  return qb.execute('run', false);
376
378
  }
377
379
  const collections = options.processCollections ? data.map(d => this.extractManyToMany(entityName, d)) : [];
package/index.mjs CHANGED
@@ -146,6 +146,7 @@ export const QueryOrderNumeric = mod.QueryOrderNumeric;
146
146
  export const QueryType = mod.QueryType;
147
147
  export const RawQueryFragment = mod.RawQueryFragment;
148
148
  export const ReadOnlyException = mod.ReadOnlyException;
149
+ export const Ref = mod.Ref;
149
150
  export const Reference = mod.Reference;
150
151
  export const ReferenceKind = mod.ReferenceKind;
151
152
  export const ReflectMetadataProvider = mod.ReflectMetadataProvider;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/knex",
3
- "version": "6.0.0-dev.75",
3
+ "version": "6.0.0-dev.76",
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.7.6"
66
+ "@mikro-orm/core": "^5.7.10"
67
67
  },
68
68
  "peerDependencies": {
69
- "@mikro-orm/core": "~6.0.0-dev.75"
69
+ "@mikro-orm/core": "~6.0.0-dev.76"
70
70
  }
71
71
  }
@@ -60,6 +60,7 @@ export declare class QueryBuilder<T extends object = AnyEntity> {
60
60
  private _orderBy;
61
61
  private _groupBy;
62
62
  private _having;
63
+ private _returning?;
63
64
  private _onConflict?;
64
65
  private _limit?;
65
66
  private _offset?;
@@ -92,9 +93,10 @@ export declare class QueryBuilder<T extends object = AnyEntity> {
92
93
  count(field?: string | string[], distinct?: boolean): CountQueryBuilder<T>;
93
94
  join(field: string, alias: string, cond?: QBFilterQuery, type?: 'leftJoin' | 'innerJoin' | 'pivotJoin', path?: string): this;
94
95
  leftJoin(field: string, alias: string, cond?: QBFilterQuery): this;
95
- joinAndSelect(field: string, alias: string, cond?: QBFilterQuery, type?: 'leftJoin' | 'innerJoin' | 'pivotJoin', path?: string): SelectQueryBuilder<T>;
96
- leftJoinAndSelect(field: string, alias: string, cond?: QBFilterQuery): SelectQueryBuilder<T>;
97
- protected getFieldsForJoinedLoad(prop: EntityProperty<T>, alias: string): Field<T>[];
96
+ joinAndSelect(field: string, alias: string, cond?: QBFilterQuery, type?: 'leftJoin' | 'innerJoin' | 'pivotJoin', path?: string, fields?: string[]): SelectQueryBuilder<T>;
97
+ leftJoinAndSelect(field: string, alias: string, cond?: QBFilterQuery, fields?: string[]): SelectQueryBuilder<T>;
98
+ innerJoinAndSelect(field: string, alias: string, cond?: QBFilterQuery, fields?: string[]): SelectQueryBuilder<T>;
99
+ protected getFieldsForJoinedLoad(prop: EntityProperty<T>, alias: string, explicitFields?: string[]): Field<T>[];
98
100
  withSubQuery(subQuery: Knex.QueryBuilder, alias: string): this;
99
101
  where(cond: QBFilterQuery<T>, operator?: keyof typeof GroupOperator): this;
100
102
  where(cond: string, params?: any[], operator?: keyof typeof GroupOperator): this;
@@ -108,6 +110,7 @@ export declare class QueryBuilder<T extends object = AnyEntity> {
108
110
  onConflict(fields?: Field<T> | Field<T>[]): this;
109
111
  ignore(): this;
110
112
  merge(data?: EntityData<T> | Field<T>[]): this;
113
+ returning(fields?: Field<T> | Field<T>[]): this;
111
114
  /**
112
115
  * @internal
113
116
  */
@@ -144,12 +144,12 @@ class QueryBuilder {
144
144
  leftJoin(field, alias, cond = {}) {
145
145
  return this.join(field, alias, cond, 'leftJoin');
146
146
  }
147
- joinAndSelect(field, alias, cond = {}, type = 'innerJoin', path) {
147
+ joinAndSelect(field, alias, cond = {}, type = 'innerJoin', path, fields) {
148
148
  if (!this.type) {
149
149
  this.select('*');
150
150
  }
151
151
  const prop = this.joinReference(field, alias, cond, type, path);
152
- this.addSelect(this.getFieldsForJoinedLoad(prop, alias));
152
+ this.addSelect(this.getFieldsForJoinedLoad(prop, alias, fields));
153
153
  const [fromAlias] = this.helper.splitField(field);
154
154
  const populate = this._joinedProps.get(fromAlias);
155
155
  const item = { field: prop.name, strategy: core_1.LoadStrategy.JOINED, children: [] };
@@ -162,13 +162,16 @@ class QueryBuilder {
162
162
  this._joinedProps.set(alias, item);
163
163
  return this;
164
164
  }
165
- leftJoinAndSelect(field, alias, cond = {}) {
166
- return this.joinAndSelect(field, alias, cond, 'leftJoin');
165
+ leftJoinAndSelect(field, alias, cond = {}, fields) {
166
+ return this.joinAndSelect(field, alias, cond, 'leftJoin', undefined, fields);
167
167
  }
168
- getFieldsForJoinedLoad(prop, alias) {
168
+ innerJoinAndSelect(field, alias, cond = {}, fields) {
169
+ return this.joinAndSelect(field, alias, cond, 'innerJoin', undefined, fields);
170
+ }
171
+ getFieldsForJoinedLoad(prop, alias, explicitFields) {
169
172
  const fields = [];
170
173
  prop.targetMeta.props
171
- .filter(prop => this.platform.shouldHaveColumn(prop, this._populate))
174
+ .filter(prop => explicitFields ? explicitFields.includes(prop.name) || prop.primary : this.platform.shouldHaveColumn(prop, this._populate))
172
175
  .forEach(prop => fields.push(...this.driver.mapPropToFieldNames(this, prop, alias)));
173
176
  return fields;
174
177
  }
@@ -283,6 +286,10 @@ class QueryBuilder {
283
286
  this._onConflict[this._onConflict.length - 1].merge = data;
284
287
  return this;
285
288
  }
289
+ returning(fields) {
290
+ this._returning = fields != null ? core_1.Utils.asArray(fields) : fields;
291
+ return this;
292
+ }
286
293
  /**
287
294
  * @internal
288
295
  */
@@ -390,7 +397,7 @@ class QueryBuilder {
390
397
  if (this.lockMode) {
391
398
  this.helper.getLockSQL(qb, this.lockMode, this.lockTables);
392
399
  }
393
- this.helper.finalize(this.type ?? enums_1.QueryType.SELECT, qb, this.mainAlias.metadata, this._data);
400
+ this.helper.finalize(this.type ?? enums_1.QueryType.SELECT, qb, this.mainAlias.metadata, this._data, this._returning);
394
401
  return qb;
395
402
  }
396
403
  /**
@@ -585,7 +592,7 @@ class QueryBuilder {
585
592
  // clone array/object properties
586
593
  const properties = [
587
594
  'flags', '_populate', '_populateWhere', '_populateMap', '_joins', '_joinedProps', '_cond', '_data', '_orderBy',
588
- '_schema', '_indexHint', '_cache', 'subQueries', 'lockMode', 'lockTables',
595
+ '_schema', '_indexHint', '_cache', 'subQueries', 'lockMode', 'lockTables', '_groupBy', '_having', '_returning',
589
596
  ];
590
597
  properties.forEach(prop => qb[prop] = core_1.Utils.copy(this[prop]));
591
598
  /* istanbul ignore else */
@@ -47,7 +47,7 @@ export declare class QueryBuilderHelper {
47
47
  private getOperatorReplacement;
48
48
  getQueryOrder(type: QueryType, orderBy: FlatQueryOrderMap | FlatQueryOrderMap[], populate: Dictionary<string>): string;
49
49
  getQueryOrderFromObject(type: QueryType, orderBy: FlatQueryOrderMap, populate: Dictionary<string>): string;
50
- finalize(type: QueryType, qb: Knex.QueryBuilder, meta?: EntityMetadata, data?: Dictionary): void;
50
+ finalize(type: QueryType, qb: Knex.QueryBuilder, meta?: EntityMetadata, data?: Dictionary, returning?: Field<any>[]): void;
51
51
  splitField<T>(field: EntityKey<T>, greedyAlias?: boolean): [string, EntityKey<T>];
52
52
  getLockSQL(qb: Knex.QueryBuilder, lockMode: LockMode, lockTables?: string[]): void;
53
53
  updateVersionProperty(qb: Knex.QueryBuilder, data: Dictionary): void;
@@ -455,17 +455,23 @@ class QueryBuilderHelper {
455
455
  });
456
456
  return ret.join(', ');
457
457
  }
458
- finalize(type, qb, meta, data) {
458
+ finalize(type, qb, meta, data, returning) {
459
459
  if (!meta || !data || !this.platform.usesReturningStatement()) {
460
460
  return;
461
461
  }
462
+ // always respect explicit returning hint
463
+ if (returning && returning.length > 0) {
464
+ qb.returning(returning.map(field => this.mapper(field, type)));
465
+ return;
466
+ }
462
467
  if (type === enums_1.QueryType.INSERT) {
463
468
  const returningProps = meta.hydrateProps
464
- .filter(prop => prop.persist !== false && ((prop.primary && prop.autoincrement) || prop.defaultRaw))
465
- .filter(prop => !(prop.name in data) || core_1.Utils.isRawSql(data[prop.name]));
469
+ .filter(prop => prop.returning || (prop.persist !== false && ((prop.primary && prop.autoincrement) || prop.defaultRaw)))
470
+ .filter(prop => !(prop.name in data));
466
471
  if (returningProps.length > 0) {
467
472
  qb.returning(core_1.Utils.flatten(returningProps.map(prop => prop.fieldNames)));
468
473
  }
474
+ return;
469
475
  }
470
476
  if (type === enums_1.QueryType.UPDATE) {
471
477
  const returningProps = meta.hydrateProps.filter(prop => core_1.Utils.isRawSql(data[prop.name]));
package/typings.d.ts CHANGED
@@ -124,7 +124,8 @@ export interface IQueryBuilder<T> {
124
124
  join(field: string, alias: string, cond?: QBFilterQuery, type?: 'leftJoin' | 'innerJoin' | 'pivotJoin', path?: string): this;
125
125
  leftJoin(field: string, alias: string, cond?: QBFilterQuery): this;
126
126
  joinAndSelect(field: string, alias: string, cond?: QBFilterQuery): this;
127
- leftJoinAndSelect(field: string, alias: string, cond?: QBFilterQuery): this;
127
+ leftJoinAndSelect(field: string, alias: string, cond?: QBFilterQuery, fields?: string[]): this;
128
+ innerJoinAndSelect(field: string, alias: string, cond?: QBFilterQuery, fields?: string[]): this;
128
129
  withSubQuery(subQuery: Knex.QueryBuilder, alias: string): this;
129
130
  where(cond: QBFilterQuery<T>, operator?: keyof typeof GroupOperator): this;
130
131
  where(cond: string, params?: any[], operator?: keyof typeof GroupOperator): this;