@mikro-orm/knex 6.1.13-dev.17 → 6.1.13-dev.19

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.
@@ -125,7 +125,13 @@ class AbstractSqlConnection extends core_1.Connection {
125
125
  */
126
126
  async loadFile(path) {
127
127
  const buf = await (0, fs_extra_1.readFile)(path);
128
- await this.getKnex().raw(buf.toString());
128
+ try {
129
+ await this.getKnex().raw(buf.toString());
130
+ }
131
+ catch (e) {
132
+ /* istanbul ignore next */
133
+ throw this.platform.getExceptionConverter().convertException(e);
134
+ }
129
135
  }
130
136
  createKnexClient(type) {
131
137
  const driverOptions = this.config.get('driverOptions');
@@ -943,9 +943,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
943
943
  }
944
944
  if (tableAlias) {
945
945
  return prop.fieldNames.map(fieldName => {
946
- const name = this.platform.quoteIdentifier(`${tableAlias}.${fieldName}`);
947
- const alias = this.platform.quoteIdentifier(`${tableAlias}__${fieldName}`);
948
- return (0, core_1.raw)(`${name} as ${alias}`);
946
+ return `${tableAlias}.${fieldName} as ${tableAlias}__${fieldName}`;
949
947
  });
950
948
  }
951
949
  return prop.fieldNames;
@@ -963,10 +961,10 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
963
961
  if (args.ctx) {
964
962
  return 'write';
965
963
  }
966
- else if (args.connectionType) {
964
+ if (args.connectionType) {
967
965
  return args.connectionType;
968
966
  }
969
- else if (this.config.get('preferReadReplicas') === true) {
967
+ if (this.config.get('preferReadReplicas')) {
970
968
  return 'read';
971
969
  }
972
970
  return 'write';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/knex",
3
- "version": "6.1.13-dev.17",
3
+ "version": "6.1.13-dev.19",
4
4
  "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",
@@ -66,6 +66,6 @@
66
66
  "@mikro-orm/core": "^6.1.12"
67
67
  },
68
68
  "peerDependencies": {
69
- "@mikro-orm/core": "6.1.13-dev.17"
69
+ "@mikro-orm/core": "6.1.13-dev.19"
70
70
  }
71
71
  }
@@ -652,8 +652,8 @@ class QueryBuilder {
652
652
  (0, core_1.helper)(entity).__serializationContext.populate ??= hint;
653
653
  hint.forEach(hint => {
654
654
  const [propName] = hint.field.split(':', 2);
655
- const value = entity[propName];
656
- if (core_1.Utils.isEntity(value, true)) {
655
+ const value = core_1.Reference.unwrapReference(entity[propName]);
656
+ if (core_1.Utils.isEntity(value)) {
657
657
  (0, core_1.helper)(value).populated();
658
658
  propagatePopulateHint(value, hint.children ?? []);
659
659
  }
@@ -954,15 +954,19 @@ class QueryBuilder {
954
954
  /* istanbul ignore next */
955
955
  const requiresSQLConversion = meta?.props.filter(p => p.hasConvertToJSValueSQL && p.persist !== false) ?? [];
956
956
  if (this.flags.has(core_1.QueryFlag.CONVERT_CUSTOM_TYPES) && (fields.includes('*') || fields.includes(`${this.mainAlias.aliasName}.*`)) && requiresSQLConversion.length > 0) {
957
- requiresSQLConversion.forEach(p => ret.push(this.helper.mapper(p.name, this.type)));
957
+ for (const p of requiresSQLConversion) {
958
+ ret.push(this.helper.mapper(p.name, this.type));
959
+ }
958
960
  }
959
- Object.keys(this._populateMap).forEach(f => {
960
- if (!fields.includes(f.replace(/#\w+$/, '')) && type === 'where') {
961
+ for (const f of Object.keys(this._populateMap)) {
962
+ if (type === 'where') {
961
963
  const cols = this.helper.mapJoinColumns(this.type ?? enums_1.QueryType.SELECT, this._joins[f]);
962
- ret.push(...cols);
964
+ for (const col of cols) {
965
+ ret.push(col);
966
+ }
963
967
  }
964
- });
965
- return ret;
968
+ }
969
+ return core_1.Utils.unique(ret);
966
970
  }
967
971
  init(type, data, cond) {
968
972
  this.ensureNotFinalized();
@@ -1204,8 +1208,7 @@ class QueryBuilder {
1204
1208
  // not perfect, but should work most of the time, ideally we should check only the alias (`... as alias`)
1205
1209
  return field.sql.includes(prop);
1206
1210
  }
1207
- // not perfect, but should work most of the time, ideally we should check only the alias (`... as alias`)
1208
- return field.toString().includes(prop);
1211
+ return false;
1209
1212
  });
1210
1213
  if (field instanceof core_1.RawQueryFragment) {
1211
1214
  knexQuery.select(this.platform.formatQuery(field.sql, field.params));
@@ -273,12 +273,19 @@ class SchemaComparator {
273
273
  */
274
274
  detectColumnRenamings(tableDifferences, inverseTableDiff) {
275
275
  const renameCandidates = {};
276
+ const oldFKs = Object.values(tableDifferences.fromTable.getForeignKeys());
277
+ const newFKs = Object.values(tableDifferences.toTable.getForeignKeys());
276
278
  for (const addedColumn of Object.values(tableDifferences.addedColumns)) {
277
279
  for (const removedColumn of Object.values(tableDifferences.removedColumns)) {
278
280
  const diff = this.diffColumn(addedColumn, removedColumn);
279
281
  if (diff.size !== 0) {
280
282
  continue;
281
283
  }
284
+ const wasFK = oldFKs.some(fk => fk.columnNames.includes(removedColumn.name));
285
+ const isFK = newFKs.some(fk => fk.columnNames.includes(addedColumn.name));
286
+ if (wasFK !== isFK) {
287
+ continue;
288
+ }
282
289
  const renamedColumn = inverseTableDiff?.renamedColumns[addedColumn.name];
283
290
  if (renamedColumn && renamedColumn?.name !== removedColumn.name) {
284
291
  continue;
@@ -27,6 +27,7 @@ export declare abstract class SchemaHelper {
27
27
  getCreateIndexSQL(tableName: string, index: IndexDef, partialExpression?: boolean): string;
28
28
  getDropIndexSQL(tableName: string, index: IndexDef): string;
29
29
  getRenameIndexSQL(tableName: string, index: IndexDef, oldIndexName: string): string;
30
+ getDropColumnsSQL(tableName: string, columns: Column[], schemaName?: string): string;
30
31
  hasNonDefaultPrimaryKeyName(table: DatabaseTable): boolean;
31
32
  createTableColumn(table: Knex.TableBuilder, column: Column, fromTable: DatabaseTable, changedProperties?: Set<string>, alter?: boolean): Knex.ColumnBuilder;
32
33
  configureColumn(column: Column, col: Knex.ColumnBuilder, knex: Knex, changedProperties?: Set<string>): Knex.ColumnBuilder;
@@ -99,6 +99,11 @@ class SchemaHelper {
99
99
  getRenameIndexSQL(tableName, index, oldIndexName) {
100
100
  return [this.getDropIndexSQL(tableName, { ...index, keyName: oldIndexName }), this.getCreateIndexSQL(tableName, index)].join(';\n');
101
101
  }
102
+ getDropColumnsSQL(tableName, columns, schemaName) {
103
+ const name = this.platform.quoteIdentifier((schemaName && schemaName !== this.platform.getDefaultSchemaName() ? schemaName + '.' : '') + tableName);
104
+ const drops = columns.map(column => `drop column ${this.platform.quoteIdentifier(column.name)}`).join(', ');
105
+ return `alter table ${name} ${drops}`;
106
+ }
102
107
  hasNonDefaultPrimaryKeyName(table) {
103
108
  const pkIndex = table.getPrimaryKey();
104
109
  if (!pkIndex || !this.platform.supportsCustomPrimaryKeyNames()) {
@@ -221,10 +226,11 @@ class SchemaHelper {
221
226
  return norm[0].replace('(?)', length != null ? `(${length})` : '');
222
227
  }
223
228
  getCreateDatabaseSQL(name) {
224
- return `create database ${name}`;
229
+ // two line breaks to force separate execution
230
+ return `create database ${name};\n\nuse ${name}`;
225
231
  }
226
232
  getDropDatabaseSQL(name) {
227
- return `drop database if exists ${name}`;
233
+ return `drop database if exists ${this.platform.quoteIdentifier(name)}`;
228
234
  }
229
235
  getDatabaseExistsSQL(name) {
230
236
  return `select 1 from information_schema.schemata where schema_name = '${name}'`;
@@ -1,4 +1,4 @@
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';
@@ -43,10 +43,11 @@ export declare class SqlSchemaGenerator extends AbstractSchemaGenerator<Abstract
43
43
  /**
44
44
  * creates new database and connects to it
45
45
  */
46
- createDatabase(name: string): Promise<void>;
46
+ createDatabase(name?: string): Promise<void>;
47
47
  dropDatabase(name?: string): Promise<void>;
48
48
  execute(sql: string, options?: {
49
49
  wrap?: boolean;
50
+ ctx?: Transaction;
50
51
  }): Promise<void>;
51
52
  private wrapSchema;
52
53
  private createSchemaBuilder;
@@ -118,7 +118,7 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
118
118
  // remove FKs explicitly if we can't use cascading statement and we don't disable FK checks (we need this for circular relations)
119
119
  for (const meta of metadata) {
120
120
  const table = schema.getTable(meta.tableName);
121
- if (!this.platform.usesCascadeStatement() && table && !wrap) {
121
+ if (!this.platform.usesCascadeStatement() && table && (!wrap || options.dropForeignKeys)) {
122
122
  for (const fk of Object.values(table.getForeignKeys())) {
123
123
  const builder = this.createSchemaBuilder(table.schema).alterTable(table.name, tbl => {
124
124
  tbl.dropForeign(fk.columnNames, fk.constraintName);
@@ -341,10 +341,8 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
341
341
  this.dropCheck(table, check);
342
342
  }
343
343
  /* istanbul ignore else */
344
- if (!safe) {
345
- for (const column of Object.values(diff.removedColumns)) {
346
- this.helper.pushTableQuery(table, `alter table ${this.platform.quoteIdentifier(tableName)} drop column ${this.platform.quoteIdentifier(column.name)}`);
347
- }
344
+ if (!safe && Object.values(diff.removedColumns).length > 0) {
345
+ this.helper.pushTableQuery(table, this.helper.getDropColumnsSQL(tableName, Object.values(diff.removedColumns), schemaName));
348
346
  }
349
347
  }));
350
348
  ret.push(this.createSchemaBuilder(schemaName).alterTable(tableName, table => {
@@ -421,9 +419,10 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
421
419
  * creates new database and connects to it
422
420
  */
423
421
  async createDatabase(name) {
422
+ name ??= this.config.get('dbName');
424
423
  const sql = this.helper.getCreateDatabaseSQL('' + this.knex.ref(name));
425
424
  if (sql) {
426
- await this.driver.execute(sql);
425
+ await this.execute(sql);
427
426
  }
428
427
  this.config.set('dbName', name);
429
428
  await this.driver.reconnect();
@@ -432,20 +431,34 @@ class SqlSchemaGenerator extends core_1.AbstractSchemaGenerator {
432
431
  name ??= this.config.get('dbName');
433
432
  this.config.set('dbName', this.helper.getManagementDbName());
434
433
  await this.driver.reconnect();
435
- await this.driver.execute(this.helper.getDropDatabaseSQL('' + this.knex.ref(name)));
434
+ await this.execute(this.helper.getDropDatabaseSQL(name));
436
435
  }
437
436
  async execute(sql, options = {}) {
438
437
  options.wrap ??= false;
439
- const lines = this.wrapSchema(sql, options).split('\n').filter(i => i.trim());
440
- if (lines.length === 0) {
438
+ const lines = this.wrapSchema(sql, options).split('\n');
439
+ const groups = [];
440
+ let i = 0;
441
+ for (const line of lines) {
442
+ if (line.trim() === '') {
443
+ if (groups[i]?.length > 0) {
444
+ i++;
445
+ }
446
+ continue;
447
+ }
448
+ groups[i] ??= [];
449
+ groups[i].push(line.trim());
450
+ }
451
+ if (groups.length === 0) {
441
452
  return;
442
453
  }
443
454
  if (this.platform.supportsMultipleStatements()) {
444
- const query = lines.join('\n');
445
- await this.driver.execute(query);
455
+ for (const group of groups) {
456
+ const query = group.join('\n');
457
+ await this.driver.execute(query);
458
+ }
446
459
  return;
447
460
  }
448
- await core_1.Utils.runSerial(lines, line => this.driver.execute(line));
461
+ await core_1.Utils.runSerial(groups.flat(), line => this.driver.execute(line));
449
462
  }
450
463
  wrapSchema(sql, options) {
451
464
  options.wrap ??= this.options.disableForeignKeys;