@mikro-orm/knex 6.0.0-dev.45 → 6.0.0-dev.46

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.
@@ -124,7 +124,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
124
124
  qb.where(where);
125
125
  const kqb = qb.getKnexQuery().clear('select');
126
126
  if (type === query_1.QueryType.COUNT) {
127
- kqb.select(qb.raw('count(*) as count'));
127
+ kqb.select(this.connection.getKnex().raw('count(*) as count'));
128
128
  }
129
129
  else { // select
130
130
  kqb.select('*');
@@ -294,9 +294,10 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
294
294
  return '(' + (keys.join(', ') || 'default') + ')';
295
295
  }).join(', ');
296
296
  }
297
- if (this.platform.usesReturningStatement()) {
298
- /* istanbul ignore next */
299
- const returningProps = meta.hydrateProps.filter(prop => prop.persist !== false && (prop.primary || prop.defaultRaw));
297
+ if (meta && this.platform.usesReturningStatement()) {
298
+ const returningProps = meta.hydrateProps
299
+ .filter(prop => prop.persist !== false && ((prop.primary && prop.autoincrement) || prop.defaultRaw))
300
+ .filter(prop => !(prop.name in data[0]) || core_1.Utils.isRawSql(data[0][prop.name]));
300
301
  const returningFields = core_1.Utils.flatten(returningProps.map(prop => prop.fieldNames));
301
302
  /* istanbul ignore next */
302
303
  sql += returningFields.length > 0 ? ` returning ${returningFields.map(field => this.platform.quoteIdentifier(field)).join(', ')}` : '';
@@ -363,7 +364,15 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
363
364
  }
364
365
  const collections = options.processCollections ? data.map(d => this.extractManyToMany(entityName, d)) : [];
365
366
  const keys = new Set();
366
- data.forEach(row => core_1.Utils.keys(row).forEach(k => keys.add(k)));
367
+ const returning = new Set();
368
+ data.forEach(row => {
369
+ core_1.Utils.keys(row).forEach(k => {
370
+ keys.add(k);
371
+ if (core_1.Utils.isRawSql(row[k])) {
372
+ returning.add(k);
373
+ }
374
+ });
375
+ });
367
376
  const pkCond = core_1.Utils.flatten(meta.primaryKeys.map(pk => meta.properties[pk].fieldNames)).map(pk => `${this.platform.quoteIdentifier(pk)} = ?`).join(' and ');
368
377
  const params = [];
369
378
  let sql = `update ${this.getTableName(meta, options)} set `;
@@ -423,6 +432,11 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
423
432
  return '?';
424
433
  });
425
434
  sql += ` in (${conds.join(', ')})`;
435
+ if (this.platform.usesReturningStatement() && returning.size > 0) {
436
+ const returningFields = core_1.Utils.flatten([...returning].map(prop => meta.properties[prop].fieldNames));
437
+ /* istanbul ignore next */
438
+ sql += returningFields.length > 0 ? ` returning ${returningFields.map(field => this.platform.quoteIdentifier(field)).join(', ')}` : '';
439
+ }
426
440
  const res = await this.rethrow(this.execute(sql, params, 'run', options.ctx));
427
441
  for (let i = 0; i < collections.length; i++) {
428
442
  await this.processManyToMany(meta, where[i], collections[i], false, options);
@@ -612,7 +626,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
612
626
  const aliased = qb.ref(tableAlias ? `${tableAlias}__${prop.fieldNames[0]}` : prop.fieldNames[0]).toString();
613
627
  if (prop.customType?.convertToJSValueSQL && tableAlias) {
614
628
  const prefixed = qb.ref(prop.fieldNames[0]).withSchema(tableAlias).toString();
615
- return [qb.raw(prop.customType.convertToJSValueSQL(prefixed, this.platform) + ' as ' + aliased).toString()];
629
+ return [prop.customType.convertToJSValueSQL(prefixed, this.platform) + ' as ' + aliased];
616
630
  }
617
631
  if (prop.formula) {
618
632
  const alias = qb.ref(tableAlias ?? qb.alias).toString();
@@ -27,6 +27,9 @@ class AbstractSqlPlatform extends core_1.Platform {
27
27
  return new schema_1.SqlSchemaGenerator(em ?? driver);
28
28
  }
29
29
  quoteValue(value) {
30
+ if (core_1.Utils.isRawSql(value)) {
31
+ return this.formatQuery(value.sql, value.params ?? []);
32
+ }
30
33
  if (this.isRaw(value)) {
31
34
  return value;
32
35
  }
@@ -16,10 +16,6 @@ export declare class SqlEntityManager<D extends AbstractSqlDriver = AbstractSqlD
16
16
  * Shortcut for `createQueryBuilder()`
17
17
  */
18
18
  qb<T extends object>(entityName: EntityName<T>, alias?: string, type?: ConnectionType): QueryBuilder<T>;
19
- /**
20
- * Creates raw SQL query that won't be escaped when used as a parameter.
21
- */
22
- raw<R = Knex.Raw>(sql: string, bindings?: Knex.RawBinding[] | Knex.ValueDict): R;
23
19
  /**
24
20
  * Returns configured knex instance.
25
21
  */
@@ -20,14 +20,6 @@ class SqlEntityManager extends core_1.EntityManager {
20
20
  qb(entityName, alias, type) {
21
21
  return this.createQueryBuilder(entityName, alias, type);
22
22
  }
23
- /**
24
- * Creates raw SQL query that won't be escaped when used as a parameter.
25
- */
26
- raw(sql, bindings = []) {
27
- const raw = this.getKnex().raw(sql, bindings);
28
- raw.__raw = true; // tag it as there is now way to check via `instanceof`
29
- return raw;
30
- }
31
23
  /**
32
24
  * Returns configured knex instance.
33
25
  */
package/index.mjs CHANGED
@@ -138,6 +138,7 @@ export const QueryOperator = mod.QueryOperator;
138
138
  export const QueryOrder = mod.QueryOrder;
139
139
  export const QueryOrderNumeric = mod.QueryOrderNumeric;
140
140
  export const QueryType = mod.QueryType;
141
+ export const RawQueryFragment = mod.RawQueryFragment;
141
142
  export const ReadOnlyException = mod.ReadOnlyException;
142
143
  export const Reference = mod.Reference;
143
144
  export const ReferenceKind = mod.ReferenceKind;
@@ -187,6 +188,7 @@ export const equals = mod.equals;
187
188
  export const expr = mod.expr;
188
189
  export const helper = mod.helper;
189
190
  export const knex = mod.knex;
191
+ export const raw = mod.raw;
190
192
  export const ref = mod.ref;
191
193
  export const rel = mod.rel;
192
194
  export const serialize = mod.serialize;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/knex",
3
- "version": "6.0.0-dev.45",
3
+ "version": "6.0.0-dev.46",
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,6 +66,6 @@
66
66
  "@mikro-orm/core": "^5.6.12"
67
67
  },
68
68
  "peerDependencies": {
69
- "@mikro-orm/core": "~6.0.0-dev.45"
69
+ "@mikro-orm/core": "~6.0.0-dev.46"
70
70
  }
71
71
  }
@@ -12,7 +12,7 @@ const CriteriaNode_1 = require("./CriteriaNode");
12
12
  class CriteriaNodeFactory {
13
13
  static createNode(metadata, entityName, payload, parent, key) {
14
14
  const customExpression = CriteriaNode_1.CriteriaNode.isCustomExpression(key || '');
15
- const scalar = core_1.Utils.isPrimaryKey(payload) || payload instanceof RegExp || payload instanceof Date || customExpression;
15
+ const scalar = core_1.Utils.isPrimaryKey(payload) || core_1.Utils.isRawSql(payload) || payload instanceof RegExp || payload instanceof Date || customExpression;
16
16
  if (Array.isArray(payload) && !scalar) {
17
17
  return this.createArrayNode(metadata, entityName, payload, parent, key);
18
18
  }
@@ -116,7 +116,6 @@ export declare class QueryBuilder<T extends object = AnyEntity> {
116
116
  ref(field: string): Knex.Ref<string, {
117
117
  [x: string]: string;
118
118
  }>;
119
- raw<R = Knex.Raw>(sql: string, bindings?: Knex.RawBinding[] | Knex.ValueDict): R;
120
119
  limit(limit?: number, offset?: number): this;
121
120
  offset(offset?: number): this;
122
121
  withSchema(schema?: string): this;
@@ -116,7 +116,7 @@ class QueryBuilder {
116
116
  this._fields = this.mainAlias.metadata.primaryKeys;
117
117
  }
118
118
  else {
119
- this._fields = [this.raw('*')];
119
+ this._fields = [(0, core_1.raw)('*')];
120
120
  }
121
121
  if (distinct) {
122
122
  this.flags.add(core_1.QueryFlag.DISTINCT);
@@ -278,11 +278,6 @@ class QueryBuilder {
278
278
  ref(field) {
279
279
  return this.knex.ref(field);
280
280
  }
281
- raw(sql, bindings = []) {
282
- const raw = this.knex.raw(sql, bindings);
283
- raw.__raw = true; // tag it as there is now way to check via `instanceof`
284
- return raw;
285
- }
286
281
  limit(limit, offset = 0) {
287
282
  this.ensureNotFinalized();
288
283
  this._limit = limit;
@@ -374,7 +369,7 @@ class QueryBuilder {
374
369
  if (this.lockMode) {
375
370
  this.helper.getLockSQL(qb, this.lockMode, this.lockTables);
376
371
  }
377
- this.helper.finalize(this.type ?? enums_1.QueryType.SELECT, qb, this.mainAlias.metadata);
372
+ this.helper.finalize(this.type ?? enums_1.QueryType.SELECT, qb, this.mainAlias.metadata, this._data);
378
373
  return qb;
379
374
  }
380
375
  /**
@@ -48,7 +48,7 @@ export declare class QueryBuilderHelper {
48
48
  private getOperatorReplacement;
49
49
  getQueryOrder(type: QueryType, orderBy: FlatQueryOrderMap | FlatQueryOrderMap[], populate: Dictionary<string>): string;
50
50
  getQueryOrderFromObject(type: QueryType, orderBy: FlatQueryOrderMap, populate: Dictionary<string>): string;
51
- finalize(type: QueryType, qb: Knex.QueryBuilder, meta?: EntityMetadata): void;
51
+ finalize(type: QueryType, qb: Knex.QueryBuilder, meta?: EntityMetadata, data?: Dictionary): void;
52
52
  splitField<T>(field: EntityKey<T>, greedyAlias?: boolean): [string, EntityKey<T>];
53
53
  getLockSQL(qb: Knex.QueryBuilder, lockMode: LockMode, lockTables?: string[]): void;
54
54
  updateVersionProperty(qb: Knex.QueryBuilder, data: Dictionary): void;
@@ -19,6 +19,9 @@ class QueryBuilderHelper {
19
19
  this.metadata = this.driver.getMetadata();
20
20
  }
21
21
  mapper(field, type = enums_1.QueryType.SELECT, value, alias) {
22
+ if (core_1.Utils.isRawSql(field)) {
23
+ return this.platform.formatQuery(field.sql, field.params ?? []);
24
+ }
22
25
  if (typeof field !== 'string') {
23
26
  return field;
24
27
  }
@@ -460,11 +463,23 @@ class QueryBuilderHelper {
460
463
  });
461
464
  return ret.join(', ');
462
465
  }
463
- finalize(type, qb, meta) {
464
- const useReturningStatement = type === enums_1.QueryType.INSERT && this.platform.usesReturningStatement() && meta && !meta.compositePK;
465
- if (useReturningStatement) {
466
- const returningProps = meta.hydrateProps.filter(prop => prop.persist !== false && (prop.primary || prop.defaultRaw));
467
- qb.returning(core_1.Utils.flatten(returningProps.map(prop => prop.fieldNames)));
466
+ finalize(type, qb, meta, data) {
467
+ if (!meta || !data || !this.platform.usesReturningStatement()) {
468
+ return;
469
+ }
470
+ if (type === enums_1.QueryType.INSERT) {
471
+ const returningProps = meta.hydrateProps
472
+ .filter(prop => prop.persist !== false && ((prop.primary && prop.autoincrement) || prop.defaultRaw))
473
+ .filter(prop => !(prop.name in data) || core_1.Utils.isRawSql(data[prop.name]));
474
+ if (returningProps.length > 0) {
475
+ qb.returning(core_1.Utils.flatten(returningProps.map(prop => prop.fieldNames)));
476
+ }
477
+ }
478
+ if (type === enums_1.QueryType.UPDATE) {
479
+ const returningProps = meta.hydrateProps.filter(prop => core_1.Utils.isRawSql(data[prop.name]));
480
+ if (returningProps.length > 0) {
481
+ qb.returning(core_1.Utils.flatten(returningProps.map(prop => prop.fieldNames)));
482
+ }
468
483
  }
469
484
  }
470
485
  splitField(field, greedyAlias = false) {