@mikro-orm/sql 7.0.10-dev.10 → 7.0.10-dev.12

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.
@@ -1,5 +1,5 @@
1
1
  import { type ControlledTransaction, type Dialect, Kysely } from 'kysely';
2
- import { type AnyEntity, Connection, type Dictionary, type EntityData, type IsolationLevel, type LogContext, type LoggingOptions, type MaybePromise, type QueryResult, RawQueryFragment, type Transaction, type TransactionEventBroadcaster } from '@mikro-orm/core';
2
+ import { type AnyEntity, Connection, type Dictionary, type EntityData, type IsolationLevel, type LogContext, type LoggingOptions, type MaybePromise, type QueryResult, type RawQueryFragment, type Transaction, type TransactionEventBroadcaster } from '@mikro-orm/core';
3
3
  import type { AbstractSqlPlatform } from './AbstractSqlPlatform.js';
4
4
  import { NativeQueryBuilder } from './query/NativeQueryBuilder.js';
5
5
  /** Base class for SQL database connections, built on top of Kysely. */
@@ -1,5 +1,5 @@
1
1
  import { CompiledQuery, Kysely } from 'kysely';
2
- import { Connection, EventType, RawQueryFragment, Utils, } from '@mikro-orm/core';
2
+ import { Connection, EventType, isRaw, Utils, } from '@mikro-orm/core';
3
3
  import { NativeQueryBuilder } from './query/NativeQueryBuilder.js';
4
4
  /** Base class for SQL database connections, built on top of Kysely. */
5
5
  export class AbstractSqlConnection extends Connection {
@@ -170,7 +170,7 @@ export class AbstractSqlConnection extends Connection {
170
170
  if (query instanceof NativeQueryBuilder) {
171
171
  query = query.toRaw();
172
172
  }
173
- if (query instanceof RawQueryFragment) {
173
+ if (isRaw(query)) {
174
174
  params = query.params;
175
175
  query = query.sql;
176
176
  }
@@ -157,7 +157,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
157
157
  if (res instanceof QueryBuilder) {
158
158
  return this.wrapVirtualExpressionInSubquery(meta, res.getFormattedQuery(), where, options, type);
159
159
  }
160
- if (res instanceof RawQueryFragment) {
160
+ if (isRaw(res)) {
161
161
  const expr = this.platform.formatQuery(res.sql, res.params);
162
162
  return this.wrapVirtualExpressionInSubquery(meta, expr, where, options, type);
163
163
  }
@@ -185,7 +185,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
185
185
  yield* this.wrapVirtualExpressionInSubqueryStream(meta, res.getFormattedQuery(), where, options, QueryType.SELECT);
186
186
  return;
187
187
  }
188
- if (res instanceof RawQueryFragment) {
188
+ if (isRaw(res)) {
189
189
  const expr = this.platform.formatQuery(res.sql, res.params);
190
190
  yield* this.wrapVirtualExpressionInSubqueryStream(meta, expr, where, options, QueryType.SELECT);
191
191
  return;
@@ -1,4 +1,4 @@
1
- import { LockMode, QueryFlag, RawQueryFragment, Utils } from '@mikro-orm/core';
1
+ import { isRaw, LockMode, QueryFlag, Utils } from '@mikro-orm/core';
2
2
  import { NativeQueryBuilder } from '../../query/NativeQueryBuilder.js';
3
3
  import { QueryType } from '../../query/enums.js';
4
4
  /** @internal */
@@ -98,7 +98,7 @@ export class MsSqlNativeQueryBuilder extends NativeQueryBuilder {
98
98
  }
99
99
  this.parts.push(`merge into ${this.getTableName()}`);
100
100
  this.parts.push(`using (values ${parts.join(', ')}) as tsource(${keys.map(key => this.quote(key)).join(', ')})`);
101
- if (clause.fields instanceof RawQueryFragment) {
101
+ if (isRaw(clause.fields)) {
102
102
  this.parts.push(clause.fields.sql);
103
103
  this.params.push(...clause.fields.params);
104
104
  }
@@ -1,4 +1,4 @@
1
- import { LockMode, RawQueryFragment, Utils } from '@mikro-orm/core';
1
+ import { isRaw, LockMode, Utils } from '@mikro-orm/core';
2
2
  import { NativeQueryBuilder } from '../../query/NativeQueryBuilder.js';
3
3
  /** @internal */
4
4
  export class MySqlNativeQueryBuilder extends NativeQueryBuilder {
@@ -65,7 +65,7 @@ export class MySqlNativeQueryBuilder extends NativeQueryBuilder {
65
65
  return;
66
66
  }
67
67
  this.parts.push('on conflict');
68
- if (clause.fields instanceof RawQueryFragment) {
68
+ if (isRaw(clause.fields)) {
69
69
  this.parts.push(clause.fields.sql);
70
70
  this.params.push(...clause.fields.params);
71
71
  }
@@ -1,4 +1,4 @@
1
- import { raw, RawQueryFragment, Utils } from '@mikro-orm/core';
1
+ import { isRaw, raw, Utils } from '@mikro-orm/core';
2
2
  import { QueryType } from '../../query/enums.js';
3
3
  import { NativeQueryBuilder } from '../../query/NativeQueryBuilder.js';
4
4
  /** @internal */
@@ -164,7 +164,7 @@ export class OracleNativeQueryBuilder extends NativeQueryBuilder {
164
164
  this.parts.push(`merge into ${this.getTableName()}`);
165
165
  this.parts.push(`using (${parts.join(' union all ')}) tsource`);
166
166
  /* v8 ignore next 4: RawQueryFragment conflict fields branch */
167
- if (clause.fields instanceof RawQueryFragment) {
167
+ if (isRaw(clause.fields)) {
168
168
  this.parts.push(clause.fields.sql);
169
169
  this.params.push(...clause.fields.params);
170
170
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/sql",
3
- "version": "7.0.10-dev.10",
3
+ "version": "7.0.10-dev.12",
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
  "keywords": [
6
6
  "data-mapper",
@@ -53,7 +53,7 @@
53
53
  "@mikro-orm/core": "^7.0.9"
54
54
  },
55
55
  "peerDependencies": {
56
- "@mikro-orm/core": "7.0.10-dev.10"
56
+ "@mikro-orm/core": "7.0.10-dev.12"
57
57
  },
58
58
  "engines": {
59
59
  "node": ">= 22.17.0"
@@ -1,4 +1,4 @@
1
- import { type Dictionary, LockMode, type QueryFlag, RawQueryFragment, type Subquery } from '@mikro-orm/core';
1
+ import { type Dictionary, LockMode, type QueryFlag, type RawQueryFragment, type Subquery } from '@mikro-orm/core';
2
2
  import { QueryType } from './enums.js';
3
3
  import type { AbstractSqlPlatform } from '../AbstractSqlPlatform.js';
4
4
  /** Options for Common Table Expression (CTE) definitions. */
@@ -1,4 +1,4 @@
1
- import { LockMode, raw, RawQueryFragment, Utils, } from '@mikro-orm/core';
1
+ import { isRaw, LockMode, raw, Utils, } from '@mikro-orm/core';
2
2
  import { QueryType } from './enums.js';
3
3
  /** @internal */
4
4
  export class NativeQueryBuilder {
@@ -157,7 +157,7 @@ export class NativeQueryBuilder {
157
157
  return;
158
158
  }
159
159
  this.parts.push('on conflict');
160
- if (clause.fields instanceof RawQueryFragment) {
160
+ if (isRaw(clause.fields)) {
161
161
  this.parts.push(clause.fields.sql);
162
162
  this.params.push(...clause.fields.params);
163
163
  }
@@ -474,14 +474,14 @@ export class NativeQueryBuilder {
474
474
  throw new Error('No table name provided');
475
475
  }
476
476
  const indexHint = this.options.indexHint ? ' ' + this.options.indexHint : '';
477
- if (this.options.tableName instanceof RawQueryFragment) {
477
+ if (isRaw(this.options.tableName)) {
478
478
  this.params.push(...this.options.tableName.params);
479
479
  return this.options.tableName.sql + indexHint;
480
480
  }
481
481
  return this.options.tableName + indexHint;
482
482
  }
483
483
  quote(id) {
484
- if (id instanceof RawQueryFragment) {
484
+ if (isRaw(id)) {
485
485
  return this.platform.formatQuery(id.sql, id.params);
486
486
  }
487
487
  if (id instanceof NativeQueryBuilder) {
@@ -187,6 +187,7 @@ export interface QBState<Entity extends object> {
187
187
  name: string;
188
188
  query: NativeQueryBuilder | RawQueryFragment;
189
189
  recursive?: boolean;
190
+ meta?: EntityMetadata;
190
191
  })[];
191
192
  tptJoinsApplied: boolean;
192
193
  autoJoinedPaths: string[];
@@ -1214,6 +1214,7 @@ export class QueryBuilder {
1214
1214
  recursive,
1215
1215
  columns: options?.columns,
1216
1216
  materialized: options?.materialized,
1217
+ meta: query instanceof _a ? query.mainAlias.meta : undefined,
1217
1218
  });
1218
1219
  return this;
1219
1220
  }
@@ -2168,14 +2169,20 @@ export class QueryBuilder {
2168
2169
  }
2169
2170
  fromRawTable(tableName, aliasName) {
2170
2171
  aliasName ??= this.#state.mainAlias?.aliasName ?? this.getNextAlias(tableName);
2171
- const meta = new EntityMetadata({
2172
- className: tableName,
2173
- collection: tableName,
2174
- });
2175
- meta.root = meta;
2172
+ // If the raw table name matches a CTE registered via `.with()` from a typed QueryBuilder,
2173
+ // reuse the source entity meta so relation joins (`leftJoinAndSelect` etc.) keep working.
2174
+ const cteMeta = this.#state.ctes.find(c => c.name === tableName)?.meta;
2175
+ let meta;
2176
+ if (cteMeta) {
2177
+ meta = cteMeta;
2178
+ }
2179
+ else {
2180
+ meta = new EntityMetadata({ className: tableName, collection: tableName });
2181
+ meta.root = meta;
2182
+ }
2176
2183
  this.#state.mainAlias = {
2177
2184
  aliasName,
2178
- entityName: tableName,
2185
+ entityName: (cteMeta?.className ?? tableName),
2179
2186
  meta,
2180
2187
  rawTableName: tableName,
2181
2188
  };
@@ -569,20 +569,24 @@ export class QueryBuilderHelper {
569
569
  parts.push(processed.sql);
570
570
  params.push(...processed.params);
571
571
  }
572
- else if (value[op] instanceof Raw || typeof value[op]?.toRaw === 'function') {
573
- const query = value[op] instanceof Raw ? value[op] : value[op].toRaw();
574
- const mappedKey = this.mapper(key, type, query, null);
575
- let sql = query.sql.replaceAll(ALIAS_REPLACEMENT, this.#alias);
576
- if (['$in', '$nin'].includes(op)) {
577
- sql = `(${sql})`;
578
- }
579
- parts.push(`${this.#platform.quoteIdentifier(mappedKey)} ${replacement} ${sql}`);
580
- params.push(...query.params);
581
- }
582
572
  else {
583
- const mappedKey = this.mapper(key, type, value[op], null);
584
- const val = this.getValueReplacement(fields, value[op], params, op, prop);
585
- parts.push(`${this.#platform.quoteIdentifier(mappedKey)} ${replacement} ${val}`);
573
+ const opValue = value[op];
574
+ const opValueIsRaw = isRaw(opValue);
575
+ if (opValueIsRaw || typeof opValue?.toRaw === 'function') {
576
+ const query = opValueIsRaw ? opValue : opValue.toRaw();
577
+ const mappedKey = this.mapper(key, type, query, null);
578
+ let sql = query.sql.replaceAll(ALIAS_REPLACEMENT, this.#alias);
579
+ if (['$in', '$nin'].includes(op)) {
580
+ sql = `(${sql})`;
581
+ }
582
+ parts.push(`${this.#platform.quoteIdentifier(mappedKey)} ${replacement} ${sql}`);
583
+ params.push(...query.params);
584
+ }
585
+ else {
586
+ const mappedKey = this.mapper(key, type, opValue, null);
587
+ const val = this.getValueReplacement(fields, opValue, params, op, prop);
588
+ parts.push(`${this.#platform.quoteIdentifier(mappedKey)} ${replacement} ${val}`);
589
+ }
586
590
  }
587
591
  return { sql: parts.join(' and '), params };
588
592
  }
@@ -753,7 +757,7 @@ export class QueryBuilderHelper {
753
757
  const tptAlias = this.getTPTAliasForProperty(field, this.#alias);
754
758
  const alias = always ? (quote ? tptAlias : this.#platform.quoteIdentifier(tptAlias)) + '.' : '';
755
759
  const fieldName = this.fieldName(field, tptAlias, always, idx);
756
- if (fieldName instanceof Raw) {
760
+ if (isRaw(fieldName)) {
757
761
  return fieldName.sql;
758
762
  }
759
763
  ret = alias + fieldName;
@@ -767,7 +771,7 @@ export class QueryBuilderHelper {
767
771
  const isTableAlias = !!this.#aliasMap[a];
768
772
  const resolvedAlias = isTableAlias ? this.getTPTAliasForProperty(f, a) : a;
769
773
  const fieldName = this.fieldName(f, resolvedAlias, always, idx);
770
- if (fieldName instanceof Raw) {
774
+ if (isRaw(fieldName)) {
771
775
  return fieldName.sql;
772
776
  }
773
777
  ret = resolvedAlias + '.' + fieldName;
@@ -1,4 +1,4 @@
1
- import { DecimalType, EntitySchema, RawQueryFragment, ReferenceKind, t, Type, UnknownType, Utils, } from '@mikro-orm/core';
1
+ import { DecimalType, EntitySchema, isRaw, ReferenceKind, t, Type, UnknownType, Utils, } from '@mikro-orm/core';
2
2
  /**
3
3
  * @internal
4
4
  */
@@ -89,7 +89,7 @@ export class DatabaseTable {
89
89
  this.#columns[field] = {
90
90
  name: prop.fieldNames[idx],
91
91
  type: prop.columnTypes[idx],
92
- generated: prop.generated instanceof RawQueryFragment
92
+ generated: isRaw(prop.generated)
93
93
  ? this.#platform.formatQuery(prop.generated.sql, prop.generated.params)
94
94
  : prop.generated,
95
95
  mappedType,
@@ -787,7 +787,7 @@ export class DatabaseTable {
787
787
  };
788
788
  const columns = meta.createSchemaColumnMappingObject();
789
789
  const exp = expression(columns, table, indexName);
790
- return exp instanceof RawQueryFragment ? this.#platform.formatQuery(exp.sql, exp.params) : exp;
790
+ return isRaw(exp) ? this.#platform.formatQuery(exp.sql, exp.params) : exp;
791
791
  }
792
792
  return expression;
793
793
  }
@@ -1,4 +1,4 @@
1
- import { type Connection, type Dictionary, type Options, type Transaction, RawQueryFragment } from '@mikro-orm/core';
1
+ import { type Connection, type Dictionary, type Options, type Transaction, type RawQueryFragment } from '@mikro-orm/core';
2
2
  import type { AbstractSqlConnection } from '../AbstractSqlConnection.js';
3
3
  import type { AbstractSqlPlatform } from '../AbstractSqlPlatform.js';
4
4
  import type { CheckDef, Column, ForeignKey, IndexDef, Table, TableDifference } from '../typings.js';
@@ -1,4 +1,4 @@
1
- import { RawQueryFragment, Utils, } from '@mikro-orm/core';
1
+ import { isRaw, Utils, } from '@mikro-orm/core';
2
2
  /** Base class for database-specific schema helpers. Provides SQL generation for DDL operations. */
3
3
  export class SchemaHelper {
4
4
  platform;
@@ -424,7 +424,7 @@ export class SchemaHelper {
424
424
  if (defaultValue == null) {
425
425
  return defaultValue;
426
426
  }
427
- if (defaultValue instanceof RawQueryFragment) {
427
+ if (isRaw(defaultValue)) {
428
428
  return this.platform.formatQuery(defaultValue.sql, defaultValue.params);
429
429
  }
430
430
  const genericValue = defaultValue.replace(/\(\d+\)/, '(?)').toLowerCase();