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

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 (69) hide show
  1. package/{dist/AbstractSqlConnection.d.ts → AbstractSqlConnection.d.ts} +8 -4
  2. package/{dist/AbstractSqlConnection.js → AbstractSqlConnection.js} +35 -18
  3. package/AbstractSqlDriver.d.ts +73 -0
  4. package/AbstractSqlDriver.js +1085 -0
  5. package/AbstractSqlPlatform.d.ts +22 -0
  6. package/{dist/AbstractSqlPlatform.js → AbstractSqlPlatform.js} +46 -19
  7. package/{dist/MonkeyPatchable.d.ts → MonkeyPatchable.d.ts} +1 -0
  8. package/{dist/MonkeyPatchable.js → MonkeyPatchable.js} +3 -0
  9. package/PivotCollectionPersister.d.ts +17 -0
  10. package/PivotCollectionPersister.js +128 -0
  11. package/{dist/README.md → README.md} +66 -109
  12. package/{dist/SqlEntityManager.d.ts → SqlEntityManager.d.ts} +6 -10
  13. package/{dist/SqlEntityManager.js → SqlEntityManager.js} +5 -10
  14. package/SqlEntityRepository.d.ts +24 -0
  15. package/{dist/SqlEntityRepository.js → SqlEntityRepository.js} +11 -8
  16. package/{dist/index.d.ts → index.d.ts} +1 -0
  17. package/{dist/index.js → index.js} +6 -1
  18. package/index.mjs +211 -0
  19. package/package.json +20 -49
  20. package/query/ArrayCriteriaNode.d.ts +10 -0
  21. package/{dist/query → query}/ArrayCriteriaNode.js +7 -2
  22. package/{dist/query → query}/CriteriaNode.d.ts +11 -9
  23. package/{dist/query → query}/CriteriaNode.js +31 -15
  24. package/query/CriteriaNodeFactory.d.ts +12 -0
  25. package/{dist/query → query}/CriteriaNodeFactory.js +32 -15
  26. package/query/ObjectCriteriaNode.d.ts +15 -0
  27. package/{dist/query → query}/ObjectCriteriaNode.js +68 -21
  28. package/query/QueryBuilder.d.ts +284 -0
  29. package/query/QueryBuilder.js +1218 -0
  30. package/{dist/query → query}/QueryBuilderHelper.d.ts +26 -23
  31. package/query/QueryBuilderHelper.js +661 -0
  32. package/query/ScalarCriteriaNode.d.ts +10 -0
  33. package/{dist/query → query}/ScalarCriteriaNode.js +12 -8
  34. package/query/enums.d.ts +15 -0
  35. package/query/enums.js +20 -0
  36. package/{dist/query → query}/index.js +5 -1
  37. package/{dist/schema → schema}/DatabaseSchema.d.ts +6 -3
  38. package/{dist/schema → schema}/DatabaseSchema.js +35 -25
  39. package/{dist/schema → schema}/DatabaseTable.d.ts +21 -13
  40. package/schema/DatabaseTable.js +645 -0
  41. package/{dist/schema → schema}/SchemaComparator.d.ts +9 -7
  42. package/{dist/schema → schema}/SchemaComparator.js +99 -25
  43. package/{dist/schema → schema}/SchemaHelper.d.ts +20 -13
  44. package/{dist/schema → schema}/SchemaHelper.js +70 -18
  45. package/{dist/schema/SchemaGenerator.d.ts → schema/SqlSchemaGenerator.d.ts} +11 -14
  46. package/{dist/schema/SchemaGenerator.js → schema/SqlSchemaGenerator.js} +149 -63
  47. package/{dist/schema → schema}/index.d.ts +1 -1
  48. package/{dist/schema → schema}/index.js +6 -2
  49. package/{dist/typings.d.ts → typings.d.ts} +45 -22
  50. package/CHANGELOG.md +0 -661
  51. package/dist/AbstractSqlDriver.d.ts +0 -55
  52. package/dist/AbstractSqlDriver.js +0 -644
  53. package/dist/AbstractSqlPlatform.d.ts +0 -21
  54. package/dist/LICENSE +0 -21
  55. package/dist/SqlEntityRepository.d.ts +0 -23
  56. package/dist/index.mjs +0 -26
  57. package/dist/package.json +0 -99
  58. package/dist/query/ArrayCriteriaNode.d.ts +0 -9
  59. package/dist/query/CriteriaNodeFactory.d.ts +0 -12
  60. package/dist/query/ObjectCriteriaNode.d.ts +0 -14
  61. package/dist/query/QueryBuilder.d.ts +0 -211
  62. package/dist/query/QueryBuilder.js +0 -688
  63. package/dist/query/QueryBuilderHelper.js +0 -523
  64. package/dist/query/ScalarCriteriaNode.d.ts +0 -9
  65. package/dist/query/enums.d.ts +0 -8
  66. package/dist/query/enums.js +0 -12
  67. package/dist/schema/DatabaseTable.js +0 -319
  68. /package/{dist/query → query}/index.d.ts +0 -0
  69. /package/{dist/typings.js → typings.js} +0 -0
@@ -1,20 +1,12 @@
1
- import { AbstractSchemaGenerator } from '@mikro-orm/core';
1
+ import { AbstractSchemaGenerator, type MikroORM, type ISchemaGenerator } from '@mikro-orm/core';
2
2
  import type { SchemaDifference } from '../typings';
3
3
  import { DatabaseSchema } from './DatabaseSchema';
4
4
  import type { AbstractSqlDriver } from '../AbstractSqlDriver';
5
- import { SqlEntityManager } from '../SqlEntityManager';
6
- /**
7
- * Should be renamed to `SqlSchemaGenerator` in v6
8
- */
9
- export declare class SchemaGenerator extends AbstractSchemaGenerator<AbstractSqlDriver> {
5
+ export declare class SqlSchemaGenerator extends AbstractSchemaGenerator<AbstractSqlDriver> implements ISchemaGenerator {
10
6
  private readonly helper;
11
- private readonly knex;
12
7
  private readonly options;
13
- /**
14
- * @deprecated For back compatibility, we also support EM as the parameter.
15
- */
16
- constructor(em: SqlEntityManager);
17
- generate(): Promise<string>;
8
+ protected lastEnsuredDatabase?: string;
9
+ static register(orm: MikroORM): void;
18
10
  createSchema(options?: {
19
11
  wrap?: boolean;
20
12
  schema?: string;
@@ -34,6 +26,10 @@ export declare class SchemaGenerator extends AbstractSchemaGenerator<AbstractSql
34
26
  dropDb?: boolean;
35
27
  schema?: string;
36
28
  }): Promise<void>;
29
+ clearDatabase(options?: {
30
+ schema?: string;
31
+ truncate?: boolean;
32
+ }): Promise<void>;
37
33
  getDropSchemaSQL(options?: {
38
34
  wrap?: boolean;
39
35
  dropMigrationsTable?: boolean;
@@ -83,7 +79,7 @@ export declare class SchemaGenerator extends AbstractSchemaGenerator<AbstractSql
83
79
  * creates new database and connects to it
84
80
  */
85
81
  createDatabase(name: string): Promise<void>;
86
- dropDatabase(name: string): Promise<void>;
82
+ dropDatabase(name?: string): Promise<void>;
87
83
  execute(sql: string, options?: {
88
84
  wrap?: boolean;
89
85
  }): Promise<void>;
@@ -95,7 +91,8 @@ export declare class SchemaGenerator extends AbstractSchemaGenerator<AbstractSql
95
91
  private createCheck;
96
92
  private dropCheck;
97
93
  private dropTable;
98
- private configureColumn;
99
94
  private createForeignKeys;
100
95
  private dump;
96
+ private get knex();
101
97
  }
98
+ export { SqlSchemaGenerator as SchemaGenerator };
@@ -1,29 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SchemaGenerator = void 0;
3
+ exports.SchemaGenerator = exports.SqlSchemaGenerator = 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
- /**
9
- * Should be renamed to `SqlSchemaGenerator` in v6
10
- */
11
- 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);
17
- this.helper = this.platform.getSchemaHelper();
18
- this.knex = this.connection.getKnex();
19
- this.options = this.config.get('schemaGenerator');
20
- }
21
- async generate() {
22
- const [dropSchema, createSchema] = await Promise.all([
23
- this.getDropSchemaSQL({ wrap: false }),
24
- this.getCreateSchemaSQL({ wrap: false }),
25
- ]);
26
- return this.wrapSchema(dropSchema + createSchema);
7
+ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
8
+ helper = this.platform.getSchemaHelper();
9
+ options = this.config.get('schemaGenerator');
10
+ lastEnsuredDatabase;
11
+ static register(orm) {
12
+ orm.config.registerExtension('@mikro-orm/schema-generator', () => new SqlSchemaGenerator(orm.em));
27
13
  }
28
14
  async createSchema(options) {
29
15
  await this.ensureDatabase();
@@ -35,7 +21,11 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
35
21
  */
36
22
  async ensureDatabase() {
37
23
  const dbName = this.config.get('dbName');
24
+ if (this.lastEnsuredDatabase === dbName) {
25
+ return true;
26
+ }
38
27
  const exists = await this.helper.databaseExists(this.connection, dbName);
28
+ this.lastEnsuredDatabase = dbName;
39
29
  if (!exists) {
40
30
  this.config.set('dbName', this.helper.getManagementDbName());
41
31
  await this.driver.reconnect();
@@ -48,7 +38,8 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
48
38
  }
49
39
  getTargetSchema(schema) {
50
40
  const metadata = this.getOrderedMetadata(schema);
51
- return DatabaseSchema_1.DatabaseSchema.fromMetadata(metadata, this.platform, this.config, schema ?? this.platform.getDefaultSchemaName());
41
+ const schemaName = schema ?? this.config.get('schema') ?? this.platform.getDefaultSchemaName();
42
+ return DatabaseSchema_1.DatabaseSchema.fromMetadata(metadata, this.platform, this.config, schemaName);
52
43
  }
53
44
  async getCreateSchemaSQL(options = {}) {
54
45
  const wrap = options.wrap ?? this.options.disableForeignKeys;
@@ -69,7 +60,6 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
69
60
  return this.wrapSchema(ret, { wrap });
70
61
  }
71
62
  async dropSchema(options = {}) {
72
- options.wrap ?? (options.wrap = true);
73
63
  if (options.dropDb) {
74
64
  const name = this.config.get('dbName');
75
65
  return this.dropDatabase(name);
@@ -77,51 +67,99 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
77
67
  const sql = await this.getDropSchemaSQL(options);
78
68
  await this.execute(sql);
79
69
  }
70
+ async clearDatabase(options) {
71
+ // truncate by default, so no value is considered as true
72
+ /* istanbul ignore if */
73
+ if (options?.truncate === false) {
74
+ return super.clearDatabase(options);
75
+ }
76
+ await this.execute(this.helper.disableForeignKeysSQL());
77
+ for (const meta of this.getOrderedMetadata(options?.schema).reverse()) {
78
+ await this.driver.createQueryBuilder(meta.className, this.em?.getTransactionContext(), 'write', false)
79
+ .withSchema(options?.schema)
80
+ .truncate();
81
+ }
82
+ await this.execute(this.helper.enableForeignKeysSQL());
83
+ if (this.em) {
84
+ const allowGlobalContext = this.config.get('allowGlobalContext');
85
+ this.config.set('allowGlobalContext', true);
86
+ this.em.clear();
87
+ this.config.set('allowGlobalContext', allowGlobalContext);
88
+ }
89
+ }
80
90
  async getDropSchemaSQL(options = {}) {
91
+ await this.ensureDatabase();
81
92
  const wrap = options.wrap ?? this.options.disableForeignKeys;
82
93
  const metadata = this.getOrderedMetadata(options.schema).reverse();
94
+ const schemas = this.getTargetSchema(options.schema).getNamespaces();
95
+ const schema = await DatabaseSchema_1.DatabaseSchema.create(this.connection, this.platform, this.config, options.schema, schemas);
83
96
  let ret = '';
97
+ // remove FKs explicitly if we can't use cascading statement and we don't disable FK checks (we need this for circular relations)
98
+ for (const meta of metadata) {
99
+ const table = schema.getTable(meta.tableName);
100
+ if (!this.platform.usesCascadeStatement() && table && !wrap) {
101
+ for (const fk of Object.values(table.getForeignKeys())) {
102
+ const builder = this.createSchemaBuilder(table.schema).alterTable(table.name, tbl => {
103
+ tbl.dropForeign(fk.columnNames, fk.constraintName);
104
+ });
105
+ ret += await this.dump(builder, '\n');
106
+ }
107
+ }
108
+ }
84
109
  for (const meta of metadata) {
85
110
  ret += await this.dump(this.dropTable(meta.collection, this.getSchemaName(meta, options)), '\n');
86
111
  }
112
+ if (this.platform.supportsNativeEnums()) {
113
+ for (const columnName of Object.keys(schema.getNativeEnums())) {
114
+ const sql = this.helper.getDropNativeEnumSQL(columnName, options.schema ?? this.config.get('schema'));
115
+ ret += await this.dump(this.knex.schema.raw(sql), '\n');
116
+ }
117
+ }
87
118
  if (options.dropMigrationsTable) {
88
119
  ret += await this.dump(this.dropTable(this.config.get('migrations').tableName, this.config.get('schema')), '\n');
89
120
  }
90
121
  return this.wrapSchema(ret + '\n', { wrap });
91
122
  }
92
123
  getSchemaName(meta, options) {
124
+ const schemaName = options.schema ?? this.config.get('schema');
93
125
  /* istanbul ignore next */
94
- return meta.schema === '*' ? options.schema : meta.schema;
126
+ return meta.schema && meta.schema === '*' ? schemaName : (meta.schema ?? schemaName);
95
127
  }
96
128
  async updateSchema(options = {}) {
97
129
  const sql = await this.getUpdateSchemaSQL(options);
98
130
  await this.execute(sql);
99
131
  }
100
132
  async getUpdateSchemaSQL(options = {}) {
133
+ await this.ensureDatabase();
101
134
  const { fromSchema, toSchema } = await this.prepareSchemaForComparison(options);
102
135
  const comparator = new SchemaComparator_1.SchemaComparator(this.platform);
103
136
  const diffUp = comparator.compare(fromSchema, toSchema);
104
137
  return this.diffToSQL(diffUp, options);
105
138
  }
106
139
  async getUpdateSchemaMigrationSQL(options = {}) {
140
+ if (!options.fromSchema) {
141
+ await this.ensureDatabase();
142
+ }
107
143
  const { fromSchema, toSchema } = await this.prepareSchemaForComparison(options);
108
144
  const comparator = new SchemaComparator_1.SchemaComparator(this.platform);
109
145
  const diffUp = comparator.compare(fromSchema, toSchema);
110
- const diffDown = comparator.compare(toSchema, fromSchema);
146
+ const diffDown = comparator.compare(toSchema, fromSchema, diffUp);
111
147
  return {
112
148
  up: await this.diffToSQL(diffUp, options),
113
149
  down: this.platform.supportsDownMigrations() ? await this.diffToSQL(diffDown, options) : '',
114
150
  };
115
151
  }
116
152
  async prepareSchemaForComparison(options) {
117
- options.wrap ?? (options.wrap = this.options.disableForeignKeys);
118
- options.safe ?? (options.safe = false);
119
- options.dropTables ?? (options.dropTables = true);
153
+ options.wrap ??= this.options.disableForeignKeys;
154
+ options.safe ??= false;
155
+ options.dropTables ??= true;
120
156
  const toSchema = this.getTargetSchema(options.schema);
121
- const fromSchema = options.fromSchema ?? await DatabaseSchema_1.DatabaseSchema.create(this.connection, this.platform, this.config, options.schema);
157
+ const schemas = toSchema.getNamespaces();
158
+ const fromSchema = options.fromSchema ?? await DatabaseSchema_1.DatabaseSchema.create(this.connection, this.platform, this.config, options.schema, schemas);
122
159
  const wildcardSchemaTables = Object.values(this.metadata.getAll()).filter(meta => meta.schema === '*').map(meta => meta.tableName);
123
160
  fromSchema.prune(options.schema, wildcardSchemaTables);
124
161
  toSchema.prune(options.schema, wildcardSchemaTables);
162
+ toSchema.setNativeEnums(fromSchema.getNativeEnums());
125
163
  return { fromSchema, toSchema };
126
164
  }
127
165
  async diffToSQL(schemaDiff, options) {
@@ -177,7 +215,7 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
177
215
  if (schema && schemaName === '*') {
178
216
  return `${schema}.${referencedTableName.replace(/^\*\./, '')}`;
179
217
  }
180
- if (schemaName === this.platform.getDefaultSchemaName()) {
218
+ if (!schemaName || schemaName === this.platform.getDefaultSchemaName()) {
181
219
  return tableName;
182
220
  }
183
221
  return `${schemaName}.${tableName}`;
@@ -225,6 +263,12 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
225
263
  alterTable(diff, safe) {
226
264
  const ret = [];
227
265
  const [schemaName, tableName] = this.splitTableName(diff.name);
266
+ const changedNativeEnums = [];
267
+ for (const { column, changedProperties } of Object.values(diff.changedColumns)) {
268
+ if (column.nativeEnumName && changedProperties.has('enumItems') && column.nativeEnumName in diff.fromTable.nativeEnums) {
269
+ changedNativeEnums.push([column.nativeEnumName, column.enumItems, diff.fromTable.getColumn(column.name).enumItems]);
270
+ }
271
+ }
228
272
  ret.push(this.createSchemaBuilder(schemaName).alterTable(tableName, table => {
229
273
  for (const index of Object.values(diff.removedIndexes)) {
230
274
  this.dropIndex(table, index);
@@ -238,9 +282,17 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
238
282
  for (const check of Object.values(diff.changedChecks)) {
239
283
  this.dropCheck(table, check);
240
284
  }
285
+ /* istanbul ignore else */
286
+ if (!safe) {
287
+ for (const column of Object.values(diff.removedColumns)) {
288
+ this.helper.pushTableQuery(table, `alter table ${this.platform.quoteIdentifier(tableName)} drop column ${this.platform.quoteIdentifier(column.name)}`);
289
+ }
290
+ }
291
+ }));
292
+ ret.push(this.createSchemaBuilder(schemaName).alterTable(tableName, table => {
241
293
  for (const column of Object.values(diff.addedColumns)) {
242
294
  const col = this.helper.createTableColumn(table, column, diff.fromTable);
243
- this.configureColumn(column, col);
295
+ this.helper.configureColumn(column, col, this.knex);
244
296
  const foreignKey = Object.values(diff.addedForeignKeys).find(fk => fk.columnNames.length === 1 && fk.columnNames[0] === column.name);
245
297
  if (foreignKey && this.options.createForeignKeyConstraints) {
246
298
  delete diff.addedForeignKeys[foreignKey.constraintName];
@@ -251,30 +303,27 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
251
303
  .onDelete(foreignKey.deleteRule);
252
304
  }
253
305
  }
254
- /* istanbul ignore else */
255
- if (!safe) {
256
- for (const column of Object.values(diff.removedColumns)) {
257
- table.dropColumn(column.name);
258
- }
259
- }
260
306
  for (const { column, changedProperties } of Object.values(diff.changedColumns)) {
261
307
  if (changedProperties.size === 1 && changedProperties.has('comment')) {
262
308
  continue;
263
309
  }
310
+ if (changedProperties.size === 1 && changedProperties.has('enumItems') && column.nativeEnumName) {
311
+ continue;
312
+ }
264
313
  const col = this.helper.createTableColumn(table, column, diff.fromTable, changedProperties).alter();
265
- this.configureColumn(column, col, changedProperties);
314
+ this.helper.configureColumn(column, col, this.knex, changedProperties);
266
315
  }
267
316
  for (const { column } of Object.values(diff.changedColumns).filter(diff => diff.changedProperties.has('autoincrement'))) {
268
- this.helper.pushTableQuery(table, this.helper.getAlterColumnAutoincrement(tableName, column));
317
+ this.helper.pushTableQuery(table, this.helper.getAlterColumnAutoincrement(tableName, column, schemaName));
269
318
  }
270
319
  for (const { column, changedProperties } of Object.values(diff.changedColumns).filter(diff => diff.changedProperties.has('comment'))) {
271
320
  if (['type', 'nullable', 'autoincrement', 'unsigned', 'default', 'enumItems'].some(t => changedProperties.has(t))) {
272
321
  continue; // will be handled via knex
273
322
  }
274
- this.helper.pushTableQuery(table, this.helper.getChangeColumnCommentSQL(tableName, column));
323
+ this.helper.pushTableQuery(table, this.helper.getChangeColumnCommentSQL(tableName, column, schemaName));
275
324
  }
276
325
  for (const [oldColumnName, column] of Object.entries(diff.renamedColumns)) {
277
- this.helper.pushTableQuery(table, this.helper.getRenameColumnSQL(tableName, oldColumnName, column));
326
+ this.helper.pushTableQuery(table, this.helper.getRenameColumnSQL(tableName, oldColumnName, column, schemaName));
278
327
  }
279
328
  for (const foreignKey of Object.values(diff.addedForeignKeys)) {
280
329
  this.createForeignKey(table, foreignKey);
@@ -283,15 +332,15 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
283
332
  this.createForeignKey(table, foreignKey);
284
333
  }
285
334
  for (const index of Object.values(diff.addedIndexes)) {
286
- this.createIndex(table, index, diff.name);
335
+ this.createIndex(table, index, diff.toTable);
287
336
  }
288
337
  for (const index of Object.values(diff.changedIndexes)) {
289
- this.createIndex(table, index, diff.name, true);
338
+ this.createIndex(table, index, diff.toTable, true);
290
339
  }
291
340
  for (const [oldIndexName, index] of Object.entries(diff.renamedIndexes)) {
292
341
  if (index.unique) {
293
342
  this.dropIndex(table, index, oldIndexName);
294
- this.createIndex(table, index, diff.name);
343
+ this.createIndex(table, index, diff.toTable);
295
344
  }
296
345
  else {
297
346
  this.helper.pushTableQuery(table, this.helper.getRenameIndexSQL(diff.name, index, oldIndexName));
@@ -304,9 +353,17 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
304
353
  this.createCheck(table, check);
305
354
  }
306
355
  if ('changedComment' in diff) {
307
- table.comment(diff.changedComment ?? '');
356
+ const comment = diff.changedComment ? this.platform.quoteValue(diff.changedComment).replace(/^'|'$/g, '') : '';
357
+ table.comment(comment);
308
358
  }
309
359
  }));
360
+ if (this.platform.supportsNativeEnums()) {
361
+ changedNativeEnums.forEach(([enumName, itemsNew, itemsOld]) => {
362
+ // postgres allows only adding new items
363
+ const newItems = itemsNew.filter(val => !itemsOld.includes(val));
364
+ ret.push(...newItems.map(val => this.knex.schema.raw(this.helper.getAlterNativeEnumSQL(enumName, schemaName, val))));
365
+ });
366
+ }
310
367
  return ret;
311
368
  }
312
369
  /**
@@ -318,19 +375,26 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
318
375
  await this.driver.reconnect();
319
376
  }
320
377
  async dropDatabase(name) {
378
+ name ??= this.config.get('dbName');
321
379
  this.config.set('dbName', this.helper.getManagementDbName());
322
380
  await this.driver.reconnect();
323
381
  await this.driver.execute(this.helper.getDropDatabaseSQL('' + this.knex.ref(name)));
324
382
  }
325
383
  async execute(sql, options = {}) {
326
- options.wrap ?? (options.wrap = false);
384
+ options.wrap ??= false;
327
385
  const lines = this.wrapSchema(sql, options).split('\n').filter(i => i.trim());
328
- for (const line of lines) {
329
- await this.driver.execute(line);
386
+ if (lines.length === 0) {
387
+ return;
330
388
  }
389
+ if (this.platform.supportsMultipleStatements()) {
390
+ const query = lines.join('\n');
391
+ await this.driver.execute(query);
392
+ return;
393
+ }
394
+ await core_1.Utils.runSerial(lines, line => this.driver.execute(line));
331
395
  }
332
- wrapSchema(sql, options = {}) {
333
- options.wrap ?? (options.wrap = this.options.disableForeignKeys);
396
+ wrapSchema(sql, options) {
397
+ options.wrap ??= this.options.disableForeignKeys;
334
398
  if (!options.wrap || sql.trim() === '') {
335
399
  return sql;
336
400
  }
@@ -350,16 +414,18 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
350
414
  return this.createSchemaBuilder(tableDef.schema).createTable(tableDef.name, table => {
351
415
  tableDef.getColumns().forEach(column => {
352
416
  const col = this.helper.createTableColumn(table, column, tableDef);
353
- this.configureColumn(column, col);
417
+ this.helper.configureColumn(column, col, this.knex);
354
418
  });
355
419
  for (const index of tableDef.getIndexes()) {
356
- this.createIndex(table, index, tableDef.name, !tableDef.getColumns().some(c => c.autoincrement));
420
+ const createPrimary = !tableDef.getColumns().some(c => c.autoincrement && c.primary) || this.helper.hasNonDefaultPrimaryKeyName(tableDef);
421
+ this.createIndex(table, index, tableDef, createPrimary);
357
422
  }
358
423
  for (const check of tableDef.getChecks()) {
359
424
  this.createCheck(table, check);
360
425
  }
361
426
  if (tableDef.comment) {
362
- table.comment(tableDef.comment);
427
+ const comment = this.platform.quoteValue(tableDef.comment).replace(/^'|'$/g, '');
428
+ table.comment(comment);
363
429
  }
364
430
  if (!this.helper.supportsSchemaConstraints()) {
365
431
  for (const fk of Object.values(tableDef.getForeignKeys())) {
@@ -369,30 +435,49 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
369
435
  this.helper.finalizeTable(table, this.config.get('charset'), this.config.get('collate'));
370
436
  });
371
437
  }
372
- createIndex(table, index, tableName, createPrimary = false) {
438
+ createIndex(table, index, tableDef, createPrimary = false) {
373
439
  if (index.primary && !createPrimary) {
374
440
  return;
375
441
  }
376
442
  if (index.primary) {
377
- /* istanbul ignore next */
378
- const keyName = tableName.includes('.') ? tableName.split('.').pop() + '_pkey' : undefined;
443
+ const keyName = this.helper.hasNonDefaultPrimaryKeyName(tableDef) ? index.keyName : undefined;
379
444
  table.primary(index.columnNames, keyName);
380
445
  }
381
446
  else if (index.unique) {
382
- table.unique(index.columnNames, { indexName: index.keyName });
447
+ // JSON columns can have unique index but not unique constraint, and we need to distinguish those, so we can properly drop them
448
+ if (index.columnNames.some(column => column.includes('.'))) {
449
+ const columns = this.platform.getJsonIndexDefinition(index);
450
+ table.index(columns.map(column => this.knex.raw(`(${column})`)), index.keyName, { indexType: 'unique' });
451
+ }
452
+ else {
453
+ table.unique(index.columnNames, { indexName: index.keyName });
454
+ }
383
455
  }
384
456
  else if (index.expression) {
385
457
  this.helper.pushTableQuery(table, index.expression);
386
458
  }
459
+ else if (index.type === 'fulltext') {
460
+ const columns = index.columnNames.map(name => ({ name, type: tableDef.getColumn(name).type }));
461
+ if (this.platform.supportsCreatingFullTextIndex()) {
462
+ this.helper.pushTableQuery(table, this.platform.getFullTextIndexExpression(index.keyName, tableDef.schema, tableDef.name, columns));
463
+ }
464
+ }
387
465
  else {
388
- table.index(index.columnNames, index.keyName, index.type);
466
+ // JSON columns can have unique index but not unique constraint, and we need to distinguish those, so we can properly drop them
467
+ if (index.columnNames.some(column => column.includes('.'))) {
468
+ const columns = this.platform.getJsonIndexDefinition(index);
469
+ table.index(columns.map(column => this.knex.raw(`(${column})`)), index.keyName, index.type);
470
+ }
471
+ else {
472
+ table.index(index.columnNames, index.keyName, index.type);
473
+ }
389
474
  }
390
475
  }
391
476
  dropIndex(table, index, oldIndexName = index.keyName) {
392
477
  if (index.primary) {
393
478
  table.dropPrimary(oldIndexName);
394
479
  }
395
- else if (index.unique) {
480
+ else if (index.unique && index.constraint) {
396
481
  table.dropUnique(index.columnNames, oldIndexName);
397
482
  }
398
483
  else {
@@ -412,9 +497,6 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
412
497
  }
413
498
  return builder;
414
499
  }
415
- configureColumn(column, col, changedProperties) {
416
- return this.helper.configureColumn(column, col, this.knex, changedProperties);
417
- }
418
500
  createForeignKeys(table, tableDef, schema) {
419
501
  if (!this.helper.supportsSchemaConstraints()) {
420
502
  return;
@@ -433,5 +515,9 @@ class SchemaGenerator extends core_1.AbstractSchemaGenerator {
433
515
  const tmp = dump.replace(/pragma table_.+/ig, '').replace(/\n\n+/g, '\n').trim();
434
516
  return tmp ? tmp + append : '';
435
517
  }
518
+ get knex() {
519
+ return this.connection.getKnex();
520
+ }
436
521
  }
437
- exports.SchemaGenerator = SchemaGenerator;
522
+ exports.SqlSchemaGenerator = SqlSchemaGenerator;
523
+ exports.SchemaGenerator = SqlSchemaGenerator;
@@ -1,5 +1,5 @@
1
1
  export * from './DatabaseSchema';
2
2
  export * from './DatabaseTable';
3
- export * from './SchemaGenerator';
3
+ export * from './SqlSchemaGenerator';
4
4
  export * from './SchemaHelper';
5
5
  export * from './SchemaComparator';
@@ -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];
@@ -12,6 +16,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
12
16
  Object.defineProperty(exports, "__esModule", { value: true });
13
17
  __exportStar(require("./DatabaseSchema"), exports);
14
18
  __exportStar(require("./DatabaseTable"), exports);
15
- __exportStar(require("./SchemaGenerator"), exports);
19
+ __exportStar(require("./SqlSchemaGenerator"), exports);
16
20
  __exportStar(require("./SchemaHelper"), exports);
17
21
  __exportStar(require("./SchemaComparator"), exports);
@@ -1,20 +1,21 @@
1
1
  import type { Knex } from 'knex';
2
- import type { CheckCallback, Dictionary, EntityProperty, GroupOperator, QBFilterQuery, QueryOrderMap, Type } from '@mikro-orm/core';
3
- import type { QueryType } from './query/enums';
2
+ import type { CheckCallback, Dictionary, EntityProperty, GroupOperator, RawQueryFragment, QBFilterQuery, QueryOrderMap, Type, QueryFlag } from '@mikro-orm/core';
3
+ import type { JoinType, QueryType } from './query/enums';
4
4
  import type { DatabaseSchema, DatabaseTable } from './schema';
5
5
  export interface Table {
6
6
  table_name: string;
7
7
  schema_name?: string;
8
8
  table_comment?: string;
9
9
  }
10
- export declare type KnexStringRef = Knex.Ref<string, {
10
+ export type KnexStringRef = Knex.Ref<string, {
11
11
  [alias: string]: string;
12
12
  }>;
13
- export declare type Field<T> = string | keyof T | KnexStringRef | Knex.QueryBuilder;
13
+ type AnyString = string & {};
14
+ export type Field<T> = AnyString | keyof T | RawQueryFragment | KnexStringRef | Knex.QueryBuilder;
14
15
  export interface JoinOptions {
15
16
  table: string;
16
17
  schema?: string;
17
- type: 'leftJoin' | 'innerJoin' | 'pivotJoin';
18
+ type: JoinType;
18
19
  alias: string;
19
20
  ownerAlias: string;
20
21
  inverseAlias?: string;
@@ -24,6 +25,8 @@ export interface JoinOptions {
24
25
  path?: string;
25
26
  prop: EntityProperty;
26
27
  cond: Dictionary;
28
+ cond_?: Dictionary;
29
+ subquery?: string;
27
30
  }
28
31
  export interface Column {
29
32
  name: string;
@@ -37,11 +40,14 @@ export interface Column {
37
40
  scale?: number;
38
41
  default?: string | null;
39
42
  comment?: string;
43
+ generated?: string;
44
+ nativeEnumName?: string;
40
45
  enumItems?: string[];
41
46
  primary?: boolean;
42
47
  unique?: boolean;
43
48
  /** mysql only */
44
49
  extra?: string;
50
+ ignoreSchemaChanges?: ('type' | 'extra')[];
45
51
  }
46
52
  export interface ForeignKey {
47
53
  columnNames: string[];
@@ -52,20 +58,22 @@ export interface ForeignKey {
52
58
  updateRule?: string;
53
59
  deleteRule?: string;
54
60
  }
55
- export interface Index {
61
+ export interface IndexDef {
56
62
  columnNames: string[];
57
63
  keyName: string;
58
64
  unique: boolean;
65
+ constraint: boolean;
59
66
  primary: boolean;
60
67
  composite?: boolean;
61
68
  expression?: string;
69
+ options?: Dictionary;
62
70
  type?: string | Readonly<{
63
71
  indexType?: string;
64
72
  storageEngineIndexType?: 'hash' | 'btree';
65
73
  predicate?: Knex.QueryBuilder;
66
74
  }>;
67
75
  }
68
- export interface Check<T = unknown> {
76
+ export interface CheckDef<T = unknown> {
69
77
  name: string;
70
78
  expression: string | CheckCallback<T>;
71
79
  definition?: string;
@@ -81,17 +89,18 @@ export interface TableDifference {
81
89
  name: string;
82
90
  changedComment?: string;
83
91
  fromTable: DatabaseTable;
92
+ toTable: DatabaseTable;
84
93
  addedColumns: Dictionary<Column>;
85
94
  changedColumns: Dictionary<ColumnDifference>;
86
95
  removedColumns: Dictionary<Column>;
87
96
  renamedColumns: Dictionary<Column>;
88
- addedIndexes: Dictionary<Index>;
89
- changedIndexes: Dictionary<Index>;
90
- removedIndexes: Dictionary<Index>;
91
- renamedIndexes: Dictionary<Index>;
92
- addedChecks: Dictionary<Check>;
93
- changedChecks: Dictionary<Check>;
94
- removedChecks: Dictionary<Check>;
97
+ addedIndexes: Dictionary<IndexDef>;
98
+ changedIndexes: Dictionary<IndexDef>;
99
+ removedIndexes: Dictionary<IndexDef>;
100
+ renamedIndexes: Dictionary<IndexDef>;
101
+ addedChecks: Dictionary<CheckDef>;
102
+ changedChecks: Dictionary<CheckDef>;
103
+ removedChecks: Dictionary<CheckDef>;
95
104
  addedForeignKeys: Dictionary<ForeignKey>;
96
105
  changedForeignKeys: Dictionary<ForeignKey>;
97
106
  removedForeignKeys: Dictionary<ForeignKey>;
@@ -107,7 +116,7 @@ export interface SchemaDifference {
107
116
  }
108
117
  export interface IQueryBuilder<T> {
109
118
  readonly alias: string;
110
- readonly type: QueryType;
119
+ readonly type?: QueryType;
111
120
  _fields?: Field<T>[];
112
121
  select(fields: Field<T> | Field<T>[], distinct?: boolean): this;
113
122
  addSelect(fields: string | string[]): this;
@@ -116,10 +125,12 @@ export interface IQueryBuilder<T> {
116
125
  delete(cond?: QBFilterQuery): this;
117
126
  truncate(): this;
118
127
  count(field?: string | string[], distinct?: boolean): this;
119
- join(field: string, alias: string, cond?: QBFilterQuery, type?: 'leftJoin' | 'innerJoin' | 'pivotJoin', path?: string): this;
128
+ join(field: string, alias: string, cond?: QBFilterQuery, type?: JoinType, path?: string): this;
129
+ innerJoin(field: string, alias: string, cond?: QBFilterQuery): this;
120
130
  leftJoin(field: string, alias: string, cond?: QBFilterQuery): this;
121
131
  joinAndSelect(field: string, alias: string, cond?: QBFilterQuery): this;
122
- leftJoinAndSelect(field: string, alias: string, cond?: QBFilterQuery): this;
132
+ leftJoinAndSelect(field: string, alias: string, cond?: QBFilterQuery, fields?: string[]): this;
133
+ innerJoinAndSelect(field: string, alias: string, cond?: QBFilterQuery, fields?: string[]): this;
123
134
  withSubQuery(subQuery: Knex.QueryBuilder, alias: string): this;
124
135
  where(cond: QBFilterQuery<T>, operator?: keyof typeof GroupOperator): this;
125
136
  where(cond: string, params?: any[], operator?: keyof typeof GroupOperator): this;
@@ -130,21 +141,33 @@ export interface IQueryBuilder<T> {
130
141
  orderBy(orderBy: QueryOrderMap<T>): this;
131
142
  groupBy(fields: (string | keyof T) | (string | keyof T)[]): this;
132
143
  having(cond?: QBFilterQuery | string, params?: any[]): this;
133
- getAliasForJoinPath(path: string): string | undefined;
144
+ getAliasForJoinPath(path: string, options?: ICriteriaNodeProcessOptions): string | undefined;
145
+ getJoinForPath(path?: string, options?: ICriteriaNodeProcessOptions): JoinOptions | undefined;
134
146
  getNextAlias(entityName?: string): string;
147
+ clone(reset?: boolean): IQueryBuilder<T>;
148
+ setFlag(flag: QueryFlag): this;
149
+ unsetFlag(flag: QueryFlag): this;
150
+ hasFlag(flag: QueryFlag): boolean;
135
151
  }
136
- export interface ICriteriaNode {
152
+ export interface ICriteriaNodeProcessOptions {
153
+ alias?: string;
154
+ matchPopulateJoins?: boolean;
155
+ ignoreBranching?: boolean;
156
+ preferNoBranch?: boolean;
157
+ }
158
+ export interface ICriteriaNode<T extends object> {
137
159
  readonly entityName: string;
138
- readonly parent?: ICriteriaNode | undefined;
160
+ readonly parent?: ICriteriaNode<T> | undefined;
139
161
  readonly key?: string | undefined;
140
162
  payload: any;
141
163
  prop?: EntityProperty;
142
164
  index?: number;
143
- process<T>(qb: IQueryBuilder<T>, alias?: string): any;
165
+ process(qb: IQueryBuilder<T>, options?: ICriteriaNodeProcessOptions): any;
144
166
  shouldInline(payload: any): boolean;
145
- willAutoJoin<T>(qb: IQueryBuilder<T>, alias?: string): boolean;
167
+ willAutoJoin(qb: IQueryBuilder<T>, alias?: string): boolean;
146
168
  shouldRename(payload: any): boolean;
147
169
  renameFieldToPK<T>(qb: IQueryBuilder<T>): string;
148
170
  getPath(addIndex?: boolean): string;
149
171
  getPivotPath(path: string): string;
150
172
  }
173
+ export {};