@mikro-orm/knex 6.0.0-dev.4 → 6.0.0-dev.41

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 (56) hide show
  1. package/{dist/AbstractSqlConnection.js → AbstractSqlConnection.js} +6 -1
  2. package/AbstractSqlDriver.d.ts +66 -0
  3. package/{dist/AbstractSqlDriver.js → AbstractSqlDriver.js} +277 -95
  4. package/{dist/AbstractSqlPlatform.d.ts → AbstractSqlPlatform.d.ts} +7 -7
  5. package/{dist/AbstractSqlPlatform.js → AbstractSqlPlatform.js} +12 -14
  6. package/{dist/README.md → README.md} +2 -2
  7. package/{dist/SqlEntityManager.d.ts → SqlEntityManager.d.ts} +5 -5
  8. package/{dist/SqlEntityManager.js → SqlEntityManager.js} +1 -2
  9. package/{dist/SqlEntityRepository.d.ts → SqlEntityRepository.d.ts} +3 -4
  10. package/{dist/SqlEntityRepository.js → SqlEntityRepository.js} +1 -2
  11. package/{dist/index.d.ts → index.d.ts} +1 -0
  12. package/{dist/index.js → index.js} +6 -1
  13. package/index.mjs +194 -0
  14. package/package.json +18 -47
  15. package/query/ArrayCriteriaNode.d.ts +9 -0
  16. package/{dist/query → query}/CriteriaNode.d.ts +8 -8
  17. package/{dist/query → query}/CriteriaNode.js +15 -12
  18. package/query/CriteriaNodeFactory.d.ts +12 -0
  19. package/{dist/query → query}/CriteriaNodeFactory.js +10 -10
  20. package/{dist/query → query}/ObjectCriteriaNode.d.ts +3 -3
  21. package/{dist/query → query}/ObjectCriteriaNode.js +19 -6
  22. package/{dist/query → query}/QueryBuilder.d.ts +66 -24
  23. package/{dist/query → query}/QueryBuilder.js +381 -94
  24. package/{dist/query → query}/QueryBuilderHelper.d.ts +19 -11
  25. package/{dist/query → query}/QueryBuilderHelper.js +227 -116
  26. package/{dist/query → query}/ScalarCriteriaNode.d.ts +2 -2
  27. package/{dist/query → query}/ScalarCriteriaNode.js +6 -6
  28. package/{dist/query → query}/index.js +5 -1
  29. package/{dist/schema → schema}/DatabaseSchema.d.ts +1 -1
  30. package/{dist/schema → schema}/DatabaseSchema.js +11 -19
  31. package/{dist/schema → schema}/DatabaseTable.d.ts +9 -9
  32. package/{dist/schema → schema}/DatabaseTable.js +22 -22
  33. package/{dist/schema → schema}/SchemaComparator.d.ts +7 -5
  34. package/{dist/schema → schema}/SchemaComparator.js +60 -10
  35. package/{dist/schema → schema}/SchemaHelper.d.ts +15 -10
  36. package/{dist/schema → schema}/SchemaHelper.js +46 -8
  37. package/{dist/schema/SchemaGenerator.d.ts → schema/SqlSchemaGenerator.d.ts} +10 -12
  38. package/{dist/schema/SchemaGenerator.js → schema/SqlSchemaGenerator.js} +89 -45
  39. package/{dist/schema → schema}/index.d.ts +1 -1
  40. package/{dist/schema → schema}/index.js +6 -2
  41. package/{dist/typings.d.ts → typings.d.ts} +21 -16
  42. package/CHANGELOG.md +0 -661
  43. package/dist/AbstractSqlDriver.d.ts +0 -55
  44. package/dist/LICENSE +0 -21
  45. package/dist/index.mjs +0 -26
  46. package/dist/package.json +0 -99
  47. package/dist/query/ArrayCriteriaNode.d.ts +0 -9
  48. package/dist/query/CriteriaNodeFactory.d.ts +0 -12
  49. /package/{dist/AbstractSqlConnection.d.ts → AbstractSqlConnection.d.ts} +0 -0
  50. /package/{dist/MonkeyPatchable.d.ts → MonkeyPatchable.d.ts} +0 -0
  51. /package/{dist/MonkeyPatchable.js → MonkeyPatchable.js} +0 -0
  52. /package/{dist/query → query}/ArrayCriteriaNode.js +0 -0
  53. /package/{dist/query → query}/enums.d.ts +0 -0
  54. /package/{dist/query → query}/enums.js +0 -0
  55. /package/{dist/query → query}/index.d.ts +0 -0
  56. /package/{dist/typings.js → typings.js} +0 -0
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[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);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -11,7 +11,7 @@ export declare class DatabaseSchema {
11
11
  private tables;
12
12
  private namespaces;
13
13
  constructor(platform: AbstractSqlPlatform, name: string);
14
- addTable(name: string, schema: string | undefined | null): DatabaseTable;
14
+ addTable(name: string, schema: string | undefined | null, comment?: string): DatabaseTable;
15
15
  getTables(): DatabaseTable[];
16
16
  getTable(name: string): DatabaseTable | undefined;
17
17
  hasTable(name: string): boolean;
@@ -13,9 +13,10 @@ class DatabaseSchema {
13
13
  this.tables = [];
14
14
  this.namespaces = new Set();
15
15
  }
16
- addTable(name, schema) {
16
+ addTable(name, schema, comment) {
17
17
  const namespaceName = schema ?? this.name;
18
18
  const table = new DatabaseTable_1.DatabaseTable(this.platform, name, namespaceName);
19
+ table.comment = comment;
19
20
  this.tables.push(table);
20
21
  if (namespaceName != null) {
21
22
  this.namespaces.add(namespaceName);
@@ -39,21 +40,12 @@ class DatabaseSchema {
39
40
  }
40
41
  static async create(connection, platform, config, schemaName) {
41
42
  const schema = new DatabaseSchema(platform, schemaName ?? config.get('schema'));
42
- const tables = await connection.execute(platform.getSchemaHelper().getListTablesSQL());
43
- for (const t of tables) {
44
- if (t.table_name === config.get('migrations').tableName) {
45
- continue;
46
- }
47
- const table = schema.addTable(t.table_name, t.schema_name);
48
- table.comment = t.table_comment;
49
- const cols = await platform.getSchemaHelper().getColumns(connection, table.name, table.schema);
50
- const indexes = await platform.getSchemaHelper().getIndexes(connection, table.name, table.schema);
51
- const checks = await platform.getSchemaHelper().getChecks(connection, table.name, table.schema);
52
- const pks = await platform.getSchemaHelper().getPrimaryKeys(connection, indexes, table.name, table.schema);
53
- const fks = await platform.getSchemaHelper().getForeignKeys(connection, table.name, table.schema);
54
- const enums = await platform.getSchemaHelper().getEnumDefinitions(connection, checks, table.name, table.schema);
55
- table.init(cols, indexes, checks, pks, fks, enums);
56
- }
43
+ const allTables = await connection.execute(platform.getSchemaHelper().getListTablesSQL());
44
+ const parts = config.get('migrations').tableName.split('.');
45
+ const migrationsTableName = parts[1] ?? parts[0];
46
+ const migrationsSchemaName = parts.length > 1 ? parts[0] : config.get('schema', platform.getDefaultSchemaName());
47
+ const tables = allTables.filter(t => t.table_name !== migrationsTableName || (t.schema_name && t.schema_name !== migrationsSchemaName));
48
+ await platform.getSchemaHelper().loadInformationSchema(schema, connection, tables);
57
49
  return schema;
58
50
  }
59
51
  static fromMetadata(metadata, platform, config, schemaName) {
@@ -86,15 +78,15 @@ class DatabaseSchema {
86
78
  if (prop.persist === false || !prop.fieldNames) {
87
79
  return false;
88
80
  }
89
- if (meta.pivotTable || (core_1.ReferenceType.EMBEDDED && prop.object)) {
81
+ if (meta.pivotTable || (core_1.ReferenceKind.EMBEDDED && prop.object)) {
90
82
  return true;
91
83
  }
92
84
  const getRootProperty = (prop) => prop.embedded ? getRootProperty(meta.properties[prop.embedded[0]]) : prop;
93
85
  const rootProp = getRootProperty(prop);
94
- if (rootProp.reference === core_1.ReferenceType.EMBEDDED) {
86
+ if (rootProp.kind === core_1.ReferenceKind.EMBEDDED) {
95
87
  return prop === rootProp || !rootProp.object;
96
88
  }
97
- return [core_1.ReferenceType.SCALAR, core_1.ReferenceType.MANY_TO_ONE].includes(prop.reference) || (prop.reference === core_1.ReferenceType.ONE_TO_ONE && prop.owner);
89
+ return [core_1.ReferenceKind.SCALAR, core_1.ReferenceKind.MANY_TO_ONE].includes(prop.kind) || (prop.kind === core_1.ReferenceKind.ONE_TO_ONE && prop.owner);
98
90
  }
99
91
  toJSON() {
100
92
  const { platform, namespaces, ...rest } = this;
@@ -1,6 +1,6 @@
1
1
  import type { Dictionary, EntityMetadata, EntityProperty, NamingStrategy } from '@mikro-orm/core';
2
2
  import type { SchemaHelper } from './SchemaHelper';
3
- import type { Check, Column, ForeignKey, Index } from '../typings';
3
+ import type { CheckDef, Column, ForeignKey, IndexDef } from '../typings';
4
4
  import type { AbstractSqlPlatform } from '../AbstractSqlPlatform';
5
5
  /**
6
6
  * @internal
@@ -17,9 +17,9 @@ export declare class DatabaseTable {
17
17
  constructor(platform: AbstractSqlPlatform, name: string, schema?: string | undefined);
18
18
  getColumns(): Column[];
19
19
  getColumn(name: string): Column | undefined;
20
- getIndexes(): Index[];
21
- getChecks(): Check[];
22
- init(cols: Column[], indexes: Index[], checks: Check[], pks: string[], fks: Dictionary<ForeignKey>, enums: Dictionary<string[]>): void;
20
+ getIndexes(): IndexDef[];
21
+ getChecks(): CheckDef[];
22
+ init(cols: Column[], indexes: IndexDef[] | undefined, checks: CheckDef<unknown>[] | undefined, pks: string[], fks?: Dictionary<ForeignKey>, enums?: Dictionary<string[]>): void;
23
23
  addColumn(column: Column): void;
24
24
  addColumnFromProperty(prop: EntityProperty, meta: EntityMetadata): void;
25
25
  private getIndexName;
@@ -30,14 +30,14 @@ export declare class DatabaseTable {
30
30
  getShortestName(): string;
31
31
  getForeignKeys(): Dictionary<ForeignKey>;
32
32
  hasColumn(columnName: string): boolean;
33
- getIndex(indexName: string): Index | undefined;
33
+ getIndex(indexName: string): IndexDef | undefined;
34
34
  hasIndex(indexName: string): boolean;
35
- getCheck(checkName: string): Check<unknown> | undefined;
35
+ getCheck(checkName: string): CheckDef<unknown> | undefined;
36
36
  hasCheck(checkName: string): boolean;
37
- getPrimaryKey(): Index | undefined;
37
+ getPrimaryKey(): IndexDef | undefined;
38
38
  hasPrimaryKey(): boolean;
39
39
  private getPropertyDeclaration;
40
- private getReferenceType;
40
+ private getReferenceKind;
41
41
  private getPropertyName;
42
42
  private getPropertyType;
43
43
  private getPropertyDefaultValue;
@@ -48,6 +48,6 @@ export declare class DatabaseTable {
48
48
  expression?: string;
49
49
  options?: Dictionary;
50
50
  }, type: 'index' | 'unique' | 'primary'): void;
51
- addCheck(check: Check): void;
51
+ addCheck(check: CheckDef): void;
52
52
  toJSON(): Dictionary;
53
53
  }
@@ -30,7 +30,7 @@ class DatabaseTable {
30
30
  getChecks() {
31
31
  return this.checks;
32
32
  }
33
- init(cols, indexes, checks, pks, fks, enums) {
33
+ init(cols, indexes = [], checks = [], pks, fks = {}, enums = {}) {
34
34
  this.indexes = indexes;
35
35
  this.checks = checks;
36
36
  this.foreignKeys = fks;
@@ -51,7 +51,6 @@ class DatabaseTable {
51
51
  }
52
52
  addColumnFromProperty(prop, meta) {
53
53
  prop.fieldNames.forEach((field, idx) => {
54
- var _a;
55
54
  const type = prop.enum ? 'enum' : prop.columnTypes[idx];
56
55
  const mappedType = this.platform.getMappedType(type);
57
56
  if (mappedType instanceof core_1.DecimalType) {
@@ -64,9 +63,9 @@ class DatabaseTable {
64
63
  }
65
64
  }
66
65
  if (mappedType instanceof core_1.DateTimeType) {
67
- prop.length ?? (prop.length = this.platform.getDefaultDateTimeLength());
66
+ prop.length ??= this.platform.getDefaultDateTimeLength();
68
67
  }
69
- const primary = !meta.compositePK && !!prop.primary && prop.reference === core_1.ReferenceType.SCALAR && this.platform.isNumericColumn(mappedType);
68
+ const primary = !meta.compositePK && !!prop.primary && prop.kind === core_1.ReferenceKind.SCALAR && this.platform.isNumericColumn(mappedType);
70
69
  this.columns[field] = {
71
70
  name: prop.fieldNames[idx],
72
71
  type: prop.columnTypes[idx],
@@ -82,12 +81,13 @@ class DatabaseTable {
82
81
  enumItems: prop.items?.every(core_1.Utils.isString) ? prop.items : undefined,
83
82
  comment: prop.comment,
84
83
  extra: prop.extra,
84
+ ignoreSchemaChanges: prop.ignoreSchemaChanges,
85
85
  };
86
- (_a = this.columns[field]).unsigned || (_a.unsigned = this.columns[field].autoincrement);
86
+ this.columns[field].unsigned ||= this.columns[field].autoincrement;
87
87
  const defaultValue = this.platform.getSchemaHelper().normalizeDefaultValue(prop.defaultRaw, prop.length);
88
88
  this.columns[field].default = defaultValue;
89
89
  });
90
- if ([core_1.ReferenceType.MANY_TO_ONE, core_1.ReferenceType.ONE_TO_ONE].includes(prop.reference)) {
90
+ if ([core_1.ReferenceKind.MANY_TO_ONE, core_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
91
91
  const constraintName = this.getIndexName(true, prop.fieldNames, 'foreign');
92
92
  let schema = prop.targetMeta.schema === '*' ? this.schema : prop.targetMeta.schema ?? this.schema;
93
93
  if (prop.referencedTableName.includes('.')) {
@@ -101,11 +101,11 @@ class DatabaseTable {
101
101
  referencedTableName: schema ? `${schema}.${prop.referencedTableName}` : prop.referencedTableName,
102
102
  };
103
103
  const cascade = prop.cascade.includes(core_1.Cascade.REMOVE) || prop.cascade.includes(core_1.Cascade.ALL);
104
- if (prop.onDelete || cascade || prop.nullable) {
105
- this.foreignKeys[constraintName].deleteRule = prop.onDelete || (cascade ? 'cascade' : 'set null');
104
+ if (prop.deleteRule || cascade || prop.nullable) {
105
+ this.foreignKeys[constraintName].deleteRule = prop.deleteRule || (cascade ? 'cascade' : 'set null');
106
106
  }
107
- if (prop.onUpdateIntegrity || prop.cascade.includes(core_1.Cascade.PERSIST) || prop.cascade.includes(core_1.Cascade.ALL)) {
108
- this.foreignKeys[constraintName].updateRule = prop.onUpdateIntegrity || 'cascade';
107
+ if (prop.updateRule || prop.cascade.includes(core_1.Cascade.PERSIST) || prop.cascade.includes(core_1.Cascade.ALL)) {
108
+ this.foreignKeys[constraintName].updateRule = prop.updateRule || 'cascade';
109
109
  }
110
110
  }
111
111
  if (prop.index) {
@@ -163,8 +163,8 @@ class DatabaseTable {
163
163
  }
164
164
  const meta = schema.init().meta;
165
165
  meta.relations
166
- .filter(prop => prop.primary && prop.reference === core_1.ReferenceType.MANY_TO_ONE && !meta.compositePK)
167
- .forEach(prop => prop.reference = core_1.ReferenceType.ONE_TO_ONE);
166
+ .filter(prop => prop.primary && prop.kind === core_1.ReferenceKind.MANY_TO_ONE && !meta.compositePK)
167
+ .forEach(prop => prop.kind = core_1.ReferenceKind.ONE_TO_ONE);
168
168
  return meta;
169
169
  }
170
170
  /**
@@ -205,20 +205,20 @@ class DatabaseTable {
205
205
  const prop = this.getPropertyName(namingStrategy, column);
206
206
  const index = compositeFkIndexes[prop] || this.indexes.find(idx => idx.columnNames[0] === column.name && !idx.composite && !idx.unique && !idx.primary);
207
207
  const unique = compositeFkUniques[prop] || this.indexes.find(idx => idx.columnNames[0] === column.name && !idx.composite && idx.unique && !idx.primary);
208
- const reference = this.getReferenceType(fk, unique);
208
+ const kind = this.getReferenceKind(fk, unique);
209
209
  const type = this.getPropertyType(namingStrategy, column, fk);
210
210
  const fkOptions = {};
211
211
  if (fk) {
212
212
  fkOptions.fieldNames = fk.columnNames;
213
213
  fkOptions.referencedTableName = fk.referencedTableName;
214
214
  fkOptions.referencedColumnNames = fk.referencedColumnNames;
215
- fkOptions.onUpdateIntegrity = fk.updateRule?.toLowerCase();
216
- fkOptions.onDelete = fk.deleteRule?.toLowerCase();
215
+ fkOptions.updateRule = fk.updateRule?.toLowerCase();
216
+ fkOptions.deleteRule = fk.deleteRule?.toLowerCase();
217
217
  }
218
218
  return {
219
219
  name: prop,
220
220
  type,
221
- reference,
221
+ kind,
222
222
  columnType: column.type,
223
223
  default: this.getPropertyDefaultValue(schemaHelper, column, type),
224
224
  defaultRaw: this.getPropertyDefaultValue(schemaHelper, column, type, true),
@@ -233,14 +233,14 @@ class DatabaseTable {
233
233
  ...fkOptions,
234
234
  };
235
235
  }
236
- getReferenceType(fk, unique) {
236
+ getReferenceKind(fk, unique) {
237
237
  if (fk && unique) {
238
- return core_1.ReferenceType.ONE_TO_ONE;
238
+ return core_1.ReferenceKind.ONE_TO_ONE;
239
239
  }
240
240
  if (fk) {
241
- return core_1.ReferenceType.MANY_TO_ONE;
241
+ return core_1.ReferenceKind.MANY_TO_ONE;
242
242
  }
243
- return core_1.ReferenceType.SCALAR;
243
+ return core_1.ReferenceKind.SCALAR;
244
244
  }
245
245
  getPropertyName(namingStrategy, column) {
246
246
  const fk = Object.values(this.foreignKeys).find(fk => fk.columnNames.includes(column.name));
@@ -307,10 +307,10 @@ class DatabaseTable {
307
307
  }
308
308
  toJSON() {
309
309
  const { platform, columns, ...rest } = this;
310
- const columnsMapped = Object.keys(columns).reduce((o, col) => {
310
+ const columnsMapped = core_1.Utils.keys(columns).reduce((o, col) => {
311
311
  const { mappedType, ...restCol } = columns[col];
312
312
  o[col] = restCol;
313
- o[col].mappedType = Object.keys(core_1.t).find(k => core_1.t[k] === mappedType.constructor);
313
+ o[col].mappedType = core_1.Utils.keys(core_1.t).find(k => core_1.t[k] === mappedType.constructor);
314
314
  return o;
315
315
  }, {});
316
316
  return { columns: columnsMapped, ...rest };
@@ -1,4 +1,4 @@
1
- import type { Check, Column, ForeignKey, Index, SchemaDifference, TableDifference } from '../typings';
1
+ import type { CheckDef, Column, ForeignKey, IndexDef, SchemaDifference, TableDifference } from '../typings';
2
2
  import type { DatabaseSchema } from './DatabaseSchema';
3
3
  import type { DatabaseTable } from './DatabaseTable';
4
4
  import type { AbstractSqlPlatform } from '../AbstractSqlPlatform';
@@ -8,6 +8,7 @@ import type { AbstractSqlPlatform } from '../AbstractSqlPlatform';
8
8
  export declare class SchemaComparator {
9
9
  private readonly platform;
10
10
  private readonly helper;
11
+ private readonly logger;
11
12
  constructor(platform: AbstractSqlPlatform);
12
13
  /**
13
14
  * Returns a SchemaDifference object containing the differences between the schemas fromSchema and toSchema.
@@ -37,19 +38,20 @@ export declare class SchemaComparator {
37
38
  * Returns the difference between the columns
38
39
  * If there are differences this method returns field2, otherwise the boolean false.
39
40
  */
40
- diffColumn(column1: Column, column2: Column): Set<string>;
41
+ diffColumn(column1: Column, column2: Column, tableName?: string): Set<string>;
41
42
  diffEnumItems(items1?: string[], items2?: string[]): boolean;
42
43
  diffComment(comment1?: string, comment2?: string): boolean;
43
44
  /**
44
45
  * Finds the difference between the indexes index1 and index2.
45
46
  * Compares index1 with index2 and returns index2 if there are any differences or false in case there are no differences.
46
47
  */
47
- diffIndex(index1: Index, index2: Index): boolean;
48
+ diffIndex(index1: IndexDef, index2: IndexDef): boolean;
48
49
  /**
49
50
  * Checks if the other index already fulfills all the indexing and constraint needs of the current one.
50
51
  */
51
- isIndexFulfilledBy(index1: Index, index2: Index): boolean;
52
- diffCheck(check1: Check, check2: Check): boolean;
52
+ isIndexFulfilledBy(index1: IndexDef, index2: IndexDef): boolean;
53
+ diffCheck(check1: CheckDef, check2: CheckDef): boolean;
53
54
  hasSameDefaultValue(from: Column, to: Column): boolean;
54
55
  private mapColumnToProperty;
56
+ private log;
55
57
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SchemaComparator = void 0;
4
+ const util_1 = require("util");
4
5
  const core_1 = require("@mikro-orm/core");
5
6
  /**
6
7
  * Compares two Schemas and return an instance of SchemaDifference.
@@ -9,6 +10,7 @@ class SchemaComparator {
9
10
  constructor(platform) {
10
11
  this.platform = platform;
11
12
  this.helper = this.platform.getSchemaHelper();
13
+ this.logger = this.platform.getConfig().getLogger();
12
14
  }
13
15
  /**
14
16
  * Returns a SchemaDifference object containing the differences between the schemas fromSchema and toSchema.
@@ -105,18 +107,22 @@ class SchemaComparator {
105
107
  renamedColumns: {},
106
108
  renamedIndexes: {},
107
109
  fromTable,
110
+ toTable,
108
111
  };
109
112
  if (this.diffComment(fromTable.comment, toTable.comment)) {
110
113
  tableDifferences.changedComment = toTable.comment;
114
+ this.log(`table comment changed for ${tableDifferences.name}`, { fromTableComment: fromTable.comment, toTableComment: toTable.comment });
111
115
  }
112
116
  const fromTableColumns = fromTable.getColumns();
113
117
  const toTableColumns = toTable.getColumns();
118
+ const tableName = (toTable.schema ? toTable.schema + '.' : '') + toTable.name;
114
119
  // See if all the columns in "from" table exist in "to" table
115
120
  for (const column of toTableColumns) {
116
121
  if (fromTable.hasColumn(column.name)) {
117
122
  continue;
118
123
  }
119
124
  tableDifferences.addedColumns[column.name] = column;
125
+ this.log(`column ${tableDifferences.name}.${column.name} of type ${column.type} added`);
120
126
  changes++;
121
127
  }
122
128
  /* See if there are any removed columns in "to" table */
@@ -124,11 +130,12 @@ class SchemaComparator {
124
130
  // See if column is removed in "to" table.
125
131
  if (!toTable.hasColumn(column.name)) {
126
132
  tableDifferences.removedColumns[column.name] = column;
133
+ this.log(`column ${tableDifferences.name}.${column.name} removed`);
127
134
  changes++;
128
135
  continue;
129
136
  }
130
137
  // See if column has changed properties in "to" table.
131
- const changedProperties = this.diffColumn(column, toTable.getColumn(column.name));
138
+ const changedProperties = this.diffColumn(column, toTable.getColumn(column.name), tableName);
132
139
  if (changedProperties.size === 0) {
133
140
  continue;
134
141
  }
@@ -138,6 +145,7 @@ class SchemaComparator {
138
145
  column: toTable.getColumn(column.name),
139
146
  changedProperties,
140
147
  };
148
+ this.log(`column ${tableDifferences.name}.${column.name} changed`, { changedProperties });
141
149
  changes++;
142
150
  }
143
151
  this.detectColumnRenamings(tableDifferences);
@@ -149,6 +157,7 @@ class SchemaComparator {
149
157
  continue;
150
158
  }
151
159
  tableDifferences.addedIndexes[index.keyName] = index;
160
+ this.log(`index ${index.keyName} added to table ${tableDifferences.name}`, { index });
152
161
  changes++;
153
162
  }
154
163
  // See if there are any removed indexes in "to" table
@@ -156,6 +165,7 @@ class SchemaComparator {
156
165
  // See if index is removed in "to" table.
157
166
  if ((index.primary && !toTable.hasPrimaryKey()) || !index.primary && !toTable.hasIndex(index.keyName)) {
158
167
  tableDifferences.removedIndexes[index.keyName] = index;
168
+ this.log(`index ${index.keyName} removed from table ${tableDifferences.name}`);
159
169
  changes++;
160
170
  continue;
161
171
  }
@@ -165,6 +175,7 @@ class SchemaComparator {
165
175
  continue;
166
176
  }
167
177
  tableDifferences.changedIndexes[index.keyName] = toTableIndex;
178
+ this.log(`index ${index.keyName} changed in table ${tableDifferences.name}`, { fromTableIndex: index, toTableIndex });
168
179
  changes++;
169
180
  }
170
181
  this.detectIndexRenamings(tableDifferences);
@@ -176,12 +187,14 @@ class SchemaComparator {
176
187
  continue;
177
188
  }
178
189
  tableDifferences.addedChecks[check.name] = check;
190
+ this.log(`check constraint ${check.name} added to table ${tableDifferences.name}`, { check });
179
191
  changes++;
180
192
  }
181
193
  // See if there are any removed checks in "to" table
182
194
  for (const check of fromTableChecks) {
183
195
  if (!toTable.hasCheck(check.name)) {
184
196
  tableDifferences.removedChecks[check.name] = check;
197
+ this.log(`check constraint ${check.name} removed from table ${tableDifferences.name}`);
185
198
  changes++;
186
199
  continue;
187
200
  }
@@ -190,6 +203,7 @@ class SchemaComparator {
190
203
  if (!this.diffCheck(check, toTableCheck)) {
191
204
  continue;
192
205
  }
206
+ this.log(`check constraint ${check.name} changed in table ${tableDifferences.name}`, { fromTableCheck: check, toTableCheck });
193
207
  tableDifferences.changedChecks[check.name] = toTableCheck;
194
208
  changes++;
195
209
  }
@@ -202,6 +216,7 @@ class SchemaComparator {
202
216
  delete toForeignKeys[toConstraint.constraintName];
203
217
  }
204
218
  else if (fromConstraint.constraintName.toLowerCase() === toConstraint.constraintName.toLowerCase()) {
219
+ this.log(`FK constraint ${fromConstraint.constraintName} changed in table ${tableDifferences.name}`, { fromConstraint, toConstraint });
205
220
  tableDifferences.changedForeignKeys[toConstraint.constraintName] = toConstraint;
206
221
  changes++;
207
222
  delete fromForeignKeys[fromConstraint.constraintName];
@@ -211,10 +226,12 @@ class SchemaComparator {
211
226
  }
212
227
  for (const fromConstraint of Object.values(fromForeignKeys)) {
213
228
  tableDifferences.removedForeignKeys[fromConstraint.constraintName] = fromConstraint;
229
+ this.log(`FK constraint ${fromConstraint.constraintName} removed from table ${tableDifferences.name}`);
214
230
  changes++;
215
231
  }
216
232
  for (const toConstraint of Object.values(toForeignKeys)) {
217
233
  tableDifferences.addedForeignKeys[toConstraint.constraintName] = toConstraint;
234
+ this.log(`FK constraint ${toConstraint.constraintName} added from table ${tableDifferences.name}`, { constraint: toConstraint });
218
235
  changes++;
219
236
  }
220
237
  return changes ? tableDifferences : false;
@@ -249,6 +266,7 @@ class SchemaComparator {
249
266
  tableDifferences.renamedColumns[removedColumnName] = addedColumn;
250
267
  delete tableDifferences.addedColumns[addedColumnName];
251
268
  delete tableDifferences.removedColumns[removedColumnName];
269
+ this.log(`renamed column detected in table ${tableDifferences.name}`, { old: removedColumnName, new: addedColumnName });
252
270
  }
253
271
  }
254
272
  /**
@@ -282,6 +300,7 @@ class SchemaComparator {
282
300
  tableDifferences.renamedIndexes[removedIndexName] = addedIndex;
283
301
  delete tableDifferences.addedIndexes[addedIndexName];
284
302
  delete tableDifferences.removedIndexes[removedIndexName];
303
+ this.log(`renamed index detected in table ${tableDifferences.name}`, { old: removedIndexName, new: addedIndexName });
285
304
  }
286
305
  }
287
306
  diffForeignKey(key1, key2) {
@@ -294,7 +313,10 @@ class SchemaComparator {
294
313
  if (key1.referencedTableName !== key2.referencedTableName) {
295
314
  return true;
296
315
  }
297
- const rule = (key, method) => (key[method] ?? this.platform.getDefaultIntegrityRule()).toLowerCase();
316
+ const defaultRule = ['restrict', 'no action'];
317
+ const rule = (key, method) => {
318
+ return (key[method] ?? defaultRule[0]).toLowerCase().replace(defaultRule[1], defaultRule[0]);
319
+ };
298
320
  const compare = (method) => rule(key1, method) === rule(key2, method);
299
321
  return !compare('updateRule') || !compare('deleteRule');
300
322
  }
@@ -302,34 +324,53 @@ class SchemaComparator {
302
324
  * Returns the difference between the columns
303
325
  * If there are differences this method returns field2, otherwise the boolean false.
304
326
  */
305
- diffColumn(column1, column2) {
327
+ diffColumn(column1, column2, tableName) {
306
328
  const changedProperties = new Set();
307
329
  const prop1 = this.mapColumnToProperty({ ...column1, autoincrement: false });
308
330
  const prop2 = this.mapColumnToProperty({ ...column2, autoincrement: false });
309
- const columnType1 = column1.mappedType.getColumnType(prop1, this.platform);
310
- const columnType2 = column2.mappedType.getColumnType(prop2, this.platform);
311
- if (columnType1 !== columnType2) {
331
+ const columnType1 = column1.mappedType.getColumnType(prop1, this.platform).toLowerCase();
332
+ const columnType2 = column2.mappedType.getColumnType(prop2, this.platform).toLowerCase();
333
+ const log = (msg, params) => {
334
+ if (tableName) {
335
+ const copy = core_1.Utils.copy(params);
336
+ core_1.Utils.dropUndefinedProperties(copy);
337
+ this.log(msg, copy);
338
+ }
339
+ };
340
+ if (columnType1 !== columnType2 &&
341
+ !(column1.ignoreSchemaChanges?.includes('type') ||
342
+ column2.ignoreSchemaChanges?.includes('type'))) {
343
+ log(`'type' changed for column ${tableName}.${column1.name}`, { columnType1, columnType2 });
312
344
  changedProperties.add('type');
313
345
  }
314
346
  if (column1.nullable !== column2.nullable) {
347
+ log(`'nullable' changed for column ${tableName}.${column1.name}`, { column1, column2 });
315
348
  changedProperties.add('nullable');
316
349
  }
317
350
  if (!!column1.autoincrement !== !!column2.autoincrement) {
351
+ log(`'autoincrement' changed for column ${tableName}.${column1.name}`, { column1, column2 });
318
352
  changedProperties.add('autoincrement');
319
353
  }
320
354
  if (column1.unsigned !== column2.unsigned && this.platform.supportsUnsigned()) {
355
+ log(`'unsigned' changed for column ${tableName}.${column1.name}`, { column1, column2 });
321
356
  changedProperties.add('unsigned');
322
357
  }
323
358
  if (!this.hasSameDefaultValue(column1, column2)) {
359
+ log(`'default' changed for column ${tableName}.${column1.name}`, { column1, column2 });
324
360
  changedProperties.add('default');
325
361
  }
326
362
  if (this.diffComment(column1.comment, column2.comment)) {
363
+ log(`'comment' changed for column ${tableName}.${column1.name}`, { column1, column2 });
327
364
  changedProperties.add('comment');
328
365
  }
329
366
  if (this.diffEnumItems(column1.enumItems, column2.enumItems)) {
367
+ log(`'enumItems' changed for column ${tableName}.${column1.name}`, { column1, column2 });
330
368
  changedProperties.add('enumItems');
331
369
  }
332
- if ((column1.extra || '').toLowerCase() !== (column2.extra || '').toLowerCase()) {
370
+ if ((column1.extra || '').toLowerCase() !== (column2.extra || '').toLowerCase() &&
371
+ !(column1.ignoreSchemaChanges?.includes('extra') ||
372
+ column2.ignoreSchemaChanges?.includes('extra'))) {
373
+ log(`'extra' changed for column ${tableName}.${column1.name}`, { column1, column2 });
333
374
  changedProperties.add('extra');
334
375
  }
335
376
  return changedProperties;
@@ -347,8 +388,8 @@ class SchemaComparator {
347
388
  * Compares index1 with index2 and returns index2 if there are any differences or false in case there are no differences.
348
389
  */
349
390
  diffIndex(index1, index2) {
350
- // if one of them is a custom expression, compare only by name
351
- if (index1.expression || index2.expression) {
391
+ // if one of them is a custom expression or full text index, compare only by name
392
+ if (index1.expression || index2.expression || index1.type === 'fulltext' || index2.type === 'fulltext') {
352
393
  return index1.keyName !== index2.keyName;
353
394
  }
354
395
  return !this.isIndexFulfilledBy(index1, index2) || !this.isIndexFulfilledBy(index2, index1);
@@ -384,7 +425,10 @@ class SchemaComparator {
384
425
  return index1.primary === index2.primary && index1.unique === index2.unique;
385
426
  }
386
427
  diffCheck(check1, check2) {
387
- return check1.expression !== check2.expression;
428
+ // check constraint definition might be normalized by the driver,
429
+ // e.g. quotes might be added (https://github.com/mikro-orm/mikro-orm/issues/3827)
430
+ const simplify = (str) => str?.replace(/['"`()]/g, '').toLowerCase();
431
+ return simplify(check1.expression) !== simplify(check2.expression);
388
432
  }
389
433
  hasSameDefaultValue(from, to) {
390
434
  if (from.default == null || from.default.toString().toLowerCase() === 'null' || from.default.toString().startsWith('nextval(')) {
@@ -423,5 +467,11 @@ class SchemaComparator {
423
467
  scale: match ? +match[2] : column.scale,
424
468
  };
425
469
  }
470
+ log(message, params) {
471
+ if (params) {
472
+ message += ' ' + (0, util_1.inspect)(params);
473
+ }
474
+ this.logger.log('schema', message);
475
+ }
426
476
  }
427
477
  exports.SchemaComparator = SchemaComparator;
@@ -2,8 +2,9 @@ import type { Knex } from 'knex';
2
2
  import type { Connection, Dictionary } from '@mikro-orm/core';
3
3
  import type { AbstractSqlConnection } from '../AbstractSqlConnection';
4
4
  import type { AbstractSqlPlatform } from '../AbstractSqlPlatform';
5
- import type { Check, Column, Index, TableDifference } from '../typings';
5
+ import type { CheckDef, Column, IndexDef, Table, TableDifference } from '../typings';
6
6
  import type { DatabaseTable } from './DatabaseTable';
7
+ import type { DatabaseSchema } from './DatabaseSchema';
7
8
  export declare abstract class SchemaHelper {
8
9
  protected readonly platform: AbstractSqlPlatform;
9
10
  constructor(platform: AbstractSqlPlatform);
@@ -13,24 +14,28 @@ export declare abstract class SchemaHelper {
13
14
  getSchemaEnd(): string;
14
15
  finalizeTable(table: Knex.TableBuilder, charset: string, collate?: string): void;
15
16
  supportsSchemaConstraints(): boolean;
16
- getPrimaryKeys(connection: AbstractSqlConnection, indexes: Index[], tableName: string, schemaName?: string): Promise<string[]>;
17
+ getPrimaryKeys(connection: AbstractSqlConnection, indexes: IndexDef[] | undefined, tableName: string, schemaName?: string): Promise<string[]>;
17
18
  getForeignKeys(connection: AbstractSqlConnection, tableName: string, schemaName?: string): Promise<Dictionary>;
18
- getEnumDefinitions(connection: AbstractSqlConnection, checks: Check[], tableName: string, schemaName?: string): Promise<Dictionary<string[]>>;
19
+ protected getTableKey(t: Table): string;
20
+ getEnumDefinitions(connection: AbstractSqlConnection, checks: CheckDef[], tableName: string, schemaName?: string): Promise<Dictionary<string[]>>;
21
+ loadInformationSchema(schema: DatabaseSchema, connection: AbstractSqlConnection, tables: Table[]): Promise<void>;
19
22
  getListTablesSQL(schemaName?: string): string;
20
- getRenameColumnSQL(tableName: string, oldColumnName: string, to: Column): string;
21
- getCreateIndexSQL(tableName: string, index: Index): string;
22
- getDropIndexSQL(tableName: string, index: Index): string;
23
- getRenameIndexSQL(tableName: string, index: Index, oldIndexName: string): string;
23
+ getRenameColumnSQL(tableName: string, oldColumnName: string, to: Column, schemaName?: string): string;
24
+ getCreateIndexSQL(tableName: string, index: IndexDef): string;
25
+ getDropIndexSQL(tableName: string, index: IndexDef): string;
26
+ getRenameIndexSQL(tableName: string, index: IndexDef, oldIndexName: string): string;
27
+ hasNonDefaultPrimaryKeyName(table: DatabaseTable): boolean;
24
28
  createTableColumn(table: Knex.TableBuilder, column: Column, fromTable: DatabaseTable, changedProperties?: Set<string>): Knex.ColumnBuilder;
25
29
  configureColumn(column: Column, col: Knex.ColumnBuilder, knex: Knex, changedProperties?: Set<string>): Knex.ColumnBuilder;
26
30
  configureColumnDefault(column: Column, col: Knex.ColumnBuilder, knex: Knex, changedProperties?: Set<string>): Knex.ColumnBuilder;
27
31
  getPreAlterTable(tableDiff: TableDifference, safe: boolean): string;
28
32
  getAlterColumnAutoincrement(tableName: string, column: Column): string;
29
33
  getChangeColumnCommentSQL(tableName: string, to: Column): string;
34
+ getNamespaces(connection: AbstractSqlConnection): Promise<string[]>;
30
35
  getColumns(connection: AbstractSqlConnection, tableName: string, schemaName?: string): Promise<Column[]>;
31
- getIndexes(connection: AbstractSqlConnection, tableName: string, schemaName?: string): Promise<Index[]>;
32
- getChecks(connection: AbstractSqlConnection, tableName: string, schemaName?: string): Promise<Check[]>;
33
- protected mapIndexes(indexes: Index[]): Promise<Index[]>;
36
+ getIndexes(connection: AbstractSqlConnection, tableName: string, schemaName?: string): Promise<IndexDef[]>;
37
+ getChecks(connection: AbstractSqlConnection, tableName: string, schemaName?: string, columns?: Column[]): Promise<CheckDef[]>;
38
+ protected mapIndexes(indexes: IndexDef[]): Promise<IndexDef[]>;
34
39
  getForeignKeysSQL(tableName: string, schemaName?: string): string;
35
40
  mapForeignKeys(fks: any[], tableName: string, schemaName?: string): Dictionary;
36
41
  normalizeDefaultValue(defaultValue: string, length?: number, defaultValues?: Dictionary<string[]>): string | number;