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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/AbstractSqlConnection.js +8 -2
  2. package/AbstractSqlDriver.d.ts +5 -5
  3. package/AbstractSqlDriver.js +21 -10
  4. package/MonkeyPatchable.d.ts +5 -0
  5. package/MonkeyPatchable.js +15 -0
  6. package/README.md +17 -11
  7. package/SqlEntityManager.d.ts +1 -1
  8. package/SqlEntityManager.js +1 -2
  9. package/dialects/index.d.ts +4 -0
  10. package/dialects/index.js +20 -0
  11. package/dialects/mssql/MsSqlColumnCompiler.d.ts +4 -0
  12. package/dialects/mssql/MsSqlColumnCompiler.js +10 -0
  13. package/dialects/mssql/MsSqlKnexDialect.d.ts +6 -0
  14. package/dialects/mssql/MsSqlKnexDialect.js +22 -0
  15. package/dialects/mssql/MsSqlQueryCompiler.d.ts +12 -0
  16. package/dialects/mssql/MsSqlQueryCompiler.js +94 -0
  17. package/dialects/mssql/MsSqlTableCompiler.d.ts +9 -0
  18. package/dialects/mssql/MsSqlTableCompiler.js +40 -0
  19. package/dialects/mssql/index.d.ts +1 -0
  20. package/dialects/mssql/index.js +17 -0
  21. package/dialects/mysql/MariaDbKnexDialect.d.ts +6 -0
  22. package/dialects/mysql/MariaDbKnexDialect.js +16 -0
  23. package/dialects/mysql/MySqlColumnCompiler.d.ts +9 -0
  24. package/dialects/mysql/MySqlColumnCompiler.js +19 -0
  25. package/dialects/mysql/MySqlConnection.d.ts +8 -0
  26. package/dialects/mysql/MySqlConnection.js +43 -0
  27. package/dialects/mysql/MySqlExceptionConverter.d.ts +9 -0
  28. package/dialects/mysql/MySqlExceptionConverter.js +83 -0
  29. package/dialects/mysql/MySqlKnexDialect.d.ts +5 -0
  30. package/dialects/mysql/MySqlKnexDialect.js +21 -0
  31. package/dialects/mysql/MySqlPlatform.d.ts +31 -0
  32. package/dialects/mysql/MySqlPlatform.js +88 -0
  33. package/dialects/mysql/MySqlQueryCompiler.d.ts +5 -0
  34. package/dialects/mysql/MySqlQueryCompiler.js +23 -0
  35. package/dialects/mysql/MySqlSchemaHelper.d.ts +43 -0
  36. package/dialects/mysql/MySqlSchemaHelper.js +297 -0
  37. package/dialects/mysql/index.d.ts +6 -0
  38. package/dialects/mysql/index.js +22 -0
  39. package/dialects/postgresql/PostgreSqlKnexDialect.d.ts +6 -0
  40. package/dialects/postgresql/PostgreSqlKnexDialect.js +19 -0
  41. package/dialects/postgresql/PostgreSqlTableCompiler.d.ts +11 -0
  42. package/dialects/postgresql/PostgreSqlTableCompiler.js +89 -0
  43. package/dialects/postgresql/index.d.ts +1 -0
  44. package/dialects/postgresql/index.js +17 -0
  45. package/dialects/sqlite/BaseSqliteConnection.d.ts +10 -0
  46. package/dialects/sqlite/BaseSqliteConnection.js +56 -0
  47. package/dialects/sqlite/BaseSqlitePlatform.d.ts +49 -0
  48. package/dialects/sqlite/BaseSqlitePlatform.js +78 -0
  49. package/dialects/sqlite/BaseSqliteSchemaHelper.d.ts +27 -0
  50. package/dialects/sqlite/BaseSqliteSchemaHelper.js +172 -0
  51. package/dialects/sqlite/BetterSqliteKnexDialect.d.ts +5 -0
  52. package/dialects/sqlite/BetterSqliteKnexDialect.js +15 -0
  53. package/dialects/sqlite/LibSqlKnexDialect.d.ts +6 -0
  54. package/dialects/sqlite/LibSqlKnexDialect.js +18 -0
  55. package/dialects/sqlite/SqliteKnexDialect.d.ts +8 -0
  56. package/dialects/sqlite/SqliteKnexDialect.js +67 -0
  57. package/dialects/sqlite/SqliteTableCompiler.d.ts +5 -0
  58. package/dialects/sqlite/SqliteTableCompiler.js +45 -0
  59. package/dialects/sqlite/index.d.ts +7 -0
  60. package/dialects/sqlite/index.js +23 -0
  61. package/index.d.ts +1 -0
  62. package/index.js +1 -0
  63. package/index.mjs +17 -0
  64. package/package.json +2 -2
  65. package/query/QueryBuilder.d.ts +59 -41
  66. package/query/QueryBuilder.js +61 -23
  67. package/query/QueryBuilderHelper.js +8 -3
  68. package/schema/DatabaseTable.js +21 -4
  69. package/schema/SchemaComparator.js +16 -3
  70. package/schema/SchemaHelper.d.ts +5 -1
  71. package/schema/SchemaHelper.js +20 -2
  72. package/schema/SqlSchemaGenerator.d.ts +12 -4
  73. package/schema/SqlSchemaGenerator.js +53 -28
  74. package/typings.d.ts +2 -1
@@ -15,6 +15,7 @@ export declare abstract class SchemaHelper {
15
15
  finalizeTable(table: Knex.TableBuilder, charset: string, collate?: string): void;
16
16
  supportsSchemaConstraints(): boolean;
17
17
  getPrimaryKeys(connection: AbstractSqlConnection, indexes: IndexDef[] | undefined, tableName: string, schemaName?: string): Promise<string[]>;
18
+ inferLengthFromColumnType(type: string): number | undefined;
18
19
  getForeignKeys(connection: AbstractSqlConnection, tableName: string, schemaName?: string): Promise<Dictionary>;
19
20
  protected getTableKey(t: Table): string;
20
21
  getEnumDefinitions(connection: AbstractSqlConnection, checks: CheckDef[], tableName: string, schemaName?: string): Promise<Dictionary<string[]>>;
@@ -27,8 +28,9 @@ export declare abstract class SchemaHelper {
27
28
  getCreateIndexSQL(tableName: string, index: IndexDef, partialExpression?: boolean): string;
28
29
  getDropIndexSQL(tableName: string, index: IndexDef): string;
29
30
  getRenameIndexSQL(tableName: string, index: IndexDef, oldIndexName: string): string;
31
+ getDropColumnsSQL(tableName: string, columns: Column[], schemaName?: string): string;
30
32
  hasNonDefaultPrimaryKeyName(table: DatabaseTable): boolean;
31
- createTableColumn(table: Knex.TableBuilder, column: Column, fromTable: DatabaseTable, changedProperties?: Set<string>, alter?: boolean): Knex.ColumnBuilder;
33
+ createTableColumn(table: Knex.TableBuilder, column: Column, fromTable: DatabaseTable, changedProperties?: Set<string>, alter?: boolean): Knex.ColumnBuilder | undefined;
32
34
  configureColumn(column: Column, col: Knex.ColumnBuilder, knex: Knex, changedProperties?: Set<string>): Knex.ColumnBuilder;
33
35
  configureColumnDefault(column: Column, col: Knex.ColumnBuilder, knex: Knex, changedProperties?: Set<string>): Knex.ColumnBuilder;
34
36
  getPreAlterTable(tableDiff: TableDifference, safe: boolean): string;
@@ -45,6 +47,8 @@ export declare abstract class SchemaHelper {
45
47
  normalizeDefaultValue(defaultValue: string, length?: number, defaultValues?: Dictionary<string[]>): string | number;
46
48
  getCreateDatabaseSQL(name: string): string;
47
49
  getDropDatabaseSQL(name: string): string;
50
+ getCreateNamespaceSQL(name: string): string;
51
+ getDropNamespaceSQL(name: string): string;
48
52
  getDatabaseExistsSQL(name: string): string;
49
53
  getDatabaseNotExistsError(dbName: string): string;
50
54
  getManagementDbName(): string;
@@ -29,6 +29,9 @@ class SchemaHelper {
29
29
  const pks = indexes.filter(i => i.primary).map(pk => pk.columnNames);
30
30
  return core_1.Utils.flatten(pks);
31
31
  }
32
+ inferLengthFromColumnType(type) {
33
+ return undefined;
34
+ }
32
35
  async getForeignKeys(connection, tableName, schemaName) {
33
36
  const fks = await connection.execute(this.getForeignKeysSQL(tableName, schemaName));
34
37
  return this.mapForeignKeys(fks, tableName, schemaName);
@@ -99,6 +102,11 @@ class SchemaHelper {
99
102
  getRenameIndexSQL(tableName, index, oldIndexName) {
100
103
  return [this.getDropIndexSQL(tableName, { ...index, keyName: oldIndexName }), this.getCreateIndexSQL(tableName, index)].join(';\n');
101
104
  }
105
+ getDropColumnsSQL(tableName, columns, schemaName) {
106
+ const name = this.platform.quoteIdentifier((schemaName && schemaName !== this.platform.getDefaultSchemaName() ? schemaName + '.' : '') + tableName);
107
+ const drops = columns.map(column => `drop column ${this.platform.quoteIdentifier(column.name)}`).join(', ');
108
+ return `alter table ${name} ${drops}`;
109
+ }
102
110
  hasNonDefaultPrimaryKeyName(table) {
103
111
  const pkIndex = table.getPrimaryKey();
104
112
  if (!pkIndex || !this.platform.supportsCustomPrimaryKeyNames()) {
@@ -199,6 +207,7 @@ class SchemaHelper {
199
207
  referencedColumnNames: [fk.referenced_column_name],
200
208
  updateRule: fk.update_rule.toLowerCase(),
201
209
  deleteRule: fk.delete_rule.toLowerCase(),
210
+ deferMode: fk.defer_mode,
202
211
  };
203
212
  }
204
213
  return ret;
@@ -220,10 +229,19 @@ class SchemaHelper {
220
229
  return norm[0].replace('(?)', length != null ? `(${length})` : '');
221
230
  }
222
231
  getCreateDatabaseSQL(name) {
223
- return `create database ${name}`;
232
+ // two line breaks to force separate execution
233
+ return `create database ${name};\n\nuse ${name}`;
224
234
  }
225
235
  getDropDatabaseSQL(name) {
226
- return `drop database if exists ${name}`;
236
+ return `drop database if exists ${this.platform.quoteIdentifier(name)}`;
237
+ }
238
+ /* istanbul ignore next */
239
+ getCreateNamespaceSQL(name) {
240
+ return `create schema if not exists ${this.platform.quoteIdentifier(name)}`;
241
+ }
242
+ /* istanbul ignore next */
243
+ getDropNamespaceSQL(name) {
244
+ return `drop schema if exists ${this.platform.quoteIdentifier(name)}`;
227
245
  }
228
246
  getDatabaseExistsSQL(name) {
229
247
  return `select 1 from information_schema.schemata where schema_name = '${name}'`;
@@ -1,10 +1,15 @@
1
- import { AbstractSchemaGenerator, type MikroORM, type ISchemaGenerator, type ClearDatabaseOptions, type CreateSchemaOptions, type EnsureDatabaseOptions, type DropSchemaOptions, type UpdateSchemaOptions } from '@mikro-orm/core';
1
+ import { AbstractSchemaGenerator, type ClearDatabaseOptions, type CreateSchemaOptions, type DropSchemaOptions, type EnsureDatabaseOptions, type ISchemaGenerator, type MikroORM, type Transaction, type UpdateSchemaOptions } 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
5
  export declare class SqlSchemaGenerator extends AbstractSchemaGenerator<AbstractSqlDriver> implements ISchemaGenerator {
6
- private readonly helper;
7
- private readonly options;
6
+ protected readonly helper: import("./SchemaHelper").SchemaHelper;
7
+ protected readonly options: {
8
+ disableForeignKeys?: boolean | undefined;
9
+ createForeignKeyConstraints?: boolean | undefined;
10
+ ignoreSchema?: string[] | undefined;
11
+ managementDbName?: string | undefined;
12
+ };
8
13
  protected lastEnsuredDatabase?: string;
9
14
  static register(orm: MikroORM): void;
10
15
  createSchema(options?: CreateSchemaOptions): Promise<void>;
@@ -15,6 +20,8 @@ export declare class SqlSchemaGenerator extends AbstractSchemaGenerator<Abstract
15
20
  getTargetSchema(schema?: string): DatabaseSchema;
16
21
  getCreateSchemaSQL(options?: CreateSchemaOptions): Promise<string>;
17
22
  dropSchema(options?: DropSchemaOptions): Promise<void>;
23
+ createNamespace(name: string): Promise<void>;
24
+ dropNamespace(name: string): Promise<void>;
18
25
  clearDatabase(options?: ClearDatabaseOptions): Promise<void>;
19
26
  getDropSchemaSQL(options?: Omit<DropSchemaOptions, 'dropDb'>): Promise<string>;
20
27
  private getSchemaName;
@@ -43,10 +50,11 @@ export declare class SqlSchemaGenerator extends AbstractSchemaGenerator<Abstract
43
50
  /**
44
51
  * creates new database and connects to it
45
52
  */
46
- createDatabase(name: string): Promise<void>;
53
+ createDatabase(name?: string): Promise<void>;
47
54
  dropDatabase(name?: string): Promise<void>;
48
55
  execute(sql: string, options?: {
49
56
  wrap?: boolean;
57
+ ctx?: Transaction;
50
58
  }): Promise<void>;
51
59
  private wrapSchema;
52
60
  private createSchemaBuilder;
@@ -58,7 +58,8 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
58
58
  if (namespace === this.platform.getDefaultSchemaName()) {
59
59
  continue;
60
60
  }
61
- ret += await this.dump(this.knex.schema.createSchemaIfNotExists(namespace));
61
+ const sql = this.helper.getCreateNamespaceSQL(namespace);
62
+ ret += await this.dump(this.knex.schema.raw(sql), '\n');
62
63
  }
63
64
  if (this.platform.supportsNativeEnums()) {
64
65
  const created = [];
@@ -88,6 +89,14 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
88
89
  const sql = await this.getDropSchemaSQL(options);
89
90
  await this.execute(sql);
90
91
  }
92
+ async createNamespace(name) {
93
+ const sql = await this.helper.getCreateNamespaceSQL(name);
94
+ await this.execute(sql);
95
+ }
96
+ async dropNamespace(name) {
97
+ const sql = await this.helper.getDropNamespaceSQL(name);
98
+ await this.execute(sql);
99
+ }
91
100
  async clearDatabase(options) {
92
101
  // truncate by default, so no value is considered as true
93
102
  /* istanbul ignore if */
@@ -101,12 +110,7 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
101
110
  .truncate();
102
111
  }
103
112
  await this.execute(this.helper.enableForeignKeysSQL());
104
- if (this.em) {
105
- const allowGlobalContext = this.config.get('allowGlobalContext');
106
- this.config.set('allowGlobalContext', true);
107
- this.em.clear();
108
- this.config.set('allowGlobalContext', allowGlobalContext);
109
- }
113
+ this.clearIdentityMap();
110
114
  }
111
115
  async getDropSchemaSQL(options = {}) {
112
116
  await this.ensureDatabase();
@@ -118,7 +122,7 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
118
122
  // remove FKs explicitly if we can't use cascading statement and we don't disable FK checks (we need this for circular relations)
119
123
  for (const meta of metadata) {
120
124
  const table = schema.getTable(meta.tableName);
121
- if (!this.platform.usesCascadeStatement() && table && !wrap) {
125
+ if (!this.platform.usesCascadeStatement() && table && (!wrap || options.dropForeignKeys)) {
122
126
  for (const fk of Object.values(table.getForeignKeys())) {
123
127
  const builder = this.createSchemaBuilder(table.schema).alterTable(table.name, tbl => {
124
128
  tbl.dropForeign(fk.columnNames, fk.constraintName);
@@ -186,8 +190,8 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
186
190
  let ret = '';
187
191
  if (this.platform.supportsSchemas()) {
188
192
  for (const newNamespace of schemaDiff.newNamespaces) {
189
- // schema might already exist, e.g. explicit usage of `public` in postgres
190
- ret += await this.dump(this.knex.schema.createSchemaIfNotExists(newNamespace));
193
+ const sql = this.helper.getCreateNamespaceSQL(newNamespace);
194
+ ret += await this.dump(this.knex.schema.raw(sql), '\n');
191
195
  }
192
196
  }
193
197
  if (this.platform.supportsNativeEnums()) {
@@ -240,7 +244,8 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
240
244
  }
241
245
  if (options.dropTables && !options.safe) {
242
246
  for (const removedNamespace of schemaDiff.removedNamespaces) {
243
- ret += await this.dump(this.knex.schema.dropSchema(removedNamespace));
247
+ const sql = this.helper.getDropNamespaceSQL(removedNamespace);
248
+ ret += await this.dump(this.knex.schema.raw(sql), '\n');
244
249
  }
245
250
  }
246
251
  return this.wrapSchema(ret, options);
@@ -266,11 +271,16 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
266
271
  .references(foreignKey.referencedColumnNames)
267
272
  .inTable(this.getReferencedTableName(foreignKey.referencedTableName, schema))
268
273
  .withKeyName(foreignKey.constraintName);
269
- if (foreignKey.updateRule) {
270
- builder.onUpdate(foreignKey.updateRule);
274
+ if (foreignKey.localTableName !== foreignKey.referencedTableName || this.platform.supportsMultipleCascadePaths()) {
275
+ if (foreignKey.updateRule) {
276
+ builder.onUpdate(foreignKey.updateRule);
277
+ }
278
+ if (foreignKey.deleteRule) {
279
+ builder.onDelete(foreignKey.deleteRule);
280
+ }
271
281
  }
272
- if (foreignKey.deleteRule) {
273
- builder.onDelete(foreignKey.deleteRule);
282
+ if (foreignKey.deferMode) {
283
+ builder.deferrable(foreignKey.deferMode);
274
284
  }
275
285
  }
276
286
  /**
@@ -338,10 +348,8 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
338
348
  this.dropCheck(table, check);
339
349
  }
340
350
  /* istanbul ignore else */
341
- if (!safe) {
342
- for (const column of Object.values(diff.removedColumns)) {
343
- this.helper.pushTableQuery(table, `alter table ${this.platform.quoteIdentifier(tableName)} drop column ${this.platform.quoteIdentifier(column.name)}`);
344
- }
351
+ if (!safe && Object.values(diff.removedColumns).length > 0) {
352
+ this.helper.pushTableQuery(table, this.helper.getDropColumnsSQL(tableName, Object.values(diff.removedColumns), schemaName));
345
353
  }
346
354
  }));
347
355
  ret.push(this.createSchemaBuilder(schemaName).alterTable(tableName, table => {
@@ -365,8 +373,10 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
365
373
  if (changedProperties.size === 1 && changedProperties.has('enumItems') && column.nativeEnumName) {
366
374
  continue;
367
375
  }
368
- const col = this.helper.createTableColumn(table, column, diff.fromTable, changedProperties, true).alter();
369
- this.helper.configureColumn(column, col, this.knex, changedProperties);
376
+ const col = this.helper.createTableColumn(table, column, diff.fromTable, changedProperties, true)?.alter();
377
+ if (col) {
378
+ this.helper.configureColumn(column, col, this.knex, changedProperties);
379
+ }
370
380
  }
371
381
  for (const { column } of Object.values(diff.changedColumns).filter(diff => diff.changedProperties.has('autoincrement'))) {
372
382
  this.helper.pushTableQuery(table, this.helper.getAlterColumnAutoincrement(tableName, column, schemaName));
@@ -418,9 +428,10 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
418
428
  * creates new database and connects to it
419
429
  */
420
430
  async createDatabase(name) {
431
+ name ??= this.config.get('dbName');
421
432
  const sql = this.helper.getCreateDatabaseSQL('' + this.knex.ref(name));
422
433
  if (sql) {
423
- await this.driver.execute(sql);
434
+ await this.execute(sql);
424
435
  }
425
436
  this.config.set('dbName', name);
426
437
  await this.driver.reconnect();
@@ -429,20 +440,34 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
429
440
  name ??= this.config.get('dbName');
430
441
  this.config.set('dbName', this.helper.getManagementDbName());
431
442
  await this.driver.reconnect();
432
- await this.driver.execute(this.helper.getDropDatabaseSQL('' + this.knex.ref(name)));
443
+ await this.execute(this.helper.getDropDatabaseSQL(name));
433
444
  }
434
445
  async execute(sql, options = {}) {
435
446
  options.wrap ??= false;
436
- const lines = this.wrapSchema(sql, options).split('\n').filter(i => i.trim());
437
- if (lines.length === 0) {
447
+ const lines = this.wrapSchema(sql, options).split('\n');
448
+ const groups = [];
449
+ let i = 0;
450
+ for (const line of lines) {
451
+ if (line.trim() === '') {
452
+ if (groups[i]?.length > 0) {
453
+ i++;
454
+ }
455
+ continue;
456
+ }
457
+ groups[i] ??= [];
458
+ groups[i].push(line.trim());
459
+ }
460
+ if (groups.length === 0) {
438
461
  return;
439
462
  }
440
463
  if (this.platform.supportsMultipleStatements()) {
441
- const query = lines.join('\n');
442
- await this.driver.execute(query);
464
+ for (const group of groups) {
465
+ const query = group.join('\n');
466
+ await this.driver.execute(query);
467
+ }
443
468
  return;
444
469
  }
445
- await core_1.Utils.runSerial(lines, line => this.driver.execute(line));
470
+ await core_1.Utils.runSerial(groups.flat(), line => this.driver.execute(line));
446
471
  }
447
472
  wrapSchema(sql, options) {
448
473
  options.wrap ??= this.options.disableForeignKeys;
package/typings.d.ts CHANGED
@@ -1,5 +1,5 @@
1
+ import type { DeferMode, CheckCallback, Dictionary, EntityProperty, GroupOperator, RawQueryFragment, QBFilterQuery, QueryOrderMap, Type, QueryFlag, AnyEntity, EntityName } from '@mikro-orm/core';
1
2
  import type { Knex } from 'knex';
2
- import type { CheckCallback, Dictionary, EntityProperty, GroupOperator, RawQueryFragment, QBFilterQuery, QueryOrderMap, Type, QueryFlag, AnyEntity, EntityName } from '@mikro-orm/core';
3
3
  import type { JoinType, QueryType } from './query/enums';
4
4
  import type { DatabaseSchema, DatabaseTable } from './schema';
5
5
  export interface Table {
@@ -57,6 +57,7 @@ export interface ForeignKey {
57
57
  referencedColumnNames: string[];
58
58
  updateRule?: string;
59
59
  deleteRule?: string;
60
+ deferMode?: DeferMode;
60
61
  }
61
62
  export interface IndexDef {
62
63
  columnNames: string[];