@mikro-orm/sql 7.0.0-rc.3 → 7.0.1-dev.0

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 (59) hide show
  1. package/AbstractSqlConnection.d.ts +5 -4
  2. package/AbstractSqlConnection.js +18 -5
  3. package/AbstractSqlDriver.d.ts +1 -1
  4. package/AbstractSqlDriver.js +39 -10
  5. package/AbstractSqlPlatform.d.ts +34 -0
  6. package/AbstractSqlPlatform.js +47 -3
  7. package/PivotCollectionPersister.d.ts +2 -11
  8. package/PivotCollectionPersister.js +59 -59
  9. package/README.md +5 -4
  10. package/SqlEntityManager.d.ts +1 -1
  11. package/dialects/index.d.ts +1 -0
  12. package/dialects/index.js +1 -0
  13. package/dialects/mysql/BaseMySqlPlatform.d.ts +6 -0
  14. package/dialects/mysql/BaseMySqlPlatform.js +17 -0
  15. package/dialects/mysql/MySqlSchemaHelper.d.ts +1 -1
  16. package/dialects/mysql/MySqlSchemaHelper.js +6 -6
  17. package/dialects/oracledb/OracleDialect.d.ts +78 -0
  18. package/dialects/oracledb/OracleDialect.js +166 -0
  19. package/dialects/oracledb/OracleNativeQueryBuilder.d.ts +19 -0
  20. package/dialects/oracledb/OracleNativeQueryBuilder.js +249 -0
  21. package/dialects/oracledb/index.d.ts +2 -0
  22. package/dialects/oracledb/index.js +2 -0
  23. package/dialects/postgresql/BasePostgreSqlPlatform.d.ts +6 -0
  24. package/dialects/postgresql/BasePostgreSqlPlatform.js +12 -8
  25. package/dialects/postgresql/PostgreSqlSchemaHelper.js +13 -13
  26. package/dialects/sqlite/SqlitePlatform.d.ts +1 -0
  27. package/dialects/sqlite/SqlitePlatform.js +3 -0
  28. package/dialects/sqlite/SqliteSchemaHelper.js +12 -8
  29. package/index.d.ts +1 -1
  30. package/index.js +0 -1
  31. package/package.json +3 -3
  32. package/plugin/index.d.ts +1 -14
  33. package/plugin/index.js +13 -13
  34. package/plugin/transformer.d.ts +6 -22
  35. package/plugin/transformer.js +81 -73
  36. package/query/ArrayCriteriaNode.d.ts +1 -1
  37. package/query/CriteriaNodeFactory.js +15 -3
  38. package/query/NativeQueryBuilder.d.ts +3 -3
  39. package/query/NativeQueryBuilder.js +4 -2
  40. package/query/ObjectCriteriaNode.js +4 -4
  41. package/query/QueryBuilder.d.ts +58 -62
  42. package/query/QueryBuilder.js +377 -370
  43. package/query/QueryBuilderHelper.d.ts +14 -11
  44. package/query/QueryBuilderHelper.js +324 -137
  45. package/query/ScalarCriteriaNode.js +3 -1
  46. package/query/enums.d.ts +2 -0
  47. package/query/enums.js +2 -0
  48. package/schema/DatabaseSchema.d.ts +7 -5
  49. package/schema/DatabaseSchema.js +50 -33
  50. package/schema/DatabaseTable.d.ts +8 -6
  51. package/schema/DatabaseTable.js +84 -60
  52. package/schema/SchemaComparator.d.ts +1 -3
  53. package/schema/SchemaComparator.js +22 -20
  54. package/schema/SchemaHelper.d.ts +2 -13
  55. package/schema/SchemaHelper.js +2 -1
  56. package/schema/SqlSchemaGenerator.d.ts +4 -14
  57. package/schema/SqlSchemaGenerator.js +15 -7
  58. package/typings.d.ts +4 -1
  59. package/tsconfig.build.tsbuildinfo +0 -1
@@ -3,13 +3,13 @@ import { ArrayType, BooleanType, DateTimeType, inspect, JsonType, parseJsonSafe,
3
3
  * Compares two Schemas and return an instance of SchemaDifference.
4
4
  */
5
5
  export class SchemaComparator {
6
- platform;
7
- helper;
8
- logger;
6
+ #helper;
7
+ #logger;
8
+ #platform;
9
9
  constructor(platform) {
10
- this.platform = platform;
11
- this.helper = this.platform.getSchemaHelper();
12
- this.logger = this.platform.getConfig().getLogger();
10
+ this.#platform = platform;
11
+ this.#helper = this.#platform.getSchemaHelper();
12
+ this.#logger = this.#platform.getConfig().getLogger();
13
13
  }
14
14
  /**
15
15
  * Returns a SchemaDifference object containing the differences between the schemas fromSchema and toSchema.
@@ -35,13 +35,13 @@ export class SchemaComparator {
35
35
  };
36
36
  const foreignKeysToTable = {};
37
37
  for (const namespace of toSchema.getNamespaces()) {
38
- if (fromSchema.hasNamespace(namespace) || namespace === this.platform.getDefaultSchemaName()) {
38
+ if (fromSchema.hasNamespace(namespace) || namespace === this.#platform.getDefaultSchemaName()) {
39
39
  continue;
40
40
  }
41
41
  diff.newNamespaces.add(namespace);
42
42
  }
43
43
  for (const namespace of fromSchema.getNamespaces()) {
44
- if (toSchema.hasNamespace(namespace) || namespace === this.platform.getDefaultSchemaName()) {
44
+ if (toSchema.hasNamespace(namespace) || namespace === this.#platform.getDefaultSchemaName()) {
45
45
  continue;
46
46
  }
47
47
  diff.removedNamespaces.add(namespace);
@@ -418,7 +418,7 @@ export class SchemaComparator {
418
418
  if (key1.deferMode !== key2.deferMode) {
419
419
  return true;
420
420
  }
421
- if (key1.localTableName === key1.referencedTableName && !this.platform.supportsMultipleCascadePaths()) {
421
+ if (key1.localTableName === key1.referencedTableName && !this.#platform.supportsMultipleCascadePaths()) {
422
422
  return false;
423
423
  }
424
424
  if (key1.columnNames.some(col => tableDifferences.changedColumns[col]?.changedProperties.has('type'))) {
@@ -429,7 +429,9 @@ export class SchemaComparator {
429
429
  return (key[method] ?? defaultRule[0]).toLowerCase().replace(defaultRule[1], defaultRule[0]).replace(/"/g, '');
430
430
  };
431
431
  const compare = (method) => rule(key1, method) === rule(key2, method);
432
- return !compare('updateRule') || !compare('deleteRule');
432
+ // Skip updateRule comparison for platforms that don't support ON UPDATE (e.g., Oracle)
433
+ const updateRuleDiffers = this.#platform.supportsOnUpdate() && !compare('updateRule');
434
+ return updateRuleDiffers || !compare('deleteRule');
433
435
  }
434
436
  /**
435
437
  * Returns the difference between the columns
@@ -438,10 +440,10 @@ export class SchemaComparator {
438
440
  const changedProperties = new Set();
439
441
  const fromProp = this.mapColumnToProperty({ ...fromColumn, autoincrement: false });
440
442
  const toProp = this.mapColumnToProperty({ ...toColumn, autoincrement: false });
441
- const fromColumnType = this.platform.normalizeColumnType(fromColumn.mappedType.getColumnType(fromProp, this.platform).toLowerCase(), fromProp);
443
+ const fromColumnType = this.#platform.normalizeColumnType(fromColumn.mappedType.getColumnType(fromProp, this.#platform).toLowerCase(), fromProp);
442
444
  const fromNativeEnum = fromTable.nativeEnums[fromColumnType] ??
443
445
  Object.values(fromTable.nativeEnums).find(e => e.name === fromColumnType && e.schema !== '*');
444
- let toColumnType = this.platform.normalizeColumnType(toColumn.mappedType.getColumnType(toProp, this.platform).toLowerCase(), toProp);
446
+ let toColumnType = this.#platform.normalizeColumnType(toColumn.mappedType.getColumnType(toProp, this.#platform).toLowerCase(), toProp);
445
447
  const log = (msg, params) => {
446
448
  if (logging) {
447
449
  const copy = Utils.copy(params);
@@ -456,7 +458,7 @@ export class SchemaComparator {
456
458
  !toColumn.generated) {
457
459
  if (!toColumnType.includes('.') &&
458
460
  fromTable.schema &&
459
- fromTable.schema !== this.platform.getDefaultSchemaName()) {
461
+ fromTable.schema !== this.#platform.getDefaultSchemaName()) {
460
462
  toColumnType = `${fromTable.schema}.${toColumnType}`;
461
463
  }
462
464
  if (fromColumnType !== toColumnType) {
@@ -476,7 +478,7 @@ export class SchemaComparator {
476
478
  log(`'autoincrement' changed for column ${fromTable.name}.${fromColumn.name}`, { fromColumn, toColumn });
477
479
  changedProperties.add('autoincrement');
478
480
  }
479
- if (!!fromColumn.unsigned !== !!toColumn.unsigned && this.platform.supportsUnsigned()) {
481
+ if (!!fromColumn.unsigned !== !!toColumn.unsigned && this.#platform.supportsUnsigned()) {
480
482
  log(`'unsigned' changed for column ${fromTable.name}.${fromColumn.name}`, { fromColumn, toColumn });
481
483
  changedProperties.add('unsigned');
482
484
  }
@@ -573,7 +575,7 @@ export class SchemaComparator {
573
575
  // index that has no constraints.
574
576
  return true;
575
577
  }
576
- if (this.platform.supportsDeferredUniqueConstraints() && index1.deferMode !== index2.deferMode) {
578
+ if (this.#platform.supportsDeferredUniqueConstraints() && index1.deferMode !== index2.deferMode) {
577
579
  return false;
578
580
  }
579
581
  return index1.primary === index2.primary && index1.unique === index2.unique;
@@ -697,15 +699,15 @@ export class SchemaComparator {
697
699
  if (from.default && to.default) {
698
700
  return from.default.toString().toLowerCase() === to.default.toString().toLowerCase();
699
701
  }
700
- if (['', this.helper.getDefaultEmptyString()].includes(to.default) && from.default != null) {
701
- return ['', this.helper.getDefaultEmptyString()].includes(from.default.toString());
702
+ if (['', this.#helper.getDefaultEmptyString()].includes(to.default) && from.default != null) {
703
+ return ['', this.#helper.getDefaultEmptyString()].includes(from.default.toString());
702
704
  }
703
705
  // eslint-disable-next-line eqeqeq
704
706
  return from.default == to.default; // == intentionally
705
707
  }
706
708
  mapColumnToProperty(column) {
707
- const length = column.type.match(/\w+\((\d+)\)/);
708
- const match = column.type.match(/\w+\((\d+), ?(\d+)\)/);
709
+ const length = /\w+\((\d+)\)/.exec(column.type);
710
+ const match = /\w+\((\d+), ?(\d+)\)/.exec(column.type);
709
711
  return {
710
712
  fieldNames: [column.name],
711
713
  columnTypes: [column.type],
@@ -720,6 +722,6 @@ export class SchemaComparator {
720
722
  if (params) {
721
723
  message += ' ' + inspect(params);
722
724
  }
723
- this.logger.log('schema', message);
725
+ this.#logger.log('schema', message);
724
726
  }
725
727
  }
@@ -1,4 +1,4 @@
1
- import { type Connection, type Dictionary, RawQueryFragment } from '@mikro-orm/core';
1
+ import { type Connection, type Dictionary, type Options, RawQueryFragment } from '@mikro-orm/core';
2
2
  import type { AbstractSqlConnection } from '../AbstractSqlConnection.js';
3
3
  import type { AbstractSqlPlatform } from '../AbstractSqlPlatform.js';
4
4
  import type { CheckDef, Column, ForeignKey, IndexDef, Table, TableDifference } from '../typings.js';
@@ -71,18 +71,7 @@ export declare abstract class SchemaHelper {
71
71
  createCheck(table: DatabaseTable, check: CheckDef): string;
72
72
  protected getTableName(table: string, schema?: string): string;
73
73
  getTablesGroupedBySchemas(tables: Table[]): Map<string | undefined, Table[]>;
74
- get options(): {
75
- disableForeignKeys?: boolean;
76
- disableForeignKeysForClear?: boolean;
77
- createForeignKeyConstraints?: boolean;
78
- ignoreSchema?: string[];
79
- skipTables?: (string | RegExp)[];
80
- skipViews?: (string | RegExp)[];
81
- skipColumns?: Dictionary<(string | RegExp)[]>;
82
- managementDbName?: string;
83
- defaultUpdateRule?: "cascade" | "no action" | "set null" | "set default" | "restrict";
84
- defaultDeleteRule?: "cascade" | "no action" | "set null" | "set default" | "restrict";
85
- };
74
+ get options(): NonNullable<Options['schemaGenerator']>;
86
75
  protected processComment(comment: string): string;
87
76
  protected quote(...keys: (string | undefined)[]): string;
88
77
  dropForeignKey(tableName: string, constraintName: string): string;
@@ -36,7 +36,7 @@ export class SchemaHelper {
36
36
  return Utils.flatten(pks);
37
37
  }
38
38
  inferLengthFromColumnType(type) {
39
- const match = type.match(/^\w+\s*(?:\(\s*(\d+)\s*\)|$)/);
39
+ const match = /^\w+\s*(?:\(\s*(\d+)\s*\)|$)/.exec(type);
40
40
  if (!match) {
41
41
  return;
42
42
  }
@@ -416,6 +416,7 @@ export class SchemaHelper {
416
416
  return norm[0].replace('(?)', length != null ? `(${length})` : '');
417
417
  }
418
418
  getCreateDatabaseSQL(name) {
419
+ name = this.quote(name);
419
420
  // two line breaks to force separate execution
420
421
  return `create database ${name};\n\nuse ${name}`;
421
422
  }
@@ -1,22 +1,12 @@
1
- import { type ClearDatabaseOptions, type CreateSchemaOptions, type Dictionary, type DropSchemaOptions, type EnsureDatabaseOptions, type EntityMetadata, type ISchemaGenerator, type MikroORM, type Transaction, type UpdateSchemaOptions } from '@mikro-orm/core';
1
+ import { type ClearDatabaseOptions, type CreateSchemaOptions, type DropSchemaOptions, type EnsureDatabaseOptions, type EntityMetadata, type ISchemaGenerator, type MikroORM, type Options, type Transaction, type UpdateSchemaOptions } from '@mikro-orm/core';
2
2
  import { AbstractSchemaGenerator } from '@mikro-orm/core/schema';
3
3
  import type { SchemaDifference } from '../typings.js';
4
4
  import { DatabaseSchema } from './DatabaseSchema.js';
5
5
  import type { AbstractSqlDriver } from '../AbstractSqlDriver.js';
6
+ import type { SchemaHelper } from './SchemaHelper.js';
6
7
  export declare class SqlSchemaGenerator extends AbstractSchemaGenerator<AbstractSqlDriver> implements ISchemaGenerator {
7
- protected readonly helper: import("./SchemaHelper.js").SchemaHelper;
8
- protected readonly options: {
9
- disableForeignKeys?: boolean;
10
- disableForeignKeysForClear?: boolean;
11
- createForeignKeyConstraints?: boolean;
12
- ignoreSchema?: string[];
13
- skipTables?: (string | RegExp)[];
14
- skipViews?: (string | RegExp)[];
15
- skipColumns?: Dictionary<(string | RegExp)[]>;
16
- managementDbName?: string;
17
- defaultUpdateRule?: "cascade" | "no action" | "set null" | "set default" | "restrict";
18
- defaultDeleteRule?: "cascade" | "no action" | "set null" | "set default" | "restrict";
19
- };
8
+ protected readonly helper: SchemaHelper;
9
+ protected readonly options: NonNullable<Options['schemaGenerator']>;
20
10
  protected lastEnsuredDatabase?: string;
21
11
  static register(orm: MikroORM): void;
22
12
  create(options?: CreateSchemaOptions): Promise<void>;
@@ -1,4 +1,4 @@
1
- import { CommitOrderCalculator, Utils, } from '@mikro-orm/core';
1
+ import { CommitOrderCalculator, TableNotFoundException, Utils, } from '@mikro-orm/core';
2
2
  import { AbstractSchemaGenerator } from '@mikro-orm/core/schema';
3
3
  import { DatabaseSchema } from './DatabaseSchema.js';
4
4
  import { SchemaComparator } from './SchemaComparator.js';
@@ -128,11 +128,19 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
128
128
  }
129
129
  const schema = options?.schema ?? this.config.get('schema', this.platform.getDefaultSchemaName());
130
130
  for (const meta of this.getOrderedMetadata(schema).reverse()) {
131
- await this.driver
132
- .createQueryBuilder(meta.class, this.em?.getTransactionContext(), 'write', false)
133
- .withSchema(schema)
134
- .truncate()
135
- .execute();
131
+ try {
132
+ await this.driver
133
+ .createQueryBuilder(meta.class, this.em?.getTransactionContext(), 'write', false)
134
+ .withSchema(schema)
135
+ .truncate()
136
+ .execute();
137
+ }
138
+ catch (e) {
139
+ if (this.platform.getExceptionConverter().convertException(e) instanceof TableNotFoundException) {
140
+ continue;
141
+ }
142
+ throw e;
143
+ }
136
144
  }
137
145
  if (this.options.disableForeignKeysForClear) {
138
146
  await this.execute(this.helper.enableForeignKeysSQL());
@@ -372,7 +380,7 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
372
380
  */
373
381
  async createDatabase(name, options) {
374
382
  name ??= this.config.get('dbName');
375
- const sql = this.helper.getCreateDatabaseSQL('' + this.platform.quoteIdentifier(name));
383
+ const sql = this.helper.getCreateDatabaseSQL(name);
376
384
  if (sql) {
377
385
  await this.execute(sql);
378
386
  }
package/typings.d.ts CHANGED
@@ -171,7 +171,10 @@ export interface IQueryBuilder<T> {
171
171
  readonly alias: string;
172
172
  readonly type: QueryType;
173
173
  /** @internal */
174
- _fields?: InternalField<T>[];
174
+ state: {
175
+ fields?: InternalField<T>[];
176
+ [key: string]: any;
177
+ };
175
178
  /** @internal */
176
179
  helper: any;
177
180
  select(fields: string | RawQueryFragment | (string | RawQueryFragment)[], distinct?: boolean): this;