sqlmorpheus 0.1.10 → 0.2.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.
package/dist/index.d.mts CHANGED
@@ -22,14 +22,44 @@ interface AllowedMigrations {
22
22
  continueWithoutRollback?: boolean;
23
23
  }
24
24
 
25
+ interface RenameData {
26
+ oldName: string;
27
+ newName: string;
28
+ }
25
29
  interface MigrationInstructions {
26
- oldTableName?: string;
30
+ tableRenaming?: RenameData;
27
31
  recreate: boolean;
28
32
  /**
29
- * Stores changes to column (0: name in the database, last: current name in code)
33
+ * Stores changes to column. One entry per column.
34
+ * Each entry is an array (0: name in the database, last: current name in code)
30
35
  */
31
- renamedColumns: string[][];
36
+ renamedColumns: RenameData[];
32
37
  allowedMigrations: AllowedMigrations;
38
+ usedMigrations: Record<string, boolean>;
39
+ }
40
+
41
+ interface ColumnInfo {
42
+ name: string;
43
+ type: string;
44
+ defaultValue: string;
45
+ isPrimaryKey: boolean;
46
+ }
47
+
48
+ type ForeignKeyActions = "SET NULL" | "SET DEFAULT" | "RESTRICT" | "NO ACTION" | "CASCADE";
49
+ interface ForeignKeyInfo {
50
+ fromTable: string;
51
+ fromColumn: string;
52
+ toTable: string;
53
+ toColumn: string;
54
+ onUpdate?: ForeignKeyActions;
55
+ onDelete?: ForeignKeyActions;
56
+ }
57
+
58
+ interface TableStructure {
59
+ table: string;
60
+ primaryKey?: string;
61
+ columns: ColumnInfo[];
62
+ foreignKeys?: ForeignKeyInfo[];
33
63
  }
34
64
 
35
65
  declare class Migrations {
@@ -37,20 +67,24 @@ declare class Migrations {
37
67
  private alwaysAllowed;
38
68
  private fromVersion;
39
69
  private migrationData;
70
+ private migrationDataForOldTableNames;
40
71
  private notAllowedChanges;
41
72
  reset(dbInstructions: DatabaseInstructions, fromVersion: number): void;
42
73
  private getEntry;
43
74
  private getTableName;
44
- verifyMigration(tableName: string, type: keyof AllowedMigrations): void;
45
- checkIfAllowed(throwIfNotAllowed: boolean): boolean;
75
+ verifyRenamingTasks(newTables: Record<string, TableStructure>): Error | void;
76
+ verifyAllowedMigrations(): Error | void;
77
+ compareWithAllowedMigration(tableName: string, type: keyof AllowedMigrations): void;
46
78
  allowMigration(version: number, table: string | Class<BackendTable>, ...allowedMigrations: (keyof AllowedMigrations)[]): void;
47
- renameTable(version: number, oldTableName: string, newTable: string | Class<BackendTable>): void;
79
+ renameTable(version: number, oldTableName: string, newTableName: string | Class<BackendTable>): void;
48
80
  renameColumn(version: number, table: string | Class<BackendTable>, oldColumn: string, newColumn: string): void;
49
81
  recreateTableImp(table: Class<BackendTable> | string): void;
50
82
  recreateTable(version: number, table: Class<BackendTable> | string): void;
51
83
  getMigrationData(): Record<string, MigrationInstructions>;
52
84
  loopRenamedColumns(tableName: string, callback: (oldColumnName: string, newColumnName: string) => void): void;
53
- getUpdatedColumnName(tableName: string, oldColumnName: string): string;
85
+ getNewestTableName(tableName: string): string;
86
+ getOldTableName(tableName: string): string;
87
+ getNewestColumnName(tableName: string, oldColumnName: string): string;
54
88
  willBeRecreated(tableName: string): boolean;
55
89
  }
56
90
  type PublicMigrations = Pick<Migrations, "recreateTable" | "renameTable" | "renameColumn" | "allowMigration">;
@@ -60,16 +94,6 @@ interface SqlChanges {
60
94
  down: string;
61
95
  }
62
96
 
63
- type ForeignKeyActions = "SET NULL" | "SET DEFAULT" | "RESTRICT" | "NO ACTION" | "CASCADE";
64
- interface ForeignKeyInfo {
65
- fromTable: string;
66
- fromColumn: string;
67
- toTable: string;
68
- toColumn: string;
69
- onUpdate?: ForeignKeyActions;
70
- onDelete?: ForeignKeyActions;
71
- }
72
-
73
97
  interface TableInfo {
74
98
  primaryKey?: string;
75
99
  foreignKeys?: ForeignKeyInfo[];
package/dist/index.d.ts CHANGED
@@ -22,14 +22,44 @@ interface AllowedMigrations {
22
22
  continueWithoutRollback?: boolean;
23
23
  }
24
24
 
25
+ interface RenameData {
26
+ oldName: string;
27
+ newName: string;
28
+ }
25
29
  interface MigrationInstructions {
26
- oldTableName?: string;
30
+ tableRenaming?: RenameData;
27
31
  recreate: boolean;
28
32
  /**
29
- * Stores changes to column (0: name in the database, last: current name in code)
33
+ * Stores changes to column. One entry per column.
34
+ * Each entry is an array (0: name in the database, last: current name in code)
30
35
  */
31
- renamedColumns: string[][];
36
+ renamedColumns: RenameData[];
32
37
  allowedMigrations: AllowedMigrations;
38
+ usedMigrations: Record<string, boolean>;
39
+ }
40
+
41
+ interface ColumnInfo {
42
+ name: string;
43
+ type: string;
44
+ defaultValue: string;
45
+ isPrimaryKey: boolean;
46
+ }
47
+
48
+ type ForeignKeyActions = "SET NULL" | "SET DEFAULT" | "RESTRICT" | "NO ACTION" | "CASCADE";
49
+ interface ForeignKeyInfo {
50
+ fromTable: string;
51
+ fromColumn: string;
52
+ toTable: string;
53
+ toColumn: string;
54
+ onUpdate?: ForeignKeyActions;
55
+ onDelete?: ForeignKeyActions;
56
+ }
57
+
58
+ interface TableStructure {
59
+ table: string;
60
+ primaryKey?: string;
61
+ columns: ColumnInfo[];
62
+ foreignKeys?: ForeignKeyInfo[];
33
63
  }
34
64
 
35
65
  declare class Migrations {
@@ -37,20 +67,24 @@ declare class Migrations {
37
67
  private alwaysAllowed;
38
68
  private fromVersion;
39
69
  private migrationData;
70
+ private migrationDataForOldTableNames;
40
71
  private notAllowedChanges;
41
72
  reset(dbInstructions: DatabaseInstructions, fromVersion: number): void;
42
73
  private getEntry;
43
74
  private getTableName;
44
- verifyMigration(tableName: string, type: keyof AllowedMigrations): void;
45
- checkIfAllowed(throwIfNotAllowed: boolean): boolean;
75
+ verifyRenamingTasks(newTables: Record<string, TableStructure>): Error | void;
76
+ verifyAllowedMigrations(): Error | void;
77
+ compareWithAllowedMigration(tableName: string, type: keyof AllowedMigrations): void;
46
78
  allowMigration(version: number, table: string | Class<BackendTable>, ...allowedMigrations: (keyof AllowedMigrations)[]): void;
47
- renameTable(version: number, oldTableName: string, newTable: string | Class<BackendTable>): void;
79
+ renameTable(version: number, oldTableName: string, newTableName: string | Class<BackendTable>): void;
48
80
  renameColumn(version: number, table: string | Class<BackendTable>, oldColumn: string, newColumn: string): void;
49
81
  recreateTableImp(table: Class<BackendTable> | string): void;
50
82
  recreateTable(version: number, table: Class<BackendTable> | string): void;
51
83
  getMigrationData(): Record<string, MigrationInstructions>;
52
84
  loopRenamedColumns(tableName: string, callback: (oldColumnName: string, newColumnName: string) => void): void;
53
- getUpdatedColumnName(tableName: string, oldColumnName: string): string;
85
+ getNewestTableName(tableName: string): string;
86
+ getOldTableName(tableName: string): string;
87
+ getNewestColumnName(tableName: string, oldColumnName: string): string;
54
88
  willBeRecreated(tableName: string): boolean;
55
89
  }
56
90
  type PublicMigrations = Pick<Migrations, "recreateTable" | "renameTable" | "renameColumn" | "allowMigration">;
@@ -60,16 +94,6 @@ interface SqlChanges {
60
94
  down: string;
61
95
  }
62
96
 
63
- type ForeignKeyActions = "SET NULL" | "SET DEFAULT" | "RESTRICT" | "NO ACTION" | "CASCADE";
64
- interface ForeignKeyInfo {
65
- fromTable: string;
66
- fromColumn: string;
67
- toTable: string;
68
- toColumn: string;
69
- onUpdate?: ForeignKeyActions;
70
- onDelete?: ForeignKeyActions;
71
- }
72
-
73
97
  interface TableInfo {
74
98
  primaryKey?: string;
75
99
  foreignKeys?: ForeignKeyInfo[];
package/dist/index.js CHANGED
@@ -146,14 +146,12 @@ var TableStructureGenerator = class {
146
146
  // src/lib/exceptions/NotAllowedException.ts
147
147
  var NotAllowedException = class extends Error {
148
148
  constructor(entries) {
149
- let message = "Some destructive changes need to be confirmed. In preMigrations() run:";
149
+ let message = "Some destructive changes need to be confirmed.\n In preMigration() run:\n";
150
150
  for (const entry of entries) {
151
- message += `
152
- migrations.allowMigration(${entry.version}, "${entry.tableName}", "${entry.type}");`;
151
+ message += ` migrations.allowMigration(${entry.version}, "${entry.tableName}", "${entry.type}");
152
+ `;
153
153
  }
154
- super(`${message}
155
-
156
- `);
154
+ super(message);
157
155
  }
158
156
  };
159
157
 
@@ -163,6 +161,7 @@ var Migrations = class {
163
161
  alwaysAllowed = {};
164
162
  fromVersion = 0;
165
163
  migrationData = {};
164
+ migrationDataForOldTableNames = {};
166
165
  notAllowedChanges = [];
167
166
  reset(dbInstructions, fromVersion) {
168
167
  this.fromVersion = fromVersion;
@@ -177,7 +176,8 @@ var Migrations = class {
177
176
  this.migrationData[tableName] = {
178
177
  recreate: false,
179
178
  renamedColumns: [],
180
- allowedMigrations: {}
179
+ allowedMigrations: {},
180
+ usedMigrations: {}
181
181
  };
182
182
  }
183
183
  return this.migrationData[tableName];
@@ -185,20 +185,47 @@ var Migrations = class {
185
185
  getTableName(table) {
186
186
  return typeof table == "string" ? table : table.name;
187
187
  }
188
- verifyMigration(tableName, type) {
189
- if (!this.migrationData[tableName]?.allowedMigrations[type] && !this.alwaysAllowed[type])
190
- this.notAllowedChanges.push({ version: this.toVersion, tableName, type });
191
- }
192
- checkIfAllowed(throwIfNotAllowed) {
193
- if (!this.notAllowedChanges.length)
194
- return true;
195
- const exception = new NotAllowedException(this.notAllowedChanges);
196
- if (throwIfNotAllowed)
197
- throw exception;
198
- else {
199
- console.error(exception.message);
200
- return false;
188
+ verifyRenamingTasks(newTables) {
189
+ for (const tableName in this.migrationData) {
190
+ const migrationEntry = this.migrationData[tableName];
191
+ if (migrationEntry.tableRenaming?.oldName == tableName)
192
+ return new Error(`You set table "${tableName}" to be renamed to itself!`);
193
+ if (migrationEntry.tableRenaming && migrationEntry.tableRenaming.newName != tableName)
194
+ return new Error(`You set table "${tableName}" to be renamed to a different name than the one in your structure (${migrationEntry.tableRenaming.newName})!`);
195
+ else if (!newTables[tableName])
196
+ return new Error(`You set table "${migrationEntry.tableRenaming}" migrations for "${tableName}". But "${tableName}" does not exist in your structure.`);
197
+ for (const renamingData of migrationEntry.renamedColumns) {
198
+ const oldColumnName = renamingData.oldName;
199
+ const newColumnName = renamingData.newName;
200
+ if (oldColumnName == newColumnName)
201
+ return new Error(`You set column ${tableName}.${oldColumnName} to be renamed to itself!`);
202
+ else if (!newTables[tableName]?.columns.find((column) => column.name == newColumnName))
203
+ return new Error(`You set column ${tableName}.${oldColumnName} to be renamed to ${tableName}.${newColumnName}. But ${tableName}.${newColumnName} does not exist in your structure.`);
204
+ }
205
+ }
206
+ }
207
+ verifyAllowedMigrations() {
208
+ if (this.notAllowedChanges.length)
209
+ return new NotAllowedException(this.notAllowedChanges);
210
+ let errorMsg = "";
211
+ for (const tableName in this.migrationData) {
212
+ const migration = this.migrationData[tableName];
213
+ for (const type in migration.allowedMigrations) {
214
+ if (!migration.usedMigrations[type])
215
+ errorMsg += `Migration "${type}" for ${tableName} was allowed but not needed.
216
+ `;
217
+ }
201
218
  }
219
+ if (errorMsg)
220
+ return new Error(errorMsg);
221
+ }
222
+ compareWithAllowedMigration(tableName, type) {
223
+ const migrationEntry = this.migrationData[tableName];
224
+ if (!migrationEntry?.allowedMigrations[type]) {
225
+ if (!this.alwaysAllowed[type])
226
+ this.notAllowedChanges.push({ version: this.toVersion, tableName, type });
227
+ } else if (migrationEntry)
228
+ migrationEntry.usedMigrations[type] = true;
202
229
  }
203
230
  allowMigration(version, table, ...allowedMigrations) {
204
231
  if (version < this.fromVersion || version > this.toVersion)
@@ -208,23 +235,30 @@ var Migrations = class {
208
235
  entry.allowedMigrations[key] = true;
209
236
  }
210
237
  }
211
- renameTable(version, oldTableName, newTable) {
238
+ renameTable(version, oldTableName, newTableName) {
212
239
  if (version < this.fromVersion || version > this.toVersion)
213
240
  return;
214
- const entry = this.getEntry(newTable);
215
- entry.recreate = true;
216
- if (!entry.oldTableName)
217
- entry.oldTableName = oldTableName;
241
+ const newTableNameString = this.getTableName(newTableName);
242
+ if (this.migrationData.hasOwnProperty(oldTableName)) {
243
+ this.migrationData[newTableNameString] = this.getEntry(oldTableName);
244
+ delete this.migrationData[oldTableName];
245
+ }
246
+ const entry = this.getEntry(newTableName);
247
+ this.migrationDataForOldTableNames[oldTableName] = entry;
248
+ if (!entry.tableRenaming)
249
+ entry.tableRenaming = { oldName: oldTableName, newName: newTableNameString };
250
+ else
251
+ entry.tableRenaming.newName = newTableNameString;
218
252
  }
219
253
  renameColumn(version, table, oldColumn, newColumn) {
220
254
  if (version < this.fromVersion || version > this.toVersion)
221
255
  return;
222
256
  const entry = this.getEntry(table);
223
- const existingColumnEntry = entry.renamedColumns.find((entry2) => entry2[entry2.length - 1] == oldColumn);
257
+ const existingColumnEntry = entry.renamedColumns.find((entry2) => entry2.newName == oldColumn);
224
258
  if (existingColumnEntry)
225
- existingColumnEntry.push(newColumn);
259
+ existingColumnEntry.newName = newColumn;
226
260
  else
227
- entry.renamedColumns.push([oldColumn, newColumn]);
261
+ entry.renamedColumns.push({ oldName: oldColumn, newName: newColumn });
228
262
  }
229
263
  recreateTableImp(table) {
230
264
  const entry = this.getEntry(table);
@@ -240,17 +274,19 @@ var Migrations = class {
240
274
  }
241
275
  loopRenamedColumns(tableName, callback) {
242
276
  const migrationEntry = this.migrationData[tableName];
243
- for (const renamingArray of migrationEntry.renamedColumns) {
244
- if (renamingArray.length <= 1)
245
- continue;
246
- const oldColumnName = renamingArray[0];
247
- const newColumnName = renamingArray[renamingArray.length - 1];
248
- callback(oldColumnName, newColumnName);
277
+ for (const renamingData of migrationEntry.renamedColumns) {
278
+ callback(renamingData.oldName, renamingData.newName);
249
279
  }
250
280
  }
251
- getUpdatedColumnName(tableName, oldColumnName) {
252
- const columnNames = this.migrationData[tableName]?.renamedColumns.find((columns) => columns[0] == oldColumnName);
253
- return columnNames ? columnNames[columnNames.length - 1] : oldColumnName;
281
+ getNewestTableName(tableName) {
282
+ return this.migrationDataForOldTableNames[tableName]?.tableRenaming?.newName ?? tableName;
283
+ }
284
+ getOldTableName(tableName) {
285
+ return this.migrationData[tableName]?.tableRenaming?.oldName ?? tableName;
286
+ }
287
+ getNewestColumnName(tableName, oldColumnName) {
288
+ const columnNames = this.migrationData[tableName]?.renamedColumns.find((columns) => columns.oldName == oldColumnName);
289
+ return columnNames ? columnNames.newName : oldColumnName;
254
290
  }
255
291
  willBeRecreated(tableName) {
256
292
  return this.migrationData[tableName]?.recreate;
@@ -261,6 +297,10 @@ var Migrations = class {
261
297
  var MigrationManager = class {
262
298
  migrations = new Migrations();
263
299
  newTables = {};
300
+ /**
301
+ * Table names that currently exist in the database
302
+ * Note: If tables are set to be renamed, then names in this array will be corrected to their future name.
303
+ */
264
304
  existingTables = [];
265
305
  dialect;
266
306
  constructor(dialect) {
@@ -318,8 +358,9 @@ ${preSQL.down}`;
318
358
  changes.down += initialChanges.down;
319
359
  } else {
320
360
  Logger.log(`Creating migration SQL from version ${fromVersion} to ${toVersion}`);
321
- this.existingTables = await this.dialect.getTableNames();
361
+ this.existingTables = (await this.dialect.getTableNames()).map((oldTableName) => this.migrations.getNewestTableName(oldTableName));
322
362
  [
363
+ this.renameTables(),
323
364
  await this.createAndDropTables(),
324
365
  await this.migrateForeignKeys(),
325
366
  await this.migrateColumns(),
@@ -348,8 +389,18 @@ ${foreignKeyOnQuery}`;
348
389
  changes.down += `
349
390
 
350
391
  ${foreignKeyOnQuery}`;
351
- if (!this.migrations.checkIfAllowed(dbInstructions.throwIfNotAllowed)) {
352
- return null;
392
+ const exception = this.migrations.verifyRenamingTasks(this.newTables) ?? this.migrations.verifyAllowedMigrations();
393
+ if (exception) {
394
+ Logger.debug(`
395
+ Canceled changes:
396
+ ${changes.up}
397
+ `);
398
+ if (dbInstructions.throwIfNotAllowed)
399
+ throw exception;
400
+ else {
401
+ console.error(exception.message);
402
+ return null;
403
+ }
353
404
  }
354
405
  return {
355
406
  fromVersion,
@@ -357,6 +408,22 @@ ${foreignKeyOnQuery}`;
357
408
  changes
358
409
  };
359
410
  }
411
+ renameTables() {
412
+ const changes = {
413
+ up: "\n\n-- Rename tables\n",
414
+ down: "\n\n-- Rename tables\n"
415
+ };
416
+ const data = this.migrations.getMigrationData();
417
+ for (const tableName in data) {
418
+ const migrationEntry = data[tableName];
419
+ if (migrationEntry.tableRenaming) {
420
+ Logger.log(`Table "${migrationEntry.tableRenaming.oldName}" will be renamed to "${tableName}"!`);
421
+ changes.up += this.dialect.renameTable(migrationEntry.tableRenaming.oldName, tableName);
422
+ changes.down += this.dialect.renameTable(tableName, migrationEntry.tableRenaming.oldName);
423
+ }
424
+ }
425
+ return changes;
426
+ }
360
427
  /**
361
428
  * Generates SQL change statements for creating and dropping tables based on the current table structure
362
429
  * and existing table configurations in the database. The `up` changes include SQL statements for creating
@@ -368,8 +435,8 @@ ${foreignKeyOnQuery}`;
368
435
  */
369
436
  async createAndDropTables() {
370
437
  let changes = {
371
- up: "\n\n-- Create tables\n",
372
- down: "\n\n-- Create tables\n"
438
+ up: "\n\n-- Create and drop tables\n",
439
+ down: "\n\n-- Create and drop tables\n"
373
440
  };
374
441
  for (const tableName in this.newTables) {
375
442
  if (this.tableDoesNotExists(tableName)) {
@@ -382,12 +449,13 @@ ${foreignKeyOnQuery}`;
382
449
  }
383
450
  for (const tableName of this.existingTables) {
384
451
  if (!this.newTables[tableName]) {
385
- this.migrations.verifyMigration(tableName, "dropTable");
452
+ this.migrations.compareWithAllowedMigration(tableName, "dropTable");
386
453
  if (!this.dialect.canInspectForeignKeys || !this.dialect.canInspectPrimaryKey)
387
- this.migrations.verifyMigration(tableName, "continueWithoutRollback");
454
+ this.migrations.compareWithAllowedMigration(tableName, "continueWithoutRollback");
455
+ const dbTableName = this.migrations.getOldTableName(tableName);
388
456
  changes.up += `${this.dialect.dropTable(tableName)}
389
457
  `;
390
- changes.down += this.dialect.canInspectForeignKeys && this.dialect.canInspectPrimaryKey ? this.createTableSql(tableName, await this.dialect.getColumnInformation(tableName), await this.dialect.getForeignKeys(tableName)) : "\n\n-- Cannot recreate foreign keys or load primary keys with this database! Table will not be recreated!\n";
458
+ changes.down += this.dialect.canInspectForeignKeys && this.dialect.canInspectPrimaryKey ? this.createTableSql(tableName, await this.dialect.getColumnInformation(dbTableName), await this.dialect.getForeignKeys(dbTableName)) : "\n\n-- Cannot recreate foreign keys or load primary keys with this database! Table will not be recreated!\n";
391
459
  }
392
460
  }
393
461
  return changes;
@@ -438,10 +506,11 @@ ${foreignKeyOnQuery}`;
438
506
  const migrationEntry = migrationData[tableName];
439
507
  if (!migrationEntry.recreate)
440
508
  continue;
441
- this.migrations.verifyMigration(tableName, "recreateTable");
509
+ Logger.log(`Table ${tableName} will be recreated!`);
510
+ this.migrations.compareWithAllowedMigration(tableName, "recreateTable");
442
511
  if (!this.dialect.canInspectForeignKeys || !this.dialect.canInspectPrimaryKey)
443
- this.migrations.verifyMigration(tableName, "continueWithoutRollback");
444
- const oldColumnList = await this.dialect.getColumnInformation(tableName);
512
+ this.migrations.compareWithAllowedMigration(tableName, "continueWithoutRollback");
513
+ const oldColumnList = await this.dialect.getColumnInformation(this.migrations.getOldTableName(tableName));
445
514
  const newColumnList = this.newTables[tableName].columns;
446
515
  const moveableColumns = newColumnList.filter((entry) => oldColumnList.find((oldEntry) => oldEntry.name == entry.name) != void 0).map((entry) => entry.name);
447
516
  const backupTableName = `${tableName}__backup`;
@@ -451,8 +520,9 @@ ${foreignKeyOnQuery}`;
451
520
  );
452
521
  const moveDataQuery = insertQuery + "\n" + this.dialect.dropTable(tableName) + "\n" + this.dialect.renameTable(backupTableName, tableName);
453
522
  const structure = this.newTables[tableName];
454
- changes.up += this.createTableSql(backupTableName, structure.columns, structure.foreignKeys) + "\n" + moveDataQuery;
455
- changes.down += this.dialect.canInspectForeignKeys && this.dialect.canInspectPrimaryKey ? this.createTableSql(backupTableName, await this.dialect.getColumnInformation(tableName), await this.dialect.getForeignKeys(tableName)) + "\n" + moveDataQuery : "\n\n-- Cannot recreate foreign keys or load primary keys with this database! Table will not be recreated!\n";
523
+ changes.up += this.createTableSql(backupTableName, structure.columns, structure.foreignKeys) + "\n" + moveDataQuery + "\n";
524
+ const dbTableName = this.migrations.getOldTableName(tableName);
525
+ changes.down += this.dialect.canInspectForeignKeys && this.dialect.canInspectPrimaryKey ? this.createTableSql(backupTableName, await this.dialect.getColumnInformation(dbTableName), await this.dialect.getForeignKeys(dbTableName)) + "\n" + moveDataQuery : "\n\n-- Cannot recreate foreign keys or load primary keys with this database! Table will not be recreated!\n";
456
526
  }
457
527
  return changes;
458
528
  }
@@ -460,8 +530,6 @@ ${foreignKeyOnQuery}`;
460
530
  * Migrates foreign key constraints for all defined tables.
461
531
  */
462
532
  async migrateForeignKeys() {
463
- if (!this.dialect.canAlterForeignKeys)
464
- return { up: "", down: "" };
465
533
  let changes = {
466
534
  up: "\n\n-- Foreign keys\n",
467
535
  down: "\n\n-- Foreign keys\n"
@@ -471,13 +539,13 @@ ${foreignKeyOnQuery}`;
471
539
  continue;
472
540
  const structure = this.newTables[tableName];
473
541
  const newForeignKeys = structure.foreignKeys ?? [];
474
- const oldForeignKeys = await this.dialect.getForeignKeys(tableName);
542
+ const oldForeignKeys = await this.dialect.getForeignKeys(this.migrations.getOldTableName(tableName));
475
543
  let checkForNewForeignKeys = true;
476
544
  for (const oldForeignKey of oldForeignKeys) {
477
545
  const newForeignKey = newForeignKeys.find((entry) => entry.fromColumn == oldForeignKey.fromColumn);
478
546
  if (!newForeignKey) {
479
- Logger.log(`Foreign key ${oldForeignKey.toTable}.${oldForeignKey.toColumn} to ${oldForeignKey.toTable}.${oldForeignKey.toColumn} was removed!`);
480
- this.migrations.verifyMigration(tableName, "removeForeignKey");
547
+ Logger.log(`Foreign key ${oldForeignKey.fromTable}.${oldForeignKey.fromColumn} to ${oldForeignKey.toTable}.${oldForeignKey.toColumn} will be removed!`);
548
+ this.migrations.compareWithAllowedMigration(tableName, "removeForeignKey");
481
549
  if (this.dialect.canAlterForeignKeys) {
482
550
  changes.up += this.dialect.removeForeignKey(oldForeignKey.fromTable, oldForeignKey.fromColumn);
483
551
  changes.down += this.dialect.addForeignKey(
@@ -490,8 +558,8 @@ ${foreignKeyOnQuery}`;
490
558
  }
491
559
  } else {
492
560
  if (!newForeignKey || oldForeignKey.toColumn != newForeignKey.toColumn || (oldForeignKey.onUpdate ?? "NO ACTION") != (newForeignKey.onUpdate ?? "NO ACTION") || (oldForeignKey.onDelete ?? "NO ACTION") != (newForeignKey.onDelete ?? "NO ACTION")) {
493
- Logger.log(`Foreign key ${oldForeignKey.toTable}.${oldForeignKey.toColumn} to ${oldForeignKey.toTable}.${oldForeignKey.toColumn} was changed!`);
494
- this.migrations.verifyMigration(tableName, "alterForeignKey");
561
+ Logger.log(`Foreign key ${oldForeignKey.fromTable}.${oldForeignKey.fromColumn} to ${oldForeignKey.toTable}.${oldForeignKey.toColumn} will be changed!`);
562
+ this.migrations.compareWithAllowedMigration(tableName, "alterForeignKey");
495
563
  if (this.dialect.canAlterForeignKeys) {
496
564
  changes.up += this.dialect.removeForeignKey(oldForeignKey.fromTable, oldForeignKey.fromColumn) + this.dialect.addForeignKey(
497
565
  newForeignKey.fromTable,
@@ -513,7 +581,7 @@ ${foreignKeyOnQuery}`;
513
581
  const oldForeignKey = oldForeignKeys.find((entry) => entry.fromColumn == newForeignKey.fromColumn);
514
582
  if (oldForeignKey)
515
583
  continue;
516
- Logger.log(`Foreign key ${newForeignKey.toTable}.${newForeignKey.toColumn} to ${newForeignKey.toTable}.${newForeignKey.toColumn} is new!`);
584
+ Logger.log(`Foreign key ${newForeignKey.fromTable}.${newForeignKey.fromColumn} to ${newForeignKey.toTable}.${newForeignKey.toColumn} will be added!`);
517
585
  if (this.dialect.canAlterForeignKeys) {
518
586
  changes.up += this.dialect.addForeignKey(
519
587
  newForeignKey.toTable,
@@ -542,13 +610,13 @@ ${foreignKeyOnQuery}`;
542
610
  if (this.migrations.willBeRecreated(tableName) || this.tableDoesNotExists(tableName))
543
611
  continue;
544
612
  const newTableDefinition = this.newTables[tableName];
545
- const oldColumnList = await this.dialect.getColumnInformation(tableName);
613
+ const oldColumnList = await this.dialect.getColumnInformation(this.migrations.getOldTableName(tableName));
546
614
  const oldPrimaryKey = this.dialect.canInspectPrimaryKey ? this.getPrimaryKeyColumn(oldColumnList) : false;
547
615
  const newColumnList = newTableDefinition.columns;
548
616
  const newPrimaryKey = newTableDefinition.primaryKey;
549
617
  if (this.dialect.canInspectPrimaryKey && oldPrimaryKey != newPrimaryKey) {
550
- Logger.log(`Primary key in ${tableName} was changed from ${oldPrimaryKey} to ${newPrimaryKey}!`);
551
- this.migrations.verifyMigration(tableName, "alterPrimaryKey");
618
+ Logger.log(`Primary key in ${tableName} will be changed from ${oldPrimaryKey} to ${newPrimaryKey}!`);
619
+ this.migrations.compareWithAllowedMigration(tableName, "alterPrimaryKey");
552
620
  if (this.dialect.canAlterPrimaryKey) {
553
621
  if (oldPrimaryKey) {
554
622
  changes.up += this.dialect.removePrimaryKey(tableName, oldPrimaryKey);
@@ -564,7 +632,7 @@ ${foreignKeyOnQuery}`;
564
632
  }
565
633
  for (const newColumn of newColumnList) {
566
634
  const oldColumn = oldColumnList.find(
567
- (entry) => this.migrations.getUpdatedColumnName(tableName, entry.name) == newColumn.name
635
+ (entry) => this.migrations.getNewestColumnName(tableName, entry.name) == newColumn.name
568
636
  );
569
637
  if (oldColumn == void 0) {
570
638
  changes.up += this.dialect.createColumn(tableName, this.dialect.columnDefinition(newColumn.name, newColumn.type, newColumn.defaultValue, newColumn.isPrimaryKey)) + "\n";
@@ -575,10 +643,10 @@ ${foreignKeyOnQuery}`;
575
643
  }
576
644
  for (const oldColumn of oldColumnList) {
577
645
  const newColumn = newColumnList.find(
578
- (entry) => entry.name == this.migrations.getUpdatedColumnName(tableName, oldColumn.name)
646
+ (entry) => entry.name == this.migrations.getNewestColumnName(tableName, oldColumn.name)
579
647
  );
580
648
  if (newColumn == void 0) {
581
- this.migrations.verifyMigration(tableName, "dropColumn");
649
+ this.migrations.compareWithAllowedMigration(tableName, "dropColumn");
582
650
  changes.up += this.dialect.dropColumn(tableName, oldColumn.name) + "\n";
583
651
  changes.down += this.dialect.createColumn(tableName, this.dialect.columnDefinition(oldColumn.name, oldColumn.type, oldColumn.defaultValue, oldColumn.isPrimaryKey)) + "\n";
584
652
  }
@@ -612,6 +680,7 @@ ${foreignKeyOnQuery}`;
612
680
  if (migrationData[tableName].recreate)
613
681
  continue;
614
682
  this.migrations.loopRenamedColumns(tableName, (oldColumnName, newColumnName) => {
683
+ Logger.log(`Column ${tableName}.${oldColumnName} will be renamed to ${tableName}.${newColumnName}!`);
615
684
  changes.up += this.dialect.renameColumn(tableName, oldColumnName, newColumnName);
616
685
  changes.down += this.dialect.renameColumn(tableName, newColumnName, oldColumnName);
617
686
  });
package/dist/index.mjs CHANGED
@@ -114,14 +114,12 @@ var TableStructureGenerator = class {
114
114
  // src/lib/exceptions/NotAllowedException.ts
115
115
  var NotAllowedException = class extends Error {
116
116
  constructor(entries) {
117
- let message = "Some destructive changes need to be confirmed. In preMigrations() run:";
117
+ let message = "Some destructive changes need to be confirmed.\n In preMigration() run:\n";
118
118
  for (const entry of entries) {
119
- message += `
120
- migrations.allowMigration(${entry.version}, "${entry.tableName}", "${entry.type}");`;
119
+ message += ` migrations.allowMigration(${entry.version}, "${entry.tableName}", "${entry.type}");
120
+ `;
121
121
  }
122
- super(`${message}
123
-
124
- `);
122
+ super(message);
125
123
  }
126
124
  };
127
125
 
@@ -131,6 +129,7 @@ var Migrations = class {
131
129
  alwaysAllowed = {};
132
130
  fromVersion = 0;
133
131
  migrationData = {};
132
+ migrationDataForOldTableNames = {};
134
133
  notAllowedChanges = [];
135
134
  reset(dbInstructions, fromVersion) {
136
135
  this.fromVersion = fromVersion;
@@ -145,7 +144,8 @@ var Migrations = class {
145
144
  this.migrationData[tableName] = {
146
145
  recreate: false,
147
146
  renamedColumns: [],
148
- allowedMigrations: {}
147
+ allowedMigrations: {},
148
+ usedMigrations: {}
149
149
  };
150
150
  }
151
151
  return this.migrationData[tableName];
@@ -153,20 +153,47 @@ var Migrations = class {
153
153
  getTableName(table) {
154
154
  return typeof table == "string" ? table : table.name;
155
155
  }
156
- verifyMigration(tableName, type) {
157
- if (!this.migrationData[tableName]?.allowedMigrations[type] && !this.alwaysAllowed[type])
158
- this.notAllowedChanges.push({ version: this.toVersion, tableName, type });
159
- }
160
- checkIfAllowed(throwIfNotAllowed) {
161
- if (!this.notAllowedChanges.length)
162
- return true;
163
- const exception = new NotAllowedException(this.notAllowedChanges);
164
- if (throwIfNotAllowed)
165
- throw exception;
166
- else {
167
- console.error(exception.message);
168
- return false;
156
+ verifyRenamingTasks(newTables) {
157
+ for (const tableName in this.migrationData) {
158
+ const migrationEntry = this.migrationData[tableName];
159
+ if (migrationEntry.tableRenaming?.oldName == tableName)
160
+ return new Error(`You set table "${tableName}" to be renamed to itself!`);
161
+ if (migrationEntry.tableRenaming && migrationEntry.tableRenaming.newName != tableName)
162
+ return new Error(`You set table "${tableName}" to be renamed to a different name than the one in your structure (${migrationEntry.tableRenaming.newName})!`);
163
+ else if (!newTables[tableName])
164
+ return new Error(`You set table "${migrationEntry.tableRenaming}" migrations for "${tableName}". But "${tableName}" does not exist in your structure.`);
165
+ for (const renamingData of migrationEntry.renamedColumns) {
166
+ const oldColumnName = renamingData.oldName;
167
+ const newColumnName = renamingData.newName;
168
+ if (oldColumnName == newColumnName)
169
+ return new Error(`You set column ${tableName}.${oldColumnName} to be renamed to itself!`);
170
+ else if (!newTables[tableName]?.columns.find((column) => column.name == newColumnName))
171
+ return new Error(`You set column ${tableName}.${oldColumnName} to be renamed to ${tableName}.${newColumnName}. But ${tableName}.${newColumnName} does not exist in your structure.`);
172
+ }
173
+ }
174
+ }
175
+ verifyAllowedMigrations() {
176
+ if (this.notAllowedChanges.length)
177
+ return new NotAllowedException(this.notAllowedChanges);
178
+ let errorMsg = "";
179
+ for (const tableName in this.migrationData) {
180
+ const migration = this.migrationData[tableName];
181
+ for (const type in migration.allowedMigrations) {
182
+ if (!migration.usedMigrations[type])
183
+ errorMsg += `Migration "${type}" for ${tableName} was allowed but not needed.
184
+ `;
185
+ }
169
186
  }
187
+ if (errorMsg)
188
+ return new Error(errorMsg);
189
+ }
190
+ compareWithAllowedMigration(tableName, type) {
191
+ const migrationEntry = this.migrationData[tableName];
192
+ if (!migrationEntry?.allowedMigrations[type]) {
193
+ if (!this.alwaysAllowed[type])
194
+ this.notAllowedChanges.push({ version: this.toVersion, tableName, type });
195
+ } else if (migrationEntry)
196
+ migrationEntry.usedMigrations[type] = true;
170
197
  }
171
198
  allowMigration(version, table, ...allowedMigrations) {
172
199
  if (version < this.fromVersion || version > this.toVersion)
@@ -176,23 +203,30 @@ var Migrations = class {
176
203
  entry.allowedMigrations[key] = true;
177
204
  }
178
205
  }
179
- renameTable(version, oldTableName, newTable) {
206
+ renameTable(version, oldTableName, newTableName) {
180
207
  if (version < this.fromVersion || version > this.toVersion)
181
208
  return;
182
- const entry = this.getEntry(newTable);
183
- entry.recreate = true;
184
- if (!entry.oldTableName)
185
- entry.oldTableName = oldTableName;
209
+ const newTableNameString = this.getTableName(newTableName);
210
+ if (this.migrationData.hasOwnProperty(oldTableName)) {
211
+ this.migrationData[newTableNameString] = this.getEntry(oldTableName);
212
+ delete this.migrationData[oldTableName];
213
+ }
214
+ const entry = this.getEntry(newTableName);
215
+ this.migrationDataForOldTableNames[oldTableName] = entry;
216
+ if (!entry.tableRenaming)
217
+ entry.tableRenaming = { oldName: oldTableName, newName: newTableNameString };
218
+ else
219
+ entry.tableRenaming.newName = newTableNameString;
186
220
  }
187
221
  renameColumn(version, table, oldColumn, newColumn) {
188
222
  if (version < this.fromVersion || version > this.toVersion)
189
223
  return;
190
224
  const entry = this.getEntry(table);
191
- const existingColumnEntry = entry.renamedColumns.find((entry2) => entry2[entry2.length - 1] == oldColumn);
225
+ const existingColumnEntry = entry.renamedColumns.find((entry2) => entry2.newName == oldColumn);
192
226
  if (existingColumnEntry)
193
- existingColumnEntry.push(newColumn);
227
+ existingColumnEntry.newName = newColumn;
194
228
  else
195
- entry.renamedColumns.push([oldColumn, newColumn]);
229
+ entry.renamedColumns.push({ oldName: oldColumn, newName: newColumn });
196
230
  }
197
231
  recreateTableImp(table) {
198
232
  const entry = this.getEntry(table);
@@ -208,17 +242,19 @@ var Migrations = class {
208
242
  }
209
243
  loopRenamedColumns(tableName, callback) {
210
244
  const migrationEntry = this.migrationData[tableName];
211
- for (const renamingArray of migrationEntry.renamedColumns) {
212
- if (renamingArray.length <= 1)
213
- continue;
214
- const oldColumnName = renamingArray[0];
215
- const newColumnName = renamingArray[renamingArray.length - 1];
216
- callback(oldColumnName, newColumnName);
245
+ for (const renamingData of migrationEntry.renamedColumns) {
246
+ callback(renamingData.oldName, renamingData.newName);
217
247
  }
218
248
  }
219
- getUpdatedColumnName(tableName, oldColumnName) {
220
- const columnNames = this.migrationData[tableName]?.renamedColumns.find((columns) => columns[0] == oldColumnName);
221
- return columnNames ? columnNames[columnNames.length - 1] : oldColumnName;
249
+ getNewestTableName(tableName) {
250
+ return this.migrationDataForOldTableNames[tableName]?.tableRenaming?.newName ?? tableName;
251
+ }
252
+ getOldTableName(tableName) {
253
+ return this.migrationData[tableName]?.tableRenaming?.oldName ?? tableName;
254
+ }
255
+ getNewestColumnName(tableName, oldColumnName) {
256
+ const columnNames = this.migrationData[tableName]?.renamedColumns.find((columns) => columns.oldName == oldColumnName);
257
+ return columnNames ? columnNames.newName : oldColumnName;
222
258
  }
223
259
  willBeRecreated(tableName) {
224
260
  return this.migrationData[tableName]?.recreate;
@@ -229,6 +265,10 @@ var Migrations = class {
229
265
  var MigrationManager = class {
230
266
  migrations = new Migrations();
231
267
  newTables = {};
268
+ /**
269
+ * Table names that currently exist in the database
270
+ * Note: If tables are set to be renamed, then names in this array will be corrected to their future name.
271
+ */
232
272
  existingTables = [];
233
273
  dialect;
234
274
  constructor(dialect) {
@@ -286,8 +326,9 @@ ${preSQL.down}`;
286
326
  changes.down += initialChanges.down;
287
327
  } else {
288
328
  Logger.log(`Creating migration SQL from version ${fromVersion} to ${toVersion}`);
289
- this.existingTables = await this.dialect.getTableNames();
329
+ this.existingTables = (await this.dialect.getTableNames()).map((oldTableName) => this.migrations.getNewestTableName(oldTableName));
290
330
  [
331
+ this.renameTables(),
291
332
  await this.createAndDropTables(),
292
333
  await this.migrateForeignKeys(),
293
334
  await this.migrateColumns(),
@@ -316,8 +357,18 @@ ${foreignKeyOnQuery}`;
316
357
  changes.down += `
317
358
 
318
359
  ${foreignKeyOnQuery}`;
319
- if (!this.migrations.checkIfAllowed(dbInstructions.throwIfNotAllowed)) {
320
- return null;
360
+ const exception = this.migrations.verifyRenamingTasks(this.newTables) ?? this.migrations.verifyAllowedMigrations();
361
+ if (exception) {
362
+ Logger.debug(`
363
+ Canceled changes:
364
+ ${changes.up}
365
+ `);
366
+ if (dbInstructions.throwIfNotAllowed)
367
+ throw exception;
368
+ else {
369
+ console.error(exception.message);
370
+ return null;
371
+ }
321
372
  }
322
373
  return {
323
374
  fromVersion,
@@ -325,6 +376,22 @@ ${foreignKeyOnQuery}`;
325
376
  changes
326
377
  };
327
378
  }
379
+ renameTables() {
380
+ const changes = {
381
+ up: "\n\n-- Rename tables\n",
382
+ down: "\n\n-- Rename tables\n"
383
+ };
384
+ const data = this.migrations.getMigrationData();
385
+ for (const tableName in data) {
386
+ const migrationEntry = data[tableName];
387
+ if (migrationEntry.tableRenaming) {
388
+ Logger.log(`Table "${migrationEntry.tableRenaming.oldName}" will be renamed to "${tableName}"!`);
389
+ changes.up += this.dialect.renameTable(migrationEntry.tableRenaming.oldName, tableName);
390
+ changes.down += this.dialect.renameTable(tableName, migrationEntry.tableRenaming.oldName);
391
+ }
392
+ }
393
+ return changes;
394
+ }
328
395
  /**
329
396
  * Generates SQL change statements for creating and dropping tables based on the current table structure
330
397
  * and existing table configurations in the database. The `up` changes include SQL statements for creating
@@ -336,8 +403,8 @@ ${foreignKeyOnQuery}`;
336
403
  */
337
404
  async createAndDropTables() {
338
405
  let changes = {
339
- up: "\n\n-- Create tables\n",
340
- down: "\n\n-- Create tables\n"
406
+ up: "\n\n-- Create and drop tables\n",
407
+ down: "\n\n-- Create and drop tables\n"
341
408
  };
342
409
  for (const tableName in this.newTables) {
343
410
  if (this.tableDoesNotExists(tableName)) {
@@ -350,12 +417,13 @@ ${foreignKeyOnQuery}`;
350
417
  }
351
418
  for (const tableName of this.existingTables) {
352
419
  if (!this.newTables[tableName]) {
353
- this.migrations.verifyMigration(tableName, "dropTable");
420
+ this.migrations.compareWithAllowedMigration(tableName, "dropTable");
354
421
  if (!this.dialect.canInspectForeignKeys || !this.dialect.canInspectPrimaryKey)
355
- this.migrations.verifyMigration(tableName, "continueWithoutRollback");
422
+ this.migrations.compareWithAllowedMigration(tableName, "continueWithoutRollback");
423
+ const dbTableName = this.migrations.getOldTableName(tableName);
356
424
  changes.up += `${this.dialect.dropTable(tableName)}
357
425
  `;
358
- changes.down += this.dialect.canInspectForeignKeys && this.dialect.canInspectPrimaryKey ? this.createTableSql(tableName, await this.dialect.getColumnInformation(tableName), await this.dialect.getForeignKeys(tableName)) : "\n\n-- Cannot recreate foreign keys or load primary keys with this database! Table will not be recreated!\n";
426
+ changes.down += this.dialect.canInspectForeignKeys && this.dialect.canInspectPrimaryKey ? this.createTableSql(tableName, await this.dialect.getColumnInformation(dbTableName), await this.dialect.getForeignKeys(dbTableName)) : "\n\n-- Cannot recreate foreign keys or load primary keys with this database! Table will not be recreated!\n";
359
427
  }
360
428
  }
361
429
  return changes;
@@ -406,10 +474,11 @@ ${foreignKeyOnQuery}`;
406
474
  const migrationEntry = migrationData[tableName];
407
475
  if (!migrationEntry.recreate)
408
476
  continue;
409
- this.migrations.verifyMigration(tableName, "recreateTable");
477
+ Logger.log(`Table ${tableName} will be recreated!`);
478
+ this.migrations.compareWithAllowedMigration(tableName, "recreateTable");
410
479
  if (!this.dialect.canInspectForeignKeys || !this.dialect.canInspectPrimaryKey)
411
- this.migrations.verifyMigration(tableName, "continueWithoutRollback");
412
- const oldColumnList = await this.dialect.getColumnInformation(tableName);
480
+ this.migrations.compareWithAllowedMigration(tableName, "continueWithoutRollback");
481
+ const oldColumnList = await this.dialect.getColumnInformation(this.migrations.getOldTableName(tableName));
413
482
  const newColumnList = this.newTables[tableName].columns;
414
483
  const moveableColumns = newColumnList.filter((entry) => oldColumnList.find((oldEntry) => oldEntry.name == entry.name) != void 0).map((entry) => entry.name);
415
484
  const backupTableName = `${tableName}__backup`;
@@ -419,8 +488,9 @@ ${foreignKeyOnQuery}`;
419
488
  );
420
489
  const moveDataQuery = insertQuery + "\n" + this.dialect.dropTable(tableName) + "\n" + this.dialect.renameTable(backupTableName, tableName);
421
490
  const structure = this.newTables[tableName];
422
- changes.up += this.createTableSql(backupTableName, structure.columns, structure.foreignKeys) + "\n" + moveDataQuery;
423
- changes.down += this.dialect.canInspectForeignKeys && this.dialect.canInspectPrimaryKey ? this.createTableSql(backupTableName, await this.dialect.getColumnInformation(tableName), await this.dialect.getForeignKeys(tableName)) + "\n" + moveDataQuery : "\n\n-- Cannot recreate foreign keys or load primary keys with this database! Table will not be recreated!\n";
491
+ changes.up += this.createTableSql(backupTableName, structure.columns, structure.foreignKeys) + "\n" + moveDataQuery + "\n";
492
+ const dbTableName = this.migrations.getOldTableName(tableName);
493
+ changes.down += this.dialect.canInspectForeignKeys && this.dialect.canInspectPrimaryKey ? this.createTableSql(backupTableName, await this.dialect.getColumnInformation(dbTableName), await this.dialect.getForeignKeys(dbTableName)) + "\n" + moveDataQuery : "\n\n-- Cannot recreate foreign keys or load primary keys with this database! Table will not be recreated!\n";
424
494
  }
425
495
  return changes;
426
496
  }
@@ -428,8 +498,6 @@ ${foreignKeyOnQuery}`;
428
498
  * Migrates foreign key constraints for all defined tables.
429
499
  */
430
500
  async migrateForeignKeys() {
431
- if (!this.dialect.canAlterForeignKeys)
432
- return { up: "", down: "" };
433
501
  let changes = {
434
502
  up: "\n\n-- Foreign keys\n",
435
503
  down: "\n\n-- Foreign keys\n"
@@ -439,13 +507,13 @@ ${foreignKeyOnQuery}`;
439
507
  continue;
440
508
  const structure = this.newTables[tableName];
441
509
  const newForeignKeys = structure.foreignKeys ?? [];
442
- const oldForeignKeys = await this.dialect.getForeignKeys(tableName);
510
+ const oldForeignKeys = await this.dialect.getForeignKeys(this.migrations.getOldTableName(tableName));
443
511
  let checkForNewForeignKeys = true;
444
512
  for (const oldForeignKey of oldForeignKeys) {
445
513
  const newForeignKey = newForeignKeys.find((entry) => entry.fromColumn == oldForeignKey.fromColumn);
446
514
  if (!newForeignKey) {
447
- Logger.log(`Foreign key ${oldForeignKey.toTable}.${oldForeignKey.toColumn} to ${oldForeignKey.toTable}.${oldForeignKey.toColumn} was removed!`);
448
- this.migrations.verifyMigration(tableName, "removeForeignKey");
515
+ Logger.log(`Foreign key ${oldForeignKey.fromTable}.${oldForeignKey.fromColumn} to ${oldForeignKey.toTable}.${oldForeignKey.toColumn} will be removed!`);
516
+ this.migrations.compareWithAllowedMigration(tableName, "removeForeignKey");
449
517
  if (this.dialect.canAlterForeignKeys) {
450
518
  changes.up += this.dialect.removeForeignKey(oldForeignKey.fromTable, oldForeignKey.fromColumn);
451
519
  changes.down += this.dialect.addForeignKey(
@@ -458,8 +526,8 @@ ${foreignKeyOnQuery}`;
458
526
  }
459
527
  } else {
460
528
  if (!newForeignKey || oldForeignKey.toColumn != newForeignKey.toColumn || (oldForeignKey.onUpdate ?? "NO ACTION") != (newForeignKey.onUpdate ?? "NO ACTION") || (oldForeignKey.onDelete ?? "NO ACTION") != (newForeignKey.onDelete ?? "NO ACTION")) {
461
- Logger.log(`Foreign key ${oldForeignKey.toTable}.${oldForeignKey.toColumn} to ${oldForeignKey.toTable}.${oldForeignKey.toColumn} was changed!`);
462
- this.migrations.verifyMigration(tableName, "alterForeignKey");
529
+ Logger.log(`Foreign key ${oldForeignKey.fromTable}.${oldForeignKey.fromColumn} to ${oldForeignKey.toTable}.${oldForeignKey.toColumn} will be changed!`);
530
+ this.migrations.compareWithAllowedMigration(tableName, "alterForeignKey");
463
531
  if (this.dialect.canAlterForeignKeys) {
464
532
  changes.up += this.dialect.removeForeignKey(oldForeignKey.fromTable, oldForeignKey.fromColumn) + this.dialect.addForeignKey(
465
533
  newForeignKey.fromTable,
@@ -481,7 +549,7 @@ ${foreignKeyOnQuery}`;
481
549
  const oldForeignKey = oldForeignKeys.find((entry) => entry.fromColumn == newForeignKey.fromColumn);
482
550
  if (oldForeignKey)
483
551
  continue;
484
- Logger.log(`Foreign key ${newForeignKey.toTable}.${newForeignKey.toColumn} to ${newForeignKey.toTable}.${newForeignKey.toColumn} is new!`);
552
+ Logger.log(`Foreign key ${newForeignKey.fromTable}.${newForeignKey.fromColumn} to ${newForeignKey.toTable}.${newForeignKey.toColumn} will be added!`);
485
553
  if (this.dialect.canAlterForeignKeys) {
486
554
  changes.up += this.dialect.addForeignKey(
487
555
  newForeignKey.toTable,
@@ -510,13 +578,13 @@ ${foreignKeyOnQuery}`;
510
578
  if (this.migrations.willBeRecreated(tableName) || this.tableDoesNotExists(tableName))
511
579
  continue;
512
580
  const newTableDefinition = this.newTables[tableName];
513
- const oldColumnList = await this.dialect.getColumnInformation(tableName);
581
+ const oldColumnList = await this.dialect.getColumnInformation(this.migrations.getOldTableName(tableName));
514
582
  const oldPrimaryKey = this.dialect.canInspectPrimaryKey ? this.getPrimaryKeyColumn(oldColumnList) : false;
515
583
  const newColumnList = newTableDefinition.columns;
516
584
  const newPrimaryKey = newTableDefinition.primaryKey;
517
585
  if (this.dialect.canInspectPrimaryKey && oldPrimaryKey != newPrimaryKey) {
518
- Logger.log(`Primary key in ${tableName} was changed from ${oldPrimaryKey} to ${newPrimaryKey}!`);
519
- this.migrations.verifyMigration(tableName, "alterPrimaryKey");
586
+ Logger.log(`Primary key in ${tableName} will be changed from ${oldPrimaryKey} to ${newPrimaryKey}!`);
587
+ this.migrations.compareWithAllowedMigration(tableName, "alterPrimaryKey");
520
588
  if (this.dialect.canAlterPrimaryKey) {
521
589
  if (oldPrimaryKey) {
522
590
  changes.up += this.dialect.removePrimaryKey(tableName, oldPrimaryKey);
@@ -532,7 +600,7 @@ ${foreignKeyOnQuery}`;
532
600
  }
533
601
  for (const newColumn of newColumnList) {
534
602
  const oldColumn = oldColumnList.find(
535
- (entry) => this.migrations.getUpdatedColumnName(tableName, entry.name) == newColumn.name
603
+ (entry) => this.migrations.getNewestColumnName(tableName, entry.name) == newColumn.name
536
604
  );
537
605
  if (oldColumn == void 0) {
538
606
  changes.up += this.dialect.createColumn(tableName, this.dialect.columnDefinition(newColumn.name, newColumn.type, newColumn.defaultValue, newColumn.isPrimaryKey)) + "\n";
@@ -543,10 +611,10 @@ ${foreignKeyOnQuery}`;
543
611
  }
544
612
  for (const oldColumn of oldColumnList) {
545
613
  const newColumn = newColumnList.find(
546
- (entry) => entry.name == this.migrations.getUpdatedColumnName(tableName, oldColumn.name)
614
+ (entry) => entry.name == this.migrations.getNewestColumnName(tableName, oldColumn.name)
547
615
  );
548
616
  if (newColumn == void 0) {
549
- this.migrations.verifyMigration(tableName, "dropColumn");
617
+ this.migrations.compareWithAllowedMigration(tableName, "dropColumn");
550
618
  changes.up += this.dialect.dropColumn(tableName, oldColumn.name) + "\n";
551
619
  changes.down += this.dialect.createColumn(tableName, this.dialect.columnDefinition(oldColumn.name, oldColumn.type, oldColumn.defaultValue, oldColumn.isPrimaryKey)) + "\n";
552
620
  }
@@ -580,6 +648,7 @@ ${foreignKeyOnQuery}`;
580
648
  if (migrationData[tableName].recreate)
581
649
  continue;
582
650
  this.migrations.loopRenamedColumns(tableName, (oldColumnName, newColumnName) => {
651
+ Logger.log(`Column ${tableName}.${oldColumnName} will be renamed to ${tableName}.${newColumnName}!`);
583
652
  changes.up += this.dialect.renameColumn(tableName, oldColumnName, newColumnName);
584
653
  changes.down += this.dialect.renameColumn(tableName, newColumnName, oldColumnName);
585
654
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sqlmorpheus",
3
- "version": "0.1.10",
3
+ "version": "0.2.0",
4
4
  "author": "JodliDev",
5
5
  "keywords": [],
6
6
  "license": "MIT",