@mikro-orm/knex 6.1.13-dev.4 → 6.1.13-dev.40

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 (74) 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 +17 -0
  64. package/package.json +2 -2
  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 +21 -4
  69. package/schema/SchemaComparator.js +16 -3
  70. package/schema/SchemaHelper.d.ts +5 -1
  71. package/schema/SchemaHelper.js +20 -2
  72. package/schema/SqlSchemaGenerator.d.ts +12 -4
  73. package/schema/SqlSchemaGenerator.js +53 -28
  74. package/typings.d.ts +2 -1
@@ -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;
@@ -56,6 +60,7 @@ export const DateType = mod.DateType;
56
60
  export const DeadlockException = mod.DeadlockException;
57
61
  export const DecimalType = mod.DecimalType;
58
62
  export const DefaultLogger = mod.DefaultLogger;
63
+ export const DeferMode = mod.DeferMode;
59
64
  export const DoubleType = mod.DoubleType;
60
65
  export const DriverException = mod.DriverException;
61
66
  export const EagerProps = mod.EagerProps;
@@ -107,11 +112,13 @@ export const JoinType = mod.JoinType;
107
112
  export const JsonProperty = mod.JsonProperty;
108
113
  export const JsonType = mod.JsonType;
109
114
  export const Knex = mod.Knex;
115
+ export const LibSqlKnexDialect = mod.LibSqlKnexDialect;
110
116
  export const LoadStrategy = mod.LoadStrategy;
111
117
  export const LockMode = mod.LockMode;
112
118
  export const LockWaitTimeoutException = mod.LockWaitTimeoutException;
113
119
  export const ManyToMany = mod.ManyToMany;
114
120
  export const ManyToOne = mod.ManyToOne;
121
+ export const MariaDbKnexDialect = mod.MariaDbKnexDialect;
115
122
  export const MediumIntType = mod.MediumIntType;
116
123
  export const MemoryCacheAdapter = mod.MemoryCacheAdapter;
117
124
  export const MetadataDiscovery = mod.MetadataDiscovery;
@@ -122,6 +129,12 @@ export const MetadataValidator = mod.MetadataValidator;
122
129
  export const MikroORM = mod.MikroORM;
123
130
  export const MongoNamingStrategy = mod.MongoNamingStrategy;
124
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;
125
138
  export const NodeState = mod.NodeState;
126
139
  export const NonUniqueFieldNameException = mod.NonUniqueFieldNameException;
127
140
  export const NotFoundError = mod.NotFoundError;
@@ -140,6 +153,8 @@ export const OptionalProps = mod.OptionalProps;
140
153
  export const PlainObject = mod.PlainObject;
141
154
  export const Platform = mod.Platform;
142
155
  export const PopulateHint = mod.PopulateHint;
156
+ export const PopulatePath = mod.PopulatePath;
157
+ export const PostgreSqlKnexDialect = mod.PostgreSqlKnexDialect;
143
158
  export const PrimaryKey = mod.PrimaryKey;
144
159
  export const PrimaryKeyProp = mod.PrimaryKeyProp;
145
160
  export const Property = mod.Property;
@@ -172,6 +187,8 @@ export const SmallIntType = mod.SmallIntType;
172
187
  export const SqlEntityManager = mod.SqlEntityManager;
173
188
  export const SqlEntityRepository = mod.SqlEntityRepository;
174
189
  export const SqlSchemaGenerator = mod.SqlSchemaGenerator;
190
+ export const SqliteKnexDialect = mod.SqliteKnexDialect;
191
+ export const SqliteTableCompiler = mod.SqliteTableCompiler;
175
192
  export const StringType = mod.StringType;
176
193
  export const SyntaxErrorException = mod.SyntaxErrorException;
177
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.4",
3
+ "version": "6.1.13-dev.40",
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": "^6.1.12"
67
67
  },
68
68
  "peerDependencies": {
69
- "@mikro-orm/core": "6.1.13-dev.4"
69
+ "@mikro-orm/core": "6.1.13-dev.40"
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,22 @@ 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
+ }
139
+ if (prop.deferMode) {
140
+ this.foreignKeys[constraintName].deferMode = prop.deferMode;
141
+ }
126
142
  }
127
143
  if (prop.index) {
128
144
  this.indexes.push({
@@ -153,8 +169,7 @@ class DatabaseTable {
153
169
  }
154
170
  getEntityDeclaration(namingStrategy, schemaHelper, scalarPropertiesForRelations) {
155
171
  const { fksOnColumnProps, fksOnStandaloneProps, columnFks, fkIndexes, nullableForeignKeys, skippedColumnNames, } = this.foreignKeysToProps(namingStrategy, scalarPropertiesForRelations);
156
- let name = namingStrategy.getEntityName(this.name, this.schema);
157
- name = name.match(/^\d/) ? 'E' + name : name;
172
+ const name = namingStrategy.getEntityName(this.name, this.schema);
158
173
  const schema = new core_1.EntitySchema({ name, collection: this.name, schema: this.schema });
159
174
  const compositeFkIndexes = {};
160
175
  const compositeFkUniques = {};
@@ -473,6 +488,7 @@ class DatabaseTable {
473
488
  fkOptions.referencedColumnNames = fk.referencedColumnNames;
474
489
  fkOptions.updateRule = fk.updateRule?.toLowerCase();
475
490
  fkOptions.deleteRule = fk.deleteRule?.toLowerCase();
491
+ fkOptions.deferMode = fk.deferMode;
476
492
  fkOptions.columnTypes = fk.columnNames.map(c => this.getColumn(c).type);
477
493
  const columnOptions = {};
478
494
  if (fk.columnNames.length === 1) {
@@ -520,6 +536,7 @@ class DatabaseTable {
520
536
  fkOptions.referencedColumnNames = fk.referencedColumnNames;
521
537
  fkOptions.updateRule = fk.updateRule?.toLowerCase();
522
538
  fkOptions.deleteRule = fk.deleteRule?.toLowerCase();
539
+ fkOptions.deferMode = fk.deferMode;
523
540
  }
524
541
  return {
525
542
  name: prop,
@@ -584,7 +601,7 @@ class DatabaseTable {
584
601
  // The enum name will be a concatenation of the table name and the column name.
585
602
  return namingStrategy.getClassName(this.name + '_' + column.name, '_');
586
603
  }
587
- return column.mappedType?.compareAsType() ?? 'unknown';
604
+ return column.mappedType?.runtimeType ?? 'unknown';
588
605
  }
589
606
  getPropertyDefaultValue(schemaHelper, column, propType, raw = false) {
590
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;
@@ -348,6 +355,12 @@ class SchemaComparator {
348
355
  if (key1.referencedTableName !== key2.referencedTableName) {
349
356
  return true;
350
357
  }
358
+ if (key1.deferMode !== key2.deferMode) {
359
+ return true;
360
+ }
361
+ if (key1.localTableName === key1.referencedTableName && !this.platform.supportsMultipleCascadePaths()) {
362
+ return false;
363
+ }
351
364
  const defaultRule = ['restrict', 'no action'];
352
365
  const rule = (key, method) => {
353
366
  return (key[method] ?? defaultRule[0]).toLowerCase().replace(defaultRule[1], defaultRule[0]);
@@ -373,8 +386,8 @@ class SchemaComparator {
373
386
  }
374
387
  };
375
388
  if (fromColumnType !== toColumnType &&
376
- !(fromColumn.ignoreSchemaChanges?.includes('type') ||
377
- toColumn.ignoreSchemaChanges?.includes('type'))) {
389
+ !(fromColumn.ignoreSchemaChanges?.includes('type') || toColumn.ignoreSchemaChanges?.includes('type')) &&
390
+ !fromColumn.generated && !toColumn.generated) {
378
391
  log(`'type' changed for column ${tableName}.${fromColumn.name}`, { fromColumnType, toColumnType });
379
392
  changedProperties.add('type');
380
393
  }
@@ -468,7 +481,7 @@ class SchemaComparator {
468
481
  diffExpression(expr1, expr2) {
469
482
  // expressions like check constraints might be normalized by the driver,
470
483
  // e.g. quotes might be added (https://github.com/mikro-orm/mikro-orm/issues/3827)
471
- 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();
472
485
  return simplify(expr1) !== simplify(expr2);
473
486
  }
474
487
  parseJsonDefault(defaultValue) {