@mikro-orm/knex 6.0.0-dev.2 → 6.0.0-dev.5

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 (53) hide show
  1. package/{dist/AbstractSqlConnection.d.ts → AbstractSqlConnection.d.ts} +0 -0
  2. package/{dist/AbstractSqlConnection.js → AbstractSqlConnection.js} +5 -0
  3. package/AbstractSqlDriver.d.ts +66 -0
  4. package/{dist/AbstractSqlDriver.js → AbstractSqlDriver.js} +218 -70
  5. package/{dist/AbstractSqlPlatform.d.ts → AbstractSqlPlatform.d.ts} +6 -4
  6. package/{dist/AbstractSqlPlatform.js → AbstractSqlPlatform.js} +18 -7
  7. package/{dist/MonkeyPatchable.d.ts → MonkeyPatchable.d.ts} +0 -0
  8. package/{dist/MonkeyPatchable.js → MonkeyPatchable.js} +0 -0
  9. package/{dist/README.md → README.md} +2 -2
  10. package/{dist/SqlEntityManager.d.ts → SqlEntityManager.d.ts} +5 -5
  11. package/{dist/SqlEntityManager.js → SqlEntityManager.js} +0 -1
  12. package/{dist/SqlEntityRepository.d.ts → SqlEntityRepository.d.ts} +3 -3
  13. package/{dist/SqlEntityRepository.js → SqlEntityRepository.js} +1 -1
  14. package/{dist/index.d.ts → index.d.ts} +0 -0
  15. package/{dist/index.js → index.js} +5 -1
  16. package/{dist/index.mjs → index.mjs} +0 -0
  17. package/package.json +27 -22
  18. package/{dist/query → query}/ArrayCriteriaNode.d.ts +0 -0
  19. package/{dist/query → query}/ArrayCriteriaNode.js +0 -0
  20. package/{dist/query → query}/CriteriaNode.d.ts +0 -0
  21. package/{dist/query → query}/CriteriaNode.js +7 -4
  22. package/{dist/query → query}/CriteriaNodeFactory.d.ts +0 -0
  23. package/{dist/query → query}/CriteriaNodeFactory.js +0 -0
  24. package/{dist/query → query}/ObjectCriteriaNode.d.ts +0 -0
  25. package/{dist/query → query}/ObjectCriteriaNode.js +14 -1
  26. package/{dist/query → query}/QueryBuilder.d.ts +58 -24
  27. package/{dist/query → query}/QueryBuilder.js +285 -84
  28. package/{dist/query → query}/QueryBuilderHelper.d.ts +19 -11
  29. package/{dist/query → query}/QueryBuilderHelper.js +206 -108
  30. package/{dist/query → query}/ScalarCriteriaNode.d.ts +0 -0
  31. package/{dist/query → query}/ScalarCriteriaNode.js +0 -0
  32. package/{dist/query → query}/enums.d.ts +0 -0
  33. package/{dist/query → query}/enums.js +0 -0
  34. package/{dist/query → query}/index.d.ts +0 -0
  35. package/{dist/query → query}/index.js +5 -1
  36. package/{dist/schema → schema}/DatabaseSchema.d.ts +1 -1
  37. package/{dist/schema → schema}/DatabaseSchema.js +8 -16
  38. package/{dist/schema → schema}/DatabaseTable.d.ts +1 -1
  39. package/{dist/schema → schema}/DatabaseTable.js +2 -1
  40. package/{dist/schema → schema}/SchemaComparator.d.ts +3 -1
  41. package/{dist/schema → schema}/SchemaComparator.js +58 -10
  42. package/{dist/schema → schema}/SchemaGenerator.d.ts +10 -8
  43. package/{dist/schema → schema}/SchemaGenerator.js +81 -28
  44. package/{dist/schema → schema}/SchemaHelper.d.ts +9 -4
  45. package/{dist/schema → schema}/SchemaHelper.js +46 -8
  46. package/{dist/schema → schema}/index.d.ts +0 -0
  47. package/{dist/schema → schema}/index.js +5 -1
  48. package/{dist/typings.d.ts → typings.d.ts} +7 -3
  49. package/{dist/typings.js → typings.js} +0 -0
  50. package/CHANGELOG.md +0 -661
  51. package/dist/AbstractSqlDriver.d.ts +0 -55
  52. package/dist/LICENSE +0 -21
  53. package/dist/package.json +0 -99
@@ -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;
@@ -82,6 +82,7 @@ class DatabaseTable {
82
82
  enumItems: prop.items?.every(core_1.Utils.isString) ? prop.items : undefined,
83
83
  comment: prop.comment,
84
84
  extra: prop.extra,
85
+ ignoreSchemaChanges: prop.ignoreSchemaChanges,
85
86
  };
86
87
  (_a = this.columns[field]).unsigned || (_a.unsigned = this.columns[field].autoincrement);
87
88
  const defaultValue = this.platform.getSchemaHelper().normalizeDefaultValue(prop.defaultRaw, prop.length);
@@ -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,7 +38,7 @@ 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
  /**
@@ -52,4 +53,5 @@ export declare class SchemaComparator {
52
53
  diffCheck(check1: Check, check2: Check): 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,8 @@ 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
+ const unquote = (str) => str?.replace(/['"`]/g, '');
429
+ return unquote(check1.expression) !== unquote(check2.expression);
388
430
  }
389
431
  hasSameDefaultValue(from, to) {
390
432
  if (from.default == null || from.default.toString().toLowerCase() === 'null' || from.default.toString().startsWith('nextval(')) {
@@ -423,5 +465,11 @@ class SchemaComparator {
423
465
  scale: match ? +match[2] : column.scale,
424
466
  };
425
467
  }
468
+ log(message, params) {
469
+ if (params) {
470
+ message += ' ' + (0, util_1.inspect)(params);
471
+ }
472
+ this.logger.log('schema', message);
473
+ }
426
474
  }
427
475
  exports.SchemaComparator = SchemaComparator;
@@ -1,19 +1,17 @@
1
+ import type { MikroORM } from '@mikro-orm/core';
1
2
  import { AbstractSchemaGenerator } from '@mikro-orm/core';
2
3
  import type { SchemaDifference } from '../typings';
3
4
  import { DatabaseSchema } from './DatabaseSchema';
4
5
  import type { AbstractSqlDriver } from '../AbstractSqlDriver';
5
- import { SqlEntityManager } from '../SqlEntityManager';
6
6
  /**
7
7
  * Should be renamed to `SqlSchemaGenerator` in v6
8
8
  */
9
9
  export declare class SchemaGenerator extends AbstractSchemaGenerator<AbstractSqlDriver> {
10
10
  private readonly helper;
11
- private readonly knex;
12
11
  private readonly options;
13
- /**
14
- * @deprecated For back compatibility, we also support EM as the parameter.
15
- */
16
- constructor(em: SqlEntityManager);
12
+ protected lastEnsuredDatabase?: string;
13
+ static register(orm: MikroORM): void;
14
+ /** @deprecated use `dropSchema` and `createSchema` commands respectively */
17
15
  generate(): Promise<string>;
18
16
  createSchema(options?: {
19
17
  wrap?: boolean;
@@ -34,6 +32,10 @@ export declare class SchemaGenerator extends AbstractSchemaGenerator<AbstractSql
34
32
  dropDb?: boolean;
35
33
  schema?: string;
36
34
  }): Promise<void>;
35
+ clearDatabase(options?: {
36
+ schema?: string;
37
+ truncate?: boolean;
38
+ }): Promise<void>;
37
39
  getDropSchemaSQL(options?: {
38
40
  wrap?: boolean;
39
41
  dropMigrationsTable?: boolean;
@@ -86,7 +88,7 @@ export declare class SchemaGenerator extends AbstractSchemaGenerator<AbstractSql
86
88
  dropDatabase(name: string): Promise<void>;
87
89
  execute(sql: string, options?: {
88
90
  wrap?: boolean;
89
- }): Promise<void>;
91
+ }): Promise<undefined>;
90
92
  private wrapSchema;
91
93
  private createSchemaBuilder;
92
94
  private createTable;
@@ -95,7 +97,7 @@ export declare class SchemaGenerator extends AbstractSchemaGenerator<AbstractSql
95
97
  private createCheck;
96
98
  private dropCheck;
97
99
  private dropTable;
98
- private configureColumn;
99
100
  private createForeignKeys;
100
101
  private dump;
102
+ private get knex();
101
103
  }
@@ -4,20 +4,19 @@ exports.SchemaGenerator = void 0;
4
4
  const core_1 = require("@mikro-orm/core");
5
5
  const DatabaseSchema_1 = require("./DatabaseSchema");
6
6
  const SchemaComparator_1 = require("./SchemaComparator");
7
- const SqlEntityManager_1 = require("../SqlEntityManager");
8
7
  /**
9
8
  * Should be renamed to `SqlSchemaGenerator` in v6
10
9
  */
11
10
  class SchemaGenerator extends core_1.AbstractSchemaGenerator {
12
- /**
13
- * `orm.getSchemaGenerator()` should be preferred way of getting the SchemaGenerator instance.
14
- */
15
- constructor(driver) {
16
- super(driver instanceof SqlEntityManager_1.SqlEntityManager ? driver.getDriver() : driver);
11
+ constructor() {
12
+ super(...arguments);
17
13
  this.helper = this.platform.getSchemaHelper();
18
- this.knex = this.connection.getKnex();
19
14
  this.options = this.config.get('schemaGenerator');
20
15
  }
16
+ static register(orm) {
17
+ orm.config.registerExtension('@mikro-orm/schema-generator', new SchemaGenerator(orm.em));
18
+ }
19
+ /** @deprecated use `dropSchema` and `createSchema` commands respectively */
21
20
  async generate() {
22
21
  const [dropSchema, createSchema] = await Promise.all([
23
22
  this.getDropSchemaSQL({ wrap: false }),
@@ -35,7 +34,11 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
35
34
  */
36
35
  async ensureDatabase() {
37
36
  const dbName = this.config.get('dbName');
37
+ if (this.lastEnsuredDatabase === dbName) {
38
+ return true;
39
+ }
38
40
  const exists = await this.helper.databaseExists(this.connection, dbName);
41
+ this.lastEnsuredDatabase = dbName;
39
42
  if (!exists) {
40
43
  this.config.set('dbName', this.helper.getManagementDbName());
41
44
  await this.driver.reconnect();
@@ -48,7 +51,8 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
48
51
  }
49
52
  getTargetSchema(schema) {
50
53
  const metadata = this.getOrderedMetadata(schema);
51
- return DatabaseSchema_1.DatabaseSchema.fromMetadata(metadata, this.platform, this.config, schema ?? this.platform.getDefaultSchemaName());
54
+ const schemaName = schema ?? this.config.get('schema') ?? this.platform.getDefaultSchemaName();
55
+ return DatabaseSchema_1.DatabaseSchema.fromMetadata(metadata, this.platform, this.config, schemaName);
52
56
  }
53
57
  async getCreateSchemaSQL(options = {}) {
54
58
  const wrap = options.wrap ?? this.options.disableForeignKeys;
@@ -69,7 +73,6 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
69
73
  return this.wrapSchema(ret, { wrap });
70
74
  }
71
75
  async dropSchema(options = {}) {
72
- options.wrap ?? (options.wrap = true);
73
76
  if (options.dropDb) {
74
77
  const name = this.config.get('dbName');
75
78
  return this.dropDatabase(name);
@@ -77,10 +80,44 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
77
80
  const sql = await this.getDropSchemaSQL(options);
78
81
  await this.execute(sql);
79
82
  }
83
+ async clearDatabase(options) {
84
+ // truncate by default, so no value is considered as true
85
+ /* istanbul ignore if */
86
+ if (options?.truncate === false) {
87
+ return super.clearDatabase(options);
88
+ }
89
+ await this.execute(this.helper.disableForeignKeysSQL());
90
+ for (const meta of this.getOrderedMetadata(options?.schema).reverse()) {
91
+ await this.driver.createQueryBuilder(meta.className, this.em?.getTransactionContext(), 'write', false)
92
+ .withSchema(options?.schema)
93
+ .truncate();
94
+ }
95
+ await this.execute(this.helper.enableForeignKeysSQL());
96
+ if (this.em) {
97
+ const allowGlobalContext = this.config.get('allowGlobalContext');
98
+ this.config.set('allowGlobalContext', true);
99
+ this.em.clear();
100
+ this.config.set('allowGlobalContext', allowGlobalContext);
101
+ }
102
+ }
80
103
  async getDropSchemaSQL(options = {}) {
104
+ await this.ensureDatabase();
81
105
  const wrap = options.wrap ?? this.options.disableForeignKeys;
82
106
  const metadata = this.getOrderedMetadata(options.schema).reverse();
107
+ const schema = await DatabaseSchema_1.DatabaseSchema.create(this.connection, this.platform, this.config, options.schema);
83
108
  let ret = '';
109
+ // remove FKs explicitly if we can't use cascading statement and we don't disable FK checks (we need this for circular relations)
110
+ for (const meta of metadata) {
111
+ const table = schema.getTable(meta.tableName);
112
+ if (!this.platform.usesCascadeStatement() && table && !wrap) {
113
+ for (const fk of Object.values(table.getForeignKeys())) {
114
+ const builder = this.createSchemaBuilder(table.schema).alterTable(table.name, tbl => {
115
+ tbl.dropForeign(fk.columnNames, fk.constraintName);
116
+ });
117
+ ret += await this.dump(builder, '\n');
118
+ }
119
+ }
120
+ }
84
121
  for (const meta of metadata) {
85
122
  ret += await this.dump(this.dropTable(meta.collection, this.getSchemaName(meta, options)), '\n');
86
123
  }
@@ -90,20 +127,23 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
90
127
  return this.wrapSchema(ret + '\n', { wrap });
91
128
  }
92
129
  getSchemaName(meta, options) {
130
+ const schemaName = options.schema ?? this.config.get('schema');
93
131
  /* istanbul ignore next */
94
- return meta.schema === '*' ? options.schema : meta.schema;
132
+ return meta.schema && meta.schema === '*' ? schemaName : (meta.schema ?? schemaName);
95
133
  }
96
134
  async updateSchema(options = {}) {
97
135
  const sql = await this.getUpdateSchemaSQL(options);
98
136
  await this.execute(sql);
99
137
  }
100
138
  async getUpdateSchemaSQL(options = {}) {
139
+ await this.ensureDatabase();
101
140
  const { fromSchema, toSchema } = await this.prepareSchemaForComparison(options);
102
141
  const comparator = new SchemaComparator_1.SchemaComparator(this.platform);
103
142
  const diffUp = comparator.compare(fromSchema, toSchema);
104
143
  return this.diffToSQL(diffUp, options);
105
144
  }
106
145
  async getUpdateSchemaMigrationSQL(options = {}) {
146
+ await this.ensureDatabase();
107
147
  const { fromSchema, toSchema } = await this.prepareSchemaForComparison(options);
108
148
  const comparator = new SchemaComparator_1.SchemaComparator(this.platform);
109
149
  const diffUp = comparator.compare(fromSchema, toSchema);
@@ -240,7 +280,7 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
240
280
  }
241
281
  for (const column of Object.values(diff.addedColumns)) {
242
282
  const col = this.helper.createTableColumn(table, column, diff.fromTable);
243
- this.configureColumn(column, col);
283
+ this.helper.configureColumn(column, col, this.knex);
244
284
  const foreignKey = Object.values(diff.addedForeignKeys).find(fk => fk.columnNames.length === 1 && fk.columnNames[0] === column.name);
245
285
  if (foreignKey && this.options.createForeignKeyConstraints) {
246
286
  delete diff.addedForeignKeys[foreignKey.constraintName];
@@ -262,7 +302,7 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
262
302
  continue;
263
303
  }
264
304
  const col = this.helper.createTableColumn(table, column, diff.fromTable, changedProperties).alter();
265
- this.configureColumn(column, col, changedProperties);
305
+ this.helper.configureColumn(column, col, this.knex, changedProperties);
266
306
  }
267
307
  for (const { column } of Object.values(diff.changedColumns).filter(diff => diff.changedProperties.has('autoincrement'))) {
268
308
  this.helper.pushTableQuery(table, this.helper.getAlterColumnAutoincrement(tableName, column));
@@ -274,7 +314,7 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
274
314
  this.helper.pushTableQuery(table, this.helper.getChangeColumnCommentSQL(tableName, column));
275
315
  }
276
316
  for (const [oldColumnName, column] of Object.entries(diff.renamedColumns)) {
277
- this.helper.pushTableQuery(table, this.helper.getRenameColumnSQL(tableName, oldColumnName, column));
317
+ this.helper.pushTableQuery(table, this.helper.getRenameColumnSQL(tableName, oldColumnName, column, schemaName));
278
318
  }
279
319
  for (const foreignKey of Object.values(diff.addedForeignKeys)) {
280
320
  this.createForeignKey(table, foreignKey);
@@ -283,15 +323,15 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
283
323
  this.createForeignKey(table, foreignKey);
284
324
  }
285
325
  for (const index of Object.values(diff.addedIndexes)) {
286
- this.createIndex(table, index, diff.name);
326
+ this.createIndex(table, index, diff.toTable);
287
327
  }
288
328
  for (const index of Object.values(diff.changedIndexes)) {
289
- this.createIndex(table, index, diff.name, true);
329
+ this.createIndex(table, index, diff.toTable, true);
290
330
  }
291
331
  for (const [oldIndexName, index] of Object.entries(diff.renamedIndexes)) {
292
332
  if (index.unique) {
293
333
  this.dropIndex(table, index, oldIndexName);
294
- this.createIndex(table, index, diff.name);
334
+ this.createIndex(table, index, diff.toTable);
295
335
  }
296
336
  else {
297
337
  this.helper.pushTableQuery(table, this.helper.getRenameIndexSQL(diff.name, index, oldIndexName));
@@ -304,7 +344,8 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
304
344
  this.createCheck(table, check);
305
345
  }
306
346
  if ('changedComment' in diff) {
307
- table.comment(diff.changedComment ?? '');
347
+ const comment = diff.changedComment ? this.platform.quoteValue(diff.changedComment).replace(/^'|'$/g, '') : '';
348
+ table.comment(comment);
308
349
  }
309
350
  }));
310
351
  return ret;
@@ -325,9 +366,14 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
325
366
  async execute(sql, options = {}) {
326
367
  options.wrap ?? (options.wrap = false);
327
368
  const lines = this.wrapSchema(sql, options).split('\n').filter(i => i.trim());
328
- for (const line of lines) {
329
- await this.driver.execute(line);
369
+ if (lines.length === 0) {
370
+ return;
330
371
  }
372
+ if (this.platform.supportsMultipleStatements()) {
373
+ const query = lines.join('\n');
374
+ return void await this.driver.execute(query);
375
+ }
376
+ await core_1.Utils.runSerial(lines, line => this.driver.execute(line));
331
377
  }
332
378
  wrapSchema(sql, options = {}) {
333
379
  options.wrap ?? (options.wrap = this.options.disableForeignKeys);
@@ -350,16 +396,18 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
350
396
  return this.createSchemaBuilder(tableDef.schema).createTable(tableDef.name, table => {
351
397
  tableDef.getColumns().forEach(column => {
352
398
  const col = this.helper.createTableColumn(table, column, tableDef);
353
- this.configureColumn(column, col);
399
+ this.helper.configureColumn(column, col, this.knex);
354
400
  });
355
401
  for (const index of tableDef.getIndexes()) {
356
- this.createIndex(table, index, tableDef.name, !tableDef.getColumns().some(c => c.autoincrement));
402
+ const createPrimary = !tableDef.getColumns().some(c => c.autoincrement && c.primary) || this.helper.hasNonDefaultPrimaryKeyName(tableDef);
403
+ this.createIndex(table, index, tableDef, createPrimary);
357
404
  }
358
405
  for (const check of tableDef.getChecks()) {
359
406
  this.createCheck(table, check);
360
407
  }
361
408
  if (tableDef.comment) {
362
- table.comment(tableDef.comment);
409
+ const comment = this.platform.quoteValue(tableDef.comment).replace(/^'|'$/g, '');
410
+ table.comment(comment);
363
411
  }
364
412
  if (!this.helper.supportsSchemaConstraints()) {
365
413
  for (const fk of Object.values(tableDef.getForeignKeys())) {
@@ -369,13 +417,12 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
369
417
  this.helper.finalizeTable(table, this.config.get('charset'), this.config.get('collate'));
370
418
  });
371
419
  }
372
- createIndex(table, index, tableName, createPrimary = false) {
420
+ createIndex(table, index, tableDef, createPrimary = false) {
373
421
  if (index.primary && !createPrimary) {
374
422
  return;
375
423
  }
376
424
  if (index.primary) {
377
- /* istanbul ignore next */
378
- const keyName = tableName.includes('.') ? tableName.split('.').pop() + '_pkey' : undefined;
425
+ const keyName = this.helper.hasNonDefaultPrimaryKeyName(tableDef) ? index.keyName : undefined;
379
426
  table.primary(index.columnNames, keyName);
380
427
  }
381
428
  else if (index.unique) {
@@ -384,6 +431,12 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
384
431
  else if (index.expression) {
385
432
  this.helper.pushTableQuery(table, index.expression);
386
433
  }
434
+ else if (index.type === 'fulltext') {
435
+ const columns = index.columnNames.map(name => ({ name, type: tableDef.getColumn(name).type }));
436
+ if (this.platform.supportsCreatingFullTextIndex()) {
437
+ this.helper.pushTableQuery(table, this.platform.getFullTextIndexExpression(index.keyName, tableDef.schema, tableDef.name, columns));
438
+ }
439
+ }
387
440
  else {
388
441
  table.index(index.columnNames, index.keyName, index.type);
389
442
  }
@@ -412,9 +465,6 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
412
465
  }
413
466
  return builder;
414
467
  }
415
- configureColumn(column, col, changedProperties) {
416
- return this.helper.configureColumn(column, col, this.knex, changedProperties);
417
- }
418
468
  createForeignKeys(table, tableDef, schema) {
419
469
  if (!this.helper.supportsSchemaConstraints()) {
420
470
  return;
@@ -433,5 +483,8 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
433
483
  const tmp = dump.replace(/pragma table_.+/ig, '').replace(/\n\n+/g, '\n').trim();
434
484
  return tmp ? tmp + append : '';
435
485
  }
486
+ get knex() {
487
+ return this.connection.getKnex();
488
+ }
436
489
  }
437
490
  exports.SchemaGenerator = SchemaGenerator;
@@ -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 { Check, Column, Index, 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,23 +14,27 @@ 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: Index[] | undefined, tableName: string, schemaName?: string): Promise<string[]>;
17
18
  getForeignKeys(connection: AbstractSqlConnection, tableName: string, schemaName?: string): Promise<Dictionary>;
19
+ protected getTableKey(t: Table): string;
18
20
  getEnumDefinitions(connection: AbstractSqlConnection, checks: Check[], 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;
23
+ getRenameColumnSQL(tableName: string, oldColumnName: string, to: Column, schemaName?: string): string;
21
24
  getCreateIndexSQL(tableName: string, index: Index): string;
22
25
  getDropIndexSQL(tableName: string, index: Index): string;
23
26
  getRenameIndexSQL(tableName: string, index: Index, 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
36
  getIndexes(connection: AbstractSqlConnection, tableName: string, schemaName?: string): Promise<Index[]>;
32
- getChecks(connection: AbstractSqlConnection, tableName: string, schemaName?: string): Promise<Check[]>;
37
+ getChecks(connection: AbstractSqlConnection, tableName: string, schemaName?: string, columns?: Column[]): Promise<Check[]>;
33
38
  protected mapIndexes(indexes: Index[]): Promise<Index[]>;
34
39
  getForeignKeysSQL(tableName: string, schemaName?: string): string;
35
40
  mapForeignKeys(fks: any[], tableName: string, schemaName?: string): Dictionary;