@mikro-orm/knex 6.1.13-dev.9 → 6.2.0

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.
Files changed (73) hide show
  1. package/AbstractSqlConnection.js +8 -2
  2. package/AbstractSqlDriver.d.ts +5 -5
  3. package/AbstractSqlDriver.js +21 -10
  4. package/MonkeyPatchable.d.ts +5 -0
  5. package/MonkeyPatchable.js +15 -0
  6. package/README.md +17 -11
  7. package/SqlEntityManager.d.ts +1 -1
  8. package/SqlEntityManager.js +1 -2
  9. package/dialects/index.d.ts +4 -0
  10. package/dialects/index.js +20 -0
  11. package/dialects/mssql/MsSqlColumnCompiler.d.ts +4 -0
  12. package/dialects/mssql/MsSqlColumnCompiler.js +10 -0
  13. package/dialects/mssql/MsSqlKnexDialect.d.ts +6 -0
  14. package/dialects/mssql/MsSqlKnexDialect.js +22 -0
  15. package/dialects/mssql/MsSqlQueryCompiler.d.ts +12 -0
  16. package/dialects/mssql/MsSqlQueryCompiler.js +94 -0
  17. package/dialects/mssql/MsSqlTableCompiler.d.ts +9 -0
  18. package/dialects/mssql/MsSqlTableCompiler.js +40 -0
  19. package/dialects/mssql/index.d.ts +1 -0
  20. package/dialects/mssql/index.js +17 -0
  21. package/dialects/mysql/MariaDbKnexDialect.d.ts +6 -0
  22. package/dialects/mysql/MariaDbKnexDialect.js +16 -0
  23. package/dialects/mysql/MySqlColumnCompiler.d.ts +9 -0
  24. package/dialects/mysql/MySqlColumnCompiler.js +19 -0
  25. package/dialects/mysql/MySqlConnection.d.ts +8 -0
  26. package/dialects/mysql/MySqlConnection.js +43 -0
  27. package/dialects/mysql/MySqlExceptionConverter.d.ts +9 -0
  28. package/dialects/mysql/MySqlExceptionConverter.js +83 -0
  29. package/dialects/mysql/MySqlKnexDialect.d.ts +5 -0
  30. package/dialects/mysql/MySqlKnexDialect.js +21 -0
  31. package/dialects/mysql/MySqlPlatform.d.ts +31 -0
  32. package/dialects/mysql/MySqlPlatform.js +88 -0
  33. package/dialects/mysql/MySqlQueryCompiler.d.ts +5 -0
  34. package/dialects/mysql/MySqlQueryCompiler.js +23 -0
  35. package/dialects/mysql/MySqlSchemaHelper.d.ts +43 -0
  36. package/dialects/mysql/MySqlSchemaHelper.js +297 -0
  37. package/dialects/mysql/index.d.ts +6 -0
  38. package/dialects/mysql/index.js +22 -0
  39. package/dialects/postgresql/PostgreSqlKnexDialect.d.ts +6 -0
  40. package/dialects/postgresql/PostgreSqlKnexDialect.js +19 -0
  41. package/dialects/postgresql/PostgreSqlTableCompiler.d.ts +11 -0
  42. package/dialects/postgresql/PostgreSqlTableCompiler.js +89 -0
  43. package/dialects/postgresql/index.d.ts +1 -0
  44. package/dialects/postgresql/index.js +17 -0
  45. package/dialects/sqlite/BaseSqliteConnection.d.ts +10 -0
  46. package/dialects/sqlite/BaseSqliteConnection.js +56 -0
  47. package/dialects/sqlite/BaseSqlitePlatform.d.ts +49 -0
  48. package/dialects/sqlite/BaseSqlitePlatform.js +78 -0
  49. package/dialects/sqlite/BaseSqliteSchemaHelper.d.ts +27 -0
  50. package/dialects/sqlite/BaseSqliteSchemaHelper.js +172 -0
  51. package/dialects/sqlite/BetterSqliteKnexDialect.d.ts +5 -0
  52. package/dialects/sqlite/BetterSqliteKnexDialect.js +15 -0
  53. package/dialects/sqlite/LibSqlKnexDialect.d.ts +6 -0
  54. package/dialects/sqlite/LibSqlKnexDialect.js +18 -0
  55. package/dialects/sqlite/SqliteKnexDialect.d.ts +8 -0
  56. package/dialects/sqlite/SqliteKnexDialect.js +67 -0
  57. package/dialects/sqlite/SqliteTableCompiler.d.ts +5 -0
  58. package/dialects/sqlite/SqliteTableCompiler.js +45 -0
  59. package/dialects/sqlite/index.d.ts +7 -0
  60. package/dialects/sqlite/index.js +23 -0
  61. package/index.d.ts +1 -0
  62. package/index.js +1 -0
  63. package/index.mjs +16 -0
  64. package/package.json +3 -3
  65. package/query/QueryBuilder.d.ts +59 -41
  66. package/query/QueryBuilder.js +61 -23
  67. package/query/QueryBuilderHelper.js +8 -3
  68. package/schema/DatabaseTable.js +16 -4
  69. package/schema/SchemaComparator.js +13 -3
  70. package/schema/SchemaHelper.d.ts +5 -1
  71. package/schema/SchemaHelper.js +19 -2
  72. package/schema/SqlSchemaGenerator.d.ts +12 -4
  73. package/schema/SqlSchemaGenerator.js +51 -29
@@ -0,0 +1,5 @@
1
+ import type { Dictionary } from '@mikro-orm/core';
2
+ import { MonkeyPatchable } from '../../MonkeyPatchable';
3
+ export declare class SqliteTableCompiler extends MonkeyPatchable.Sqlite3DialectTableCompiler {
4
+ foreign(this: any, foreignInfo: Dictionary): void;
5
+ }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SqliteTableCompiler = void 0;
4
+ const MonkeyPatchable_1 = require("../../MonkeyPatchable");
5
+ class SqliteTableCompiler extends MonkeyPatchable_1.MonkeyPatchable.Sqlite3DialectTableCompiler {
6
+ foreign(foreignInfo) {
7
+ foreignInfo.column = Array.isArray(foreignInfo.column)
8
+ ? foreignInfo.column
9
+ : [foreignInfo.column];
10
+ foreignInfo.column = foreignInfo.column.map((column) => this.client.customWrapIdentifier(column, (a) => a));
11
+ foreignInfo.inTable = this.client.customWrapIdentifier(foreignInfo.inTable, (a) => a);
12
+ foreignInfo.references = Array.isArray(foreignInfo.references)
13
+ ? foreignInfo.references
14
+ : [foreignInfo.references];
15
+ foreignInfo.references = foreignInfo.references.map((column) => this.client.customWrapIdentifier(column, (a) => a));
16
+ // quoted versions
17
+ const column = this.formatter.columnize(foreignInfo.column);
18
+ const inTable = this.formatter.columnize(foreignInfo.inTable);
19
+ const references = this.formatter.columnize(foreignInfo.references);
20
+ const keyName = this.formatter.columnize(foreignInfo.keyName);
21
+ const addColumnQuery = this.sequence.find((query) => query.sql.includes(`add column ${column[0]}`));
22
+ // no need for temp tables if we just add a column
23
+ if (addColumnQuery) {
24
+ /* istanbul ignore next */
25
+ const onUpdate = foreignInfo.onUpdate ? ` on update ${foreignInfo.onUpdate}` : '';
26
+ /* istanbul ignore next */
27
+ const onDelete = foreignInfo.onDelete ? ` on delete ${foreignInfo.onDelete}` : '';
28
+ addColumnQuery.sql += ` constraint ${keyName} references ${inTable} (${references})${onUpdate}${onDelete}`;
29
+ return;
30
+ }
31
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
32
+ const compiler = this;
33
+ if (this.method !== 'create' && this.method !== 'createIfNot') {
34
+ this.pushQuery({
35
+ sql: `PRAGMA table_info(${this.tableName()})`,
36
+ statementsProducer(pragma, connection) {
37
+ return compiler.client
38
+ .ddl(compiler, pragma, connection)
39
+ .foreign(foreignInfo);
40
+ },
41
+ });
42
+ }
43
+ }
44
+ }
45
+ exports.SqliteTableCompiler = SqliteTableCompiler;
@@ -0,0 +1,7 @@
1
+ export * from './BaseSqliteConnection';
2
+ export * from './BaseSqlitePlatform';
3
+ export * from './BaseSqliteSchemaHelper';
4
+ export * from './SqliteTableCompiler';
5
+ export * from './BetterSqliteKnexDialect';
6
+ export * from './LibSqlKnexDialect';
7
+ export * from './SqliteKnexDialect';
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./BaseSqliteConnection"), exports);
18
+ __exportStar(require("./BaseSqlitePlatform"), exports);
19
+ __exportStar(require("./BaseSqliteSchemaHelper"), exports);
20
+ __exportStar(require("./SqliteTableCompiler"), exports);
21
+ __exportStar(require("./BetterSqliteKnexDialect"), exports);
22
+ __exportStar(require("./LibSqlKnexDialect"), exports);
23
+ __exportStar(require("./SqliteKnexDialect"), exports);
package/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export * from './SqlEntityManager';
10
10
  export * from './SqlEntityRepository';
11
11
  export * from './query';
12
12
  export * from './schema';
13
+ export * from './dialects';
13
14
  export * from './typings';
14
15
  export { SqlEntityManager as EntityManager } from './SqlEntityManager';
15
16
  export { SqlEntityRepository as EntityRepository } from './SqlEntityRepository';
package/index.js CHANGED
@@ -28,6 +28,7 @@ __exportStar(require("./SqlEntityManager"), exports);
28
28
  __exportStar(require("./SqlEntityRepository"), exports);
29
29
  __exportStar(require("./query"), exports);
30
30
  __exportStar(require("./schema"), exports);
31
+ __exportStar(require("./dialects"), exports);
31
32
  __exportStar(require("./typings"), exports);
32
33
  var SqlEntityManager_1 = require("./SqlEntityManager");
33
34
  Object.defineProperty(exports, "EntityManager", { enumerable: true, get: function () { return SqlEntityManager_1.SqlEntityManager; } });
package/index.mjs CHANGED
@@ -17,10 +17,14 @@ export const ArrayCollection = mod.ArrayCollection;
17
17
  export const ArrayCriteriaNode = mod.ArrayCriteriaNode;
18
18
  export const ArrayType = mod.ArrayType;
19
19
  export const BaseEntity = mod.BaseEntity;
20
+ export const BaseSqliteConnection = mod.BaseSqliteConnection;
21
+ export const BaseSqlitePlatform = mod.BaseSqlitePlatform;
22
+ export const BaseSqliteSchemaHelper = mod.BaseSqliteSchemaHelper;
20
23
  export const BeforeCreate = mod.BeforeCreate;
21
24
  export const BeforeDelete = mod.BeforeDelete;
22
25
  export const BeforeUpdate = mod.BeforeUpdate;
23
26
  export const BeforeUpsert = mod.BeforeUpsert;
27
+ export const BetterSqliteKnexDialect = mod.BetterSqliteKnexDialect;
24
28
  export const BigIntType = mod.BigIntType;
25
29
  export const BlobType = mod.BlobType;
26
30
  export const BooleanType = mod.BooleanType;
@@ -108,11 +112,13 @@ export const JoinType = mod.JoinType;
108
112
  export const JsonProperty = mod.JsonProperty;
109
113
  export const JsonType = mod.JsonType;
110
114
  export const Knex = mod.Knex;
115
+ export const LibSqlKnexDialect = mod.LibSqlKnexDialect;
111
116
  export const LoadStrategy = mod.LoadStrategy;
112
117
  export const LockMode = mod.LockMode;
113
118
  export const LockWaitTimeoutException = mod.LockWaitTimeoutException;
114
119
  export const ManyToMany = mod.ManyToMany;
115
120
  export const ManyToOne = mod.ManyToOne;
121
+ export const MariaDbKnexDialect = mod.MariaDbKnexDialect;
116
122
  export const MediumIntType = mod.MediumIntType;
117
123
  export const MemoryCacheAdapter = mod.MemoryCacheAdapter;
118
124
  export const MetadataDiscovery = mod.MetadataDiscovery;
@@ -123,6 +129,12 @@ export const MetadataValidator = mod.MetadataValidator;
123
129
  export const MikroORM = mod.MikroORM;
124
130
  export const MongoNamingStrategy = mod.MongoNamingStrategy;
125
131
  export const MonkeyPatchable = mod.MonkeyPatchable;
132
+ export const MsSqlKnexDialect = mod.MsSqlKnexDialect;
133
+ export const MySqlConnection = mod.MySqlConnection;
134
+ export const MySqlExceptionConverter = mod.MySqlExceptionConverter;
135
+ export const MySqlKnexDialect = mod.MySqlKnexDialect;
136
+ export const MySqlPlatform = mod.MySqlPlatform;
137
+ export const MySqlSchemaHelper = mod.MySqlSchemaHelper;
126
138
  export const NodeState = mod.NodeState;
127
139
  export const NonUniqueFieldNameException = mod.NonUniqueFieldNameException;
128
140
  export const NotFoundError = mod.NotFoundError;
@@ -141,6 +153,8 @@ export const OptionalProps = mod.OptionalProps;
141
153
  export const PlainObject = mod.PlainObject;
142
154
  export const Platform = mod.Platform;
143
155
  export const PopulateHint = mod.PopulateHint;
156
+ export const PopulatePath = mod.PopulatePath;
157
+ export const PostgreSqlKnexDialect = mod.PostgreSqlKnexDialect;
144
158
  export const PrimaryKey = mod.PrimaryKey;
145
159
  export const PrimaryKeyProp = mod.PrimaryKeyProp;
146
160
  export const Property = mod.Property;
@@ -173,6 +187,8 @@ export const SmallIntType = mod.SmallIntType;
173
187
  export const SqlEntityManager = mod.SqlEntityManager;
174
188
  export const SqlEntityRepository = mod.SqlEntityRepository;
175
189
  export const SqlSchemaGenerator = mod.SqlSchemaGenerator;
190
+ export const SqliteKnexDialect = mod.SqliteKnexDialect;
191
+ export const SqliteTableCompiler = mod.SqliteTableCompiler;
176
192
  export const StringType = mod.StringType;
177
193
  export const SyntaxErrorException = mod.SyntaxErrorException;
178
194
  export const TableExistsException = mod.TableExistsException;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/knex",
3
- "version": "6.1.13-dev.9",
3
+ "version": "6.2.0",
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": "^6.1.12"
66
+ "@mikro-orm/core": "^6.2.0"
67
67
  },
68
68
  "peerDependencies": {
69
- "@mikro-orm/core": "6.1.13-dev.9"
69
+ "@mikro-orm/core": "^6.0.0"
70
70
  }
71
71
  }
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import { inspect } from 'util';
3
3
  import type { Knex } from 'knex';
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';
4
+ import { type AnyEntity, type ConnectionType, type Dictionary, type EntityData, type EntityMetadata, type EntityName, type EntityProperty, type FlushMode, type GroupOperator, LockMode, type LoggingOptions, type MetadataStorage, type ObjectQuery, PopulateHint, type PopulateOptions, type QBFilterQuery, type QBQueryOrderMap, QueryFlag, type QueryOrderMap, type QueryResult, type RequiredEntityData } from '@mikro-orm/core';
5
5
  import { JoinType, QueryType } from './enums';
6
6
  import type { AbstractSqlDriver } from '../AbstractSqlDriver';
7
7
  import { type Alias, QueryBuilderHelper } from './QueryBuilderHelper';
@@ -32,13 +32,12 @@ export interface ExecuteOptions {
32
32
  * ```
33
33
  */
34
34
  export declare class QueryBuilder<T extends object = AnyEntity> {
35
- #private;
36
- private readonly metadata;
37
- private readonly driver;
38
- private readonly context?;
39
- private connectionType?;
40
- private readonly em?;
41
- private readonly loggerContext?;
35
+ protected readonly metadata: MetadataStorage;
36
+ protected readonly driver: AbstractSqlDriver;
37
+ protected readonly context?: Knex.Transaction<any, any[]> | undefined;
38
+ protected connectionType?: ConnectionType | undefined;
39
+ protected em?: SqlEntityManager<AbstractSqlDriver<import("..").AbstractSqlConnection, AbstractSqlPlatform>> | undefined;
40
+ protected loggerContext?: (LoggingOptions & Dictionary) | undefined;
42
41
  get mainAlias(): Alias<T>;
43
42
  get alias(): string;
44
43
  get helper(): QueryBuilderHelper;
@@ -56,40 +55,51 @@ export declare class QueryBuilder<T extends object = AnyEntity> {
56
55
  _populateMap: Dictionary<string>;
57
56
  /** @internal */
58
57
  readonly rawFragments: Set<string>;
59
- private aliasCounter;
60
- private flags;
61
- private finalized;
62
- private _joins;
63
- private _explicitAlias;
64
- private _schema?;
65
- private _cond;
66
- private _data;
67
- private _orderBy;
68
- private _groupBy;
69
- private _having;
70
- private _returning?;
71
- private _onConflict?;
72
- private _limit?;
73
- private _offset?;
74
- private _distinctOn?;
75
- private _joinedProps;
76
- private _cache?;
77
- private _indexHint?;
78
- private _comments;
79
- private _hintComments;
80
- private flushMode?;
81
- private lockMode?;
82
- private lockTables?;
83
- private subQueries;
84
- private _mainAlias?;
85
- private _aliases;
86
- private _helper?;
87
- private readonly platform;
88
- private readonly knex;
58
+ protected aliasCounter: number;
59
+ protected flags: Set<QueryFlag>;
60
+ protected finalized: boolean;
61
+ protected _joins: Dictionary<JoinOptions>;
62
+ protected _explicitAlias: boolean;
63
+ protected _schema?: string;
64
+ protected _cond: Dictionary;
65
+ protected _data: Dictionary;
66
+ protected _orderBy: QueryOrderMap<T>[];
67
+ protected _groupBy: Field<T>[];
68
+ protected _having: Dictionary;
69
+ protected _returning?: Field<T>[];
70
+ protected _onConflict?: {
71
+ fields: string[];
72
+ ignore?: boolean;
73
+ merge?: EntityData<T> | Field<T>[];
74
+ where?: QBFilterQuery<T>;
75
+ }[];
76
+ protected _limit?: number;
77
+ protected _offset?: number;
78
+ protected _distinctOn?: string[];
79
+ protected _joinedProps: Map<string, PopulateOptions<any>>;
80
+ protected _cache?: boolean | number | [string, number];
81
+ protected _indexHint?: string;
82
+ protected _comments: string[];
83
+ protected _hintComments: string[];
84
+ protected flushMode?: FlushMode;
85
+ protected lockMode?: LockMode;
86
+ protected lockTables?: string[];
87
+ protected subQueries: Dictionary<string>;
88
+ protected _mainAlias?: Alias<T>;
89
+ protected _aliases: Dictionary<Alias<any>>;
90
+ protected _helper?: QueryBuilderHelper;
91
+ protected _query?: {
92
+ sql?: string;
93
+ _sql?: Knex.Sql;
94
+ params?: readonly unknown[];
95
+ qb: Knex.QueryBuilder<T>;
96
+ };
97
+ protected readonly platform: AbstractSqlPlatform;
98
+ protected readonly knex: Knex;
89
99
  /**
90
100
  * @internal
91
101
  */
92
- constructor(entityName: EntityName<T> | QueryBuilder<T>, metadata: MetadataStorage, driver: AbstractSqlDriver, context?: Knex.Transaction<any, any[]> | undefined, alias?: string, connectionType?: ConnectionType | undefined, em?: SqlEntityManager<AbstractSqlDriver<import("..").AbstractSqlConnection, AbstractSqlPlatform>> | undefined, loggerContext?: LoggingOptions | undefined);
102
+ constructor(entityName: EntityName<T> | QueryBuilder<T>, metadata: MetadataStorage, driver: AbstractSqlDriver, context?: Knex.Transaction<any, any[]> | undefined, alias?: string, connectionType?: ConnectionType | undefined, em?: SqlEntityManager<AbstractSqlDriver<import("..").AbstractSqlConnection, AbstractSqlPlatform>> | undefined, loggerContext?: (LoggingOptions & Dictionary) | undefined);
93
103
  select(fields: Field<T> | Field<T>[], distinct?: boolean): SelectQueryBuilder<T>;
94
104
  addSelect(fields: Field<T> | Field<T>[]): SelectQueryBuilder<T>;
95
105
  distinct(): SelectQueryBuilder<T>;
@@ -232,16 +242,24 @@ export declare class QueryBuilder<T extends object = AnyEntity> {
232
242
  as(alias: string): Knex.QueryBuilder;
233
243
  clone(reset?: boolean | string[]): QueryBuilder<T>;
234
244
  getKnex(processVirtualEntity?: boolean): Knex.QueryBuilder;
245
+ /**
246
+ * Sets logger context for this query builder.
247
+ */
248
+ setLoggerContext(context: LoggingOptions & Dictionary): void;
249
+ /**
250
+ * Gets logger context for this query builder.
251
+ */
252
+ getLoggerContext<T extends Dictionary & LoggingOptions = Dictionary>(): T;
235
253
  private fromVirtual;
236
254
  private joinReference;
237
- private prepareFields;
255
+ protected prepareFields<T, U extends string | Knex.Raw>(fields: Field<T>[], type?: 'where' | 'groupBy' | 'sub-query'): U[];
238
256
  private init;
239
257
  private getQueryBase;
240
258
  private applyDiscriminatorCondition;
241
259
  private finalize;
242
260
  private processPopulateWhere;
243
261
  private hasToManyJoins;
244
- private wrapPaginateSubQuery;
262
+ protected wrapPaginateSubQuery(meta: EntityMetadata): void;
245
263
  private wrapModifySubQuery;
246
264
  private getSchema;
247
265
  private createAlias;
@@ -85,6 +85,7 @@ class QueryBuilder {
85
85
  _mainAlias;
86
86
  _aliases = {};
87
87
  _helper;
88
+ _query;
88
89
  platform;
89
90
  knex;
90
91
  /**
@@ -459,10 +460,10 @@ class QueryBuilder {
459
460
  return this;
460
461
  }
461
462
  getKnexQuery(processVirtualEntity = true) {
462
- if (this.#query) {
463
- return this.#query.qb;
463
+ if (this._query?.qb) {
464
+ return this._query.qb;
464
465
  }
465
- this.#query = {};
466
+ this._query = {};
466
467
  this.finalize();
467
468
  const qb = this.getQueryBase(processVirtualEntity);
468
469
  const type = this.type ?? enums_1.QueryType.SELECT;
@@ -484,14 +485,14 @@ class QueryBuilder {
484
485
  core_1.Utils.runIfNotEmpty(() => this._hintComments.forEach(comment => qb.hintComment(comment)), this._hintComments);
485
486
  core_1.Utils.runIfNotEmpty(() => this.helper.appendOnConflictClause(type, this._onConflict, qb), this._onConflict);
486
487
  if (this.type === enums_1.QueryType.TRUNCATE && this.platform.usesCascadeStatement()) {
487
- return this.#query.qb = this.knex.raw(qb.toSQL().toNative().sql + ' cascade');
488
+ return this._query.qb = this.knex.raw(qb.toSQL().toNative().sql + ' cascade');
488
489
  }
489
490
  if (this.lockMode) {
490
491
  this.helper.getLockSQL(qb, this.lockMode, this.lockTables);
491
492
  }
492
493
  this.helper.finalize(type, qb, this.mainAlias.metadata, this._data, this._returning);
493
494
  this.clearRawFragmentsCache();
494
- return this.#query.qb = qb;
495
+ return this._query.qb = qb;
495
496
  }
496
497
  /**
497
498
  * @internal
@@ -506,17 +507,16 @@ class QueryBuilder {
506
507
  getQuery() {
507
508
  return this.toQuery().sql;
508
509
  }
509
- #query;
510
510
  toQuery() {
511
- if (this.#query?.sql) {
512
- return { sql: this.#query.sql, _sql: this.#query._sql, params: this.#query.params };
511
+ if (this._query?.sql) {
512
+ return { sql: this._query.sql, _sql: this._query._sql, params: this._query.params };
513
513
  }
514
514
  const sql = this.getKnexQuery().toSQL();
515
515
  const query = sql.toNative();
516
- this.#query.sql = query.sql;
517
- this.#query._sql = sql;
518
- this.#query.params = query.bindings ?? [];
519
- return { sql: this.#query.sql, _sql: this.#query._sql, params: this.#query.params };
516
+ this._query.sql = query.sql;
517
+ this._query._sql = sql;
518
+ this._query.params = query.bindings ?? [];
519
+ return { sql: this._query.sql, _sql: this._query._sql, params: this._query.params };
520
520
  }
521
521
  /**
522
522
  * Returns the list of all parameters for this query.
@@ -608,7 +608,8 @@ class QueryBuilder {
608
608
  }
609
609
  const write = method === 'run' || !this.platform.getConfig().get('preferReadReplicas');
610
610
  const type = this.connectionType || (write ? 'write' : 'read');
611
- const res = await this.driver.getConnection(type).execute(query.sql, query.bindings, method, this.context, this.loggerContext);
611
+ const loggerContext = { id: this.em?.id, ...this.loggerContext };
612
+ const res = await this.driver.getConnection(type).execute(query.sql, query.bindings, method, this.context, loggerContext);
612
613
  const meta = this.mainAlias.metadata;
613
614
  if (!options.mapResults || !meta) {
614
615
  await this.em?.storeCache(this._cache, cached, res);
@@ -652,8 +653,8 @@ class QueryBuilder {
652
653
  (0, core_1.helper)(entity).__serializationContext.populate ??= hint;
653
654
  hint.forEach(hint => {
654
655
  const [propName] = hint.field.split(':', 2);
655
- const value = entity[propName];
656
- if (core_1.Utils.isEntity(value, true)) {
656
+ const value = core_1.Reference.unwrapReference(entity[propName]);
657
+ if (core_1.Utils.isEntity(value)) {
657
658
  (0, core_1.helper)(value).populated();
658
659
  propagatePopulateHint(value, hint.children ?? []);
659
660
  }
@@ -794,6 +795,19 @@ class QueryBuilder {
794
795
  }
795
796
  return qb;
796
797
  }
798
+ /**
799
+ * Sets logger context for this query builder.
800
+ */
801
+ setLoggerContext(context) {
802
+ this.loggerContext = context;
803
+ }
804
+ /**
805
+ * Gets logger context for this query builder.
806
+ */
807
+ getLoggerContext() {
808
+ this.loggerContext ??= {};
809
+ return this.loggerContext;
810
+ }
797
811
  fromVirtual(meta) {
798
812
  if (typeof meta.expression === 'string') {
799
813
  return `(${meta.expression}) as ${this.platform.quoteIdentifier(this.alias)}`;
@@ -954,15 +968,19 @@ class QueryBuilder {
954
968
  /* istanbul ignore next */
955
969
  const requiresSQLConversion = meta?.props.filter(p => p.hasConvertToJSValueSQL && p.persist !== false) ?? [];
956
970
  if (this.flags.has(core_1.QueryFlag.CONVERT_CUSTOM_TYPES) && (fields.includes('*') || fields.includes(`${this.mainAlias.aliasName}.*`)) && requiresSQLConversion.length > 0) {
957
- requiresSQLConversion.forEach(p => ret.push(this.helper.mapper(p.name, this.type)));
971
+ for (const p of requiresSQLConversion) {
972
+ ret.push(this.helper.mapper(p.name, this.type));
973
+ }
958
974
  }
959
- Object.keys(this._populateMap).forEach(f => {
960
- if (!fields.includes(f.replace(/#\w+$/, '')) && type === 'where') {
975
+ for (const f of Object.keys(this._populateMap)) {
976
+ if (type === 'where' && this._joins[f]) {
961
977
  const cols = this.helper.mapJoinColumns(this.type ?? enums_1.QueryType.SELECT, this._joins[f]);
962
- ret.push(...cols);
978
+ for (const col of cols) {
979
+ ret.push(col);
980
+ }
963
981
  }
964
- });
965
- return ret;
982
+ }
983
+ return core_1.Utils.unique(ret);
966
984
  }
967
985
  init(type, data, cond) {
968
986
  this.ensureNotFinalized();
@@ -1204,8 +1222,7 @@ class QueryBuilder {
1204
1222
  // not perfect, but should work most of the time, ideally we should check only the alias (`... as alias`)
1205
1223
  return field.sql.includes(prop);
1206
1224
  }
1207
- // not perfect, but should work most of the time, ideally we should check only the alias (`... as alias`)
1208
- return field.toString().includes(prop);
1225
+ return false;
1209
1226
  });
1210
1227
  if (field instanceof core_1.RawQueryFragment) {
1211
1228
  knexQuery.select(this.platform.formatQuery(field.sql, field.params));
@@ -1221,6 +1238,27 @@ class QueryBuilder {
1221
1238
  subSubQuery.__raw = true; // tag it as there is now way to check via `instanceof`
1222
1239
  this._limit = undefined;
1223
1240
  this._offset = undefined;
1241
+ // remove joins that are not used for population or ordering to improve performance
1242
+ const populate = new Set();
1243
+ const orderByAliases = this._orderBy
1244
+ .flatMap(hint => Object.keys(hint))
1245
+ .map(k => k.split('.')[0]);
1246
+ function addPath(hints, prefix = '') {
1247
+ for (const hint of hints) {
1248
+ const field = hint.field.split(':')[0];
1249
+ populate.add((prefix ? prefix + '.' : '') + field);
1250
+ if (hint.children) {
1251
+ addPath(hint.children, (prefix ? prefix + '.' : '') + field);
1252
+ }
1253
+ }
1254
+ }
1255
+ addPath(this._populate);
1256
+ for (const [key, join] of Object.entries(this._joins)) {
1257
+ const path = join.path?.replace(/\[populate]|\[pivot]|:ref/g, '').replace(new RegExp(`^${meta.className}.`), '');
1258
+ if (!populate.has(path ?? '') && !orderByAliases.includes(join.alias)) {
1259
+ delete this._joins[key];
1260
+ }
1261
+ }
1224
1262
  this.select(this._fields).where({ [core_1.Utils.getPrimaryKeyHash(meta.primaryKeys)]: { $in: subSubQuery } });
1225
1263
  }
1226
1264
  wrapModifySubQuery(meta) {
@@ -488,7 +488,7 @@ class QueryBuilderHelper {
488
488
  const order = core_1.Utils.isNumber(direction) ? core_1.QueryOrderNumeric[direction] : direction;
489
489
  const raw = core_1.RawQueryFragment.getKnownFragment(key);
490
490
  if (raw) {
491
- ret.push(`${this.platform.formatQuery(raw.sql, raw.params)} ${order.toLowerCase()}`);
491
+ ret.push(...this.platform.getOrderByExpression(this.platform.formatQuery(raw.sql, raw.params), order));
492
492
  continue;
493
493
  }
494
494
  for (const f of core_1.Utils.splitPrimaryKeys(key)) {
@@ -518,7 +518,8 @@ class QueryBuilderHelper {
518
518
  return ret;
519
519
  }
520
520
  finalize(type, qb, meta, data, returning) {
521
- if (!meta || !data || !this.platform.usesReturningStatement()) {
521
+ const usesReturningStatement = this.platform.usesReturningStatement() || this.platform.usesOutputStatement();
522
+ if (!meta || !data || !usesReturningStatement) {
522
523
  return;
523
524
  }
524
525
  // always respect explicit returning hint
@@ -605,7 +606,11 @@ class QueryBuilderHelper {
605
606
  else {
606
607
  const [a, ...rest] = field.split('.');
607
608
  const f = rest.join('.');
608
- ret = a + '.' + this.fieldName(f, a, always, idx);
609
+ const fieldName = this.fieldName(f, a, always, idx);
610
+ if (fieldName instanceof core_1.RawQueryFragment) {
611
+ return fieldName.sql;
612
+ }
613
+ ret = a + '.' + fieldName;
609
614
  }
610
615
  if (quote) {
611
616
  return this.platform.quoteIdentifier(ret);
@@ -79,6 +79,9 @@ class DatabaseTable {
79
79
  prop.length ??= this.platform.getDefaultDateTimeLength();
80
80
  }
81
81
  }
82
+ if (prop.length == null && prop.columnTypes[idx]) {
83
+ prop.length = this.platform.getSchemaHelper().inferLengthFromColumnType(prop.columnTypes[idx]);
84
+ }
82
85
  const primary = !meta.compositePK && !!prop.primary && prop.kind === core_1.ReferenceKind.SCALAR && this.platform.isNumericColumn(mappedType);
83
86
  this.columns[field] = {
84
87
  name: prop.fieldNames[idx],
@@ -120,9 +123,19 @@ class DatabaseTable {
120
123
  if (prop.deleteRule || cascade || prop.nullable) {
121
124
  this.foreignKeys[constraintName].deleteRule = prop.deleteRule || (cascade ? 'cascade' : 'set null');
122
125
  }
123
- if (prop.updateRule || prop.cascade.includes(core_1.Cascade.PERSIST) || prop.cascade.includes(core_1.Cascade.ALL)) {
126
+ if (prop.updateRule) {
124
127
  this.foreignKeys[constraintName].updateRule = prop.updateRule || 'cascade';
125
128
  }
129
+ if ((prop.cascade.includes(core_1.Cascade.PERSIST) || prop.cascade.includes(core_1.Cascade.ALL))) {
130
+ const hasCascadePath = Object.values(this.foreignKeys).some(fk => {
131
+ return fk.constraintName !== constraintName
132
+ && ((fk.updateRule && fk.updateRule !== 'no action') || (fk.deleteRule && fk.deleteRule !== 'no action'))
133
+ && fk.referencedTableName === this.foreignKeys[constraintName].referencedTableName;
134
+ });
135
+ if (!hasCascadePath || this.platform.supportsMultipleCascadePaths()) {
136
+ this.foreignKeys[constraintName].updateRule ??= 'cascade';
137
+ }
138
+ }
126
139
  if (prop.deferMode) {
127
140
  this.foreignKeys[constraintName].deferMode = prop.deferMode;
128
141
  }
@@ -156,8 +169,7 @@ class DatabaseTable {
156
169
  }
157
170
  getEntityDeclaration(namingStrategy, schemaHelper, scalarPropertiesForRelations) {
158
171
  const { fksOnColumnProps, fksOnStandaloneProps, columnFks, fkIndexes, nullableForeignKeys, skippedColumnNames, } = this.foreignKeysToProps(namingStrategy, scalarPropertiesForRelations);
159
- let name = namingStrategy.getEntityName(this.name, this.schema);
160
- name = name.match(/^\d/) ? 'E' + name : name;
172
+ const name = namingStrategy.getEntityName(this.name, this.schema);
161
173
  const schema = new core_1.EntitySchema({ name, collection: this.name, schema: this.schema });
162
174
  const compositeFkIndexes = {};
163
175
  const compositeFkUniques = {};
@@ -589,7 +601,7 @@ class DatabaseTable {
589
601
  // The enum name will be a concatenation of the table name and the column name.
590
602
  return namingStrategy.getClassName(this.name + '_' + column.name, '_');
591
603
  }
592
- return column.mappedType?.compareAsType() ?? 'unknown';
604
+ return column.mappedType?.runtimeType ?? 'unknown';
593
605
  }
594
606
  getPropertyDefaultValue(schemaHelper, column, propType, raw = false) {
595
607
  const empty = raw ? 'null' : undefined;
@@ -273,12 +273,19 @@ class SchemaComparator {
273
273
  */
274
274
  detectColumnRenamings(tableDifferences, inverseTableDiff) {
275
275
  const renameCandidates = {};
276
+ const oldFKs = Object.values(tableDifferences.fromTable.getForeignKeys());
277
+ const newFKs = Object.values(tableDifferences.toTable.getForeignKeys());
276
278
  for (const addedColumn of Object.values(tableDifferences.addedColumns)) {
277
279
  for (const removedColumn of Object.values(tableDifferences.removedColumns)) {
278
280
  const diff = this.diffColumn(addedColumn, removedColumn);
279
281
  if (diff.size !== 0) {
280
282
  continue;
281
283
  }
284
+ const wasFK = oldFKs.some(fk => fk.columnNames.includes(removedColumn.name));
285
+ const isFK = newFKs.some(fk => fk.columnNames.includes(addedColumn.name));
286
+ if (wasFK !== isFK) {
287
+ continue;
288
+ }
282
289
  const renamedColumn = inverseTableDiff?.renamedColumns[addedColumn.name];
283
290
  if (renamedColumn && renamedColumn?.name !== removedColumn.name) {
284
291
  continue;
@@ -351,6 +358,9 @@ class SchemaComparator {
351
358
  if (key1.deferMode !== key2.deferMode) {
352
359
  return true;
353
360
  }
361
+ if (key1.localTableName === key1.referencedTableName && !this.platform.supportsMultipleCascadePaths()) {
362
+ return false;
363
+ }
354
364
  const defaultRule = ['restrict', 'no action'];
355
365
  const rule = (key, method) => {
356
366
  return (key[method] ?? defaultRule[0]).toLowerCase().replace(defaultRule[1], defaultRule[0]);
@@ -376,8 +386,8 @@ class SchemaComparator {
376
386
  }
377
387
  };
378
388
  if (fromColumnType !== toColumnType &&
379
- !(fromColumn.ignoreSchemaChanges?.includes('type') ||
380
- toColumn.ignoreSchemaChanges?.includes('type'))) {
389
+ !(fromColumn.ignoreSchemaChanges?.includes('type') || toColumn.ignoreSchemaChanges?.includes('type')) &&
390
+ !fromColumn.generated && !toColumn.generated) {
381
391
  log(`'type' changed for column ${tableName}.${fromColumn.name}`, { fromColumnType, toColumnType });
382
392
  changedProperties.add('type');
383
393
  }
@@ -471,7 +481,7 @@ class SchemaComparator {
471
481
  diffExpression(expr1, expr2) {
472
482
  // expressions like check constraints might be normalized by the driver,
473
483
  // e.g. quotes might be added (https://github.com/mikro-orm/mikro-orm/issues/3827)
474
- const simplify = (str) => str?.replace(/_\w+\\'(.*?)\\'/g, '$1').replace(/['"`()]|::\w+| +/g, '').toLowerCase();
484
+ const simplify = (str) => str?.replace(/_\w+'(.*?)'/g, '$1').replace(/['"`()]|::\w+| +/g, '').toLowerCase();
475
485
  return simplify(expr1) !== simplify(expr2);
476
486
  }
477
487
  parseJsonDefault(defaultValue) {
@@ -15,6 +15,7 @@ export declare abstract class SchemaHelper {
15
15
  finalizeTable(table: Knex.TableBuilder, charset: string, collate?: string): void;
16
16
  supportsSchemaConstraints(): boolean;
17
17
  getPrimaryKeys(connection: AbstractSqlConnection, indexes: IndexDef[] | undefined, tableName: string, schemaName?: string): Promise<string[]>;
18
+ inferLengthFromColumnType(type: string): number | undefined;
18
19
  getForeignKeys(connection: AbstractSqlConnection, tableName: string, schemaName?: string): Promise<Dictionary>;
19
20
  protected getTableKey(t: Table): string;
20
21
  getEnumDefinitions(connection: AbstractSqlConnection, checks: CheckDef[], tableName: string, schemaName?: string): Promise<Dictionary<string[]>>;
@@ -27,8 +28,9 @@ export declare abstract class SchemaHelper {
27
28
  getCreateIndexSQL(tableName: string, index: IndexDef, partialExpression?: boolean): string;
28
29
  getDropIndexSQL(tableName: string, index: IndexDef): string;
29
30
  getRenameIndexSQL(tableName: string, index: IndexDef, oldIndexName: string): string;
31
+ getDropColumnsSQL(tableName: string, columns: Column[], schemaName?: string): string;
30
32
  hasNonDefaultPrimaryKeyName(table: DatabaseTable): boolean;
31
- createTableColumn(table: Knex.TableBuilder, column: Column, fromTable: DatabaseTable, changedProperties?: Set<string>, alter?: boolean): Knex.ColumnBuilder;
33
+ createTableColumn(table: Knex.TableBuilder, column: Column, fromTable: DatabaseTable, changedProperties?: Set<string>, alter?: boolean): Knex.ColumnBuilder | undefined;
32
34
  configureColumn(column: Column, col: Knex.ColumnBuilder, knex: Knex, changedProperties?: Set<string>): Knex.ColumnBuilder;
33
35
  configureColumnDefault(column: Column, col: Knex.ColumnBuilder, knex: Knex, changedProperties?: Set<string>): Knex.ColumnBuilder;
34
36
  getPreAlterTable(tableDiff: TableDifference, safe: boolean): string;
@@ -45,6 +47,8 @@ export declare abstract class SchemaHelper {
45
47
  normalizeDefaultValue(defaultValue: string, length?: number, defaultValues?: Dictionary<string[]>): string | number;
46
48
  getCreateDatabaseSQL(name: string): string;
47
49
  getDropDatabaseSQL(name: string): string;
50
+ getCreateNamespaceSQL(name: string): string;
51
+ getDropNamespaceSQL(name: string): string;
48
52
  getDatabaseExistsSQL(name: string): string;
49
53
  getDatabaseNotExistsError(dbName: string): string;
50
54
  getManagementDbName(): string;