sqlmorpheus 0.1.9 → 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
@@ -1,5 +1,5 @@
1
1
  interface DatabaseAccess {
2
- createBackup?(name: string): Promise<void>;
2
+ createBackup?(backupName: string): Promise<void>;
3
3
  runGetStatement(query: string): Promise<unknown>;
4
4
  runMultipleWriteStatements(query: string): Promise<void>;
5
5
  }
@@ -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
@@ -1,5 +1,5 @@
1
1
  interface DatabaseAccess {
2
- createBackup?(name: string): Promise<void>;
2
+ createBackup?(backupName: string): Promise<void>;
3
3
  runGetStatement(query: string): Promise<unknown>;
4
4
  runMultipleWriteStatements(query: string): Promise<void>;
5
5
  }
@@ -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,10 +146,10 @@ 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
154
  super(message);
155
155
  }
@@ -161,6 +161,7 @@ var Migrations = class {
161
161
  alwaysAllowed = {};
162
162
  fromVersion = 0;
163
163
  migrationData = {};
164
+ migrationDataForOldTableNames = {};
164
165
  notAllowedChanges = [];
165
166
  reset(dbInstructions, fromVersion) {
166
167
  this.fromVersion = fromVersion;
@@ -175,7 +176,8 @@ var Migrations = class {
175
176
  this.migrationData[tableName] = {
176
177
  recreate: false,
177
178
  renamedColumns: [],
178
- allowedMigrations: {}
179
+ allowedMigrations: {},
180
+ usedMigrations: {}
179
181
  };
180
182
  }
181
183
  return this.migrationData[tableName];
@@ -183,18 +185,47 @@ var Migrations = class {
183
185
  getTableName(table) {
184
186
  return typeof table == "string" ? table : table.name;
185
187
  }
186
- verifyMigration(tableName, type) {
187
- if (!this.migrationData[tableName]?.allowedMigrations[type] && !this.alwaysAllowed[type])
188
- this.notAllowedChanges.push({ version: this.toVersion, tableName, type });
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
+ }
189
206
  }
190
- checkIfAllowed(throwIfNotAllowed) {
191
- const exception = new NotAllowedException(this.notAllowedChanges);
192
- if (throwIfNotAllowed)
193
- throw exception;
194
- else {
195
- console.error(exception.message);
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
+ }
196
218
  }
197
- return !this.notAllowedChanges.length;
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;
198
229
  }
199
230
  allowMigration(version, table, ...allowedMigrations) {
200
231
  if (version < this.fromVersion || version > this.toVersion)
@@ -204,23 +235,30 @@ var Migrations = class {
204
235
  entry.allowedMigrations[key] = true;
205
236
  }
206
237
  }
207
- renameTable(version, oldTableName, newTable) {
238
+ renameTable(version, oldTableName, newTableName) {
208
239
  if (version < this.fromVersion || version > this.toVersion)
209
240
  return;
210
- const entry = this.getEntry(newTable);
211
- entry.recreate = true;
212
- if (!entry.oldTableName)
213
- 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;
214
252
  }
215
253
  renameColumn(version, table, oldColumn, newColumn) {
216
254
  if (version < this.fromVersion || version > this.toVersion)
217
255
  return;
218
256
  const entry = this.getEntry(table);
219
- const existingColumnEntry = entry.renamedColumns.find((entry2) => entry2[entry2.length - 1] == oldColumn);
257
+ const existingColumnEntry = entry.renamedColumns.find((entry2) => entry2.newName == oldColumn);
220
258
  if (existingColumnEntry)
221
- existingColumnEntry.push(newColumn);
259
+ existingColumnEntry.newName = newColumn;
222
260
  else
223
- entry.renamedColumns.push([oldColumn, newColumn]);
261
+ entry.renamedColumns.push({ oldName: oldColumn, newName: newColumn });
224
262
  }
225
263
  recreateTableImp(table) {
226
264
  const entry = this.getEntry(table);
@@ -236,17 +274,19 @@ var Migrations = class {
236
274
  }
237
275
  loopRenamedColumns(tableName, callback) {
238
276
  const migrationEntry = this.migrationData[tableName];
239
- for (const renamingArray of migrationEntry.renamedColumns) {
240
- if (renamingArray.length <= 1)
241
- continue;
242
- const oldColumnName = renamingArray[0];
243
- const newColumnName = renamingArray[renamingArray.length - 1];
244
- callback(oldColumnName, newColumnName);
277
+ for (const renamingData of migrationEntry.renamedColumns) {
278
+ callback(renamingData.oldName, renamingData.newName);
245
279
  }
246
280
  }
247
- getUpdatedColumnName(tableName, oldColumnName) {
248
- const columnNames = this.migrationData[tableName]?.renamedColumns.find((columns) => columns[0] == oldColumnName);
249
- 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;
250
290
  }
251
291
  willBeRecreated(tableName) {
252
292
  return this.migrationData[tableName]?.recreate;
@@ -257,6 +297,10 @@ var Migrations = class {
257
297
  var MigrationManager = class {
258
298
  migrations = new Migrations();
259
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
+ */
260
304
  existingTables = [];
261
305
  dialect;
262
306
  constructor(dialect) {
@@ -314,8 +358,9 @@ ${preSQL.down}`;
314
358
  changes.down += initialChanges.down;
315
359
  } else {
316
360
  Logger.log(`Creating migration SQL from version ${fromVersion} to ${toVersion}`);
317
- this.existingTables = await this.dialect.getTableNames();
361
+ this.existingTables = (await this.dialect.getTableNames()).map((oldTableName) => this.migrations.getNewestTableName(oldTableName));
318
362
  [
363
+ this.renameTables(),
319
364
  await this.createAndDropTables(),
320
365
  await this.migrateForeignKeys(),
321
366
  await this.migrateColumns(),
@@ -344,8 +389,18 @@ ${foreignKeyOnQuery}`;
344
389
  changes.down += `
345
390
 
346
391
  ${foreignKeyOnQuery}`;
347
- if (!this.migrations.checkIfAllowed(dbInstructions.throwIfNotAllowed)) {
348
- 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
+ }
349
404
  }
350
405
  return {
351
406
  fromVersion,
@@ -353,6 +408,22 @@ ${foreignKeyOnQuery}`;
353
408
  changes
354
409
  };
355
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
+ }
356
427
  /**
357
428
  * Generates SQL change statements for creating and dropping tables based on the current table structure
358
429
  * and existing table configurations in the database. The `up` changes include SQL statements for creating
@@ -364,8 +435,8 @@ ${foreignKeyOnQuery}`;
364
435
  */
365
436
  async createAndDropTables() {
366
437
  let changes = {
367
- up: "\n\n-- Create tables\n",
368
- down: "\n\n-- Create tables\n"
438
+ up: "\n\n-- Create and drop tables\n",
439
+ down: "\n\n-- Create and drop tables\n"
369
440
  };
370
441
  for (const tableName in this.newTables) {
371
442
  if (this.tableDoesNotExists(tableName)) {
@@ -378,12 +449,13 @@ ${foreignKeyOnQuery}`;
378
449
  }
379
450
  for (const tableName of this.existingTables) {
380
451
  if (!this.newTables[tableName]) {
381
- this.migrations.verifyMigration(tableName, "dropTable");
452
+ this.migrations.compareWithAllowedMigration(tableName, "dropTable");
382
453
  if (!this.dialect.canInspectForeignKeys || !this.dialect.canInspectPrimaryKey)
383
- this.migrations.verifyMigration(tableName, "continueWithoutRollback");
454
+ this.migrations.compareWithAllowedMigration(tableName, "continueWithoutRollback");
455
+ const dbTableName = this.migrations.getOldTableName(tableName);
384
456
  changes.up += `${this.dialect.dropTable(tableName)}
385
457
  `;
386
- 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";
387
459
  }
388
460
  }
389
461
  return changes;
@@ -434,10 +506,11 @@ ${foreignKeyOnQuery}`;
434
506
  const migrationEntry = migrationData[tableName];
435
507
  if (!migrationEntry.recreate)
436
508
  continue;
437
- this.migrations.verifyMigration(tableName, "recreateTable");
509
+ Logger.log(`Table ${tableName} will be recreated!`);
510
+ this.migrations.compareWithAllowedMigration(tableName, "recreateTable");
438
511
  if (!this.dialect.canInspectForeignKeys || !this.dialect.canInspectPrimaryKey)
439
- this.migrations.verifyMigration(tableName, "continueWithoutRollback");
440
- const oldColumnList = await this.dialect.getColumnInformation(tableName);
512
+ this.migrations.compareWithAllowedMigration(tableName, "continueWithoutRollback");
513
+ const oldColumnList = await this.dialect.getColumnInformation(this.migrations.getOldTableName(tableName));
441
514
  const newColumnList = this.newTables[tableName].columns;
442
515
  const moveableColumns = newColumnList.filter((entry) => oldColumnList.find((oldEntry) => oldEntry.name == entry.name) != void 0).map((entry) => entry.name);
443
516
  const backupTableName = `${tableName}__backup`;
@@ -447,8 +520,9 @@ ${foreignKeyOnQuery}`;
447
520
  );
448
521
  const moveDataQuery = insertQuery + "\n" + this.dialect.dropTable(tableName) + "\n" + this.dialect.renameTable(backupTableName, tableName);
449
522
  const structure = this.newTables[tableName];
450
- changes.up += this.createTableSql(backupTableName, structure.columns, structure.foreignKeys) + "\n" + moveDataQuery;
451
- 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";
452
526
  }
453
527
  return changes;
454
528
  }
@@ -456,8 +530,6 @@ ${foreignKeyOnQuery}`;
456
530
  * Migrates foreign key constraints for all defined tables.
457
531
  */
458
532
  async migrateForeignKeys() {
459
- if (!this.dialect.canAlterForeignKeys)
460
- return { up: "", down: "" };
461
533
  let changes = {
462
534
  up: "\n\n-- Foreign keys\n",
463
535
  down: "\n\n-- Foreign keys\n"
@@ -467,13 +539,13 @@ ${foreignKeyOnQuery}`;
467
539
  continue;
468
540
  const structure = this.newTables[tableName];
469
541
  const newForeignKeys = structure.foreignKeys ?? [];
470
- const oldForeignKeys = await this.dialect.getForeignKeys(tableName);
542
+ const oldForeignKeys = await this.dialect.getForeignKeys(this.migrations.getOldTableName(tableName));
471
543
  let checkForNewForeignKeys = true;
472
544
  for (const oldForeignKey of oldForeignKeys) {
473
545
  const newForeignKey = newForeignKeys.find((entry) => entry.fromColumn == oldForeignKey.fromColumn);
474
546
  if (!newForeignKey) {
475
- Logger.log(`Foreign key ${oldForeignKey.toTable}.${oldForeignKey.toColumn} to ${oldForeignKey.toTable}.${oldForeignKey.toColumn} was removed!`);
476
- 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");
477
549
  if (this.dialect.canAlterForeignKeys) {
478
550
  changes.up += this.dialect.removeForeignKey(oldForeignKey.fromTable, oldForeignKey.fromColumn);
479
551
  changes.down += this.dialect.addForeignKey(
@@ -486,8 +558,8 @@ ${foreignKeyOnQuery}`;
486
558
  }
487
559
  } else {
488
560
  if (!newForeignKey || oldForeignKey.toColumn != newForeignKey.toColumn || (oldForeignKey.onUpdate ?? "NO ACTION") != (newForeignKey.onUpdate ?? "NO ACTION") || (oldForeignKey.onDelete ?? "NO ACTION") != (newForeignKey.onDelete ?? "NO ACTION")) {
489
- Logger.log(`Foreign key ${oldForeignKey.toTable}.${oldForeignKey.toColumn} to ${oldForeignKey.toTable}.${oldForeignKey.toColumn} was changed!`);
490
- 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");
491
563
  if (this.dialect.canAlterForeignKeys) {
492
564
  changes.up += this.dialect.removeForeignKey(oldForeignKey.fromTable, oldForeignKey.fromColumn) + this.dialect.addForeignKey(
493
565
  newForeignKey.fromTable,
@@ -509,7 +581,7 @@ ${foreignKeyOnQuery}`;
509
581
  const oldForeignKey = oldForeignKeys.find((entry) => entry.fromColumn == newForeignKey.fromColumn);
510
582
  if (oldForeignKey)
511
583
  continue;
512
- 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!`);
513
585
  if (this.dialect.canAlterForeignKeys) {
514
586
  changes.up += this.dialect.addForeignKey(
515
587
  newForeignKey.toTable,
@@ -538,13 +610,13 @@ ${foreignKeyOnQuery}`;
538
610
  if (this.migrations.willBeRecreated(tableName) || this.tableDoesNotExists(tableName))
539
611
  continue;
540
612
  const newTableDefinition = this.newTables[tableName];
541
- const oldColumnList = await this.dialect.getColumnInformation(tableName);
613
+ const oldColumnList = await this.dialect.getColumnInformation(this.migrations.getOldTableName(tableName));
542
614
  const oldPrimaryKey = this.dialect.canInspectPrimaryKey ? this.getPrimaryKeyColumn(oldColumnList) : false;
543
615
  const newColumnList = newTableDefinition.columns;
544
616
  const newPrimaryKey = newTableDefinition.primaryKey;
545
617
  if (this.dialect.canInspectPrimaryKey && oldPrimaryKey != newPrimaryKey) {
546
- Logger.log(`Primary key in ${tableName} was changed from ${oldPrimaryKey} to ${newPrimaryKey}!`);
547
- 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");
548
620
  if (this.dialect.canAlterPrimaryKey) {
549
621
  if (oldPrimaryKey) {
550
622
  changes.up += this.dialect.removePrimaryKey(tableName, oldPrimaryKey);
@@ -560,7 +632,7 @@ ${foreignKeyOnQuery}`;
560
632
  }
561
633
  for (const newColumn of newColumnList) {
562
634
  const oldColumn = oldColumnList.find(
563
- (entry) => this.migrations.getUpdatedColumnName(tableName, entry.name) == newColumn.name
635
+ (entry) => this.migrations.getNewestColumnName(tableName, entry.name) == newColumn.name
564
636
  );
565
637
  if (oldColumn == void 0) {
566
638
  changes.up += this.dialect.createColumn(tableName, this.dialect.columnDefinition(newColumn.name, newColumn.type, newColumn.defaultValue, newColumn.isPrimaryKey)) + "\n";
@@ -571,10 +643,10 @@ ${foreignKeyOnQuery}`;
571
643
  }
572
644
  for (const oldColumn of oldColumnList) {
573
645
  const newColumn = newColumnList.find(
574
- (entry) => entry.name == this.migrations.getUpdatedColumnName(tableName, oldColumn.name)
646
+ (entry) => entry.name == this.migrations.getNewestColumnName(tableName, oldColumn.name)
575
647
  );
576
648
  if (newColumn == void 0) {
577
- this.migrations.verifyMigration(tableName, "dropColumn");
649
+ this.migrations.compareWithAllowedMigration(tableName, "dropColumn");
578
650
  changes.up += this.dialect.dropColumn(tableName, oldColumn.name) + "\n";
579
651
  changes.down += this.dialect.createColumn(tableName, this.dialect.columnDefinition(oldColumn.name, oldColumn.type, oldColumn.defaultValue, oldColumn.isPrimaryKey)) + "\n";
580
652
  }
@@ -608,6 +680,7 @@ ${foreignKeyOnQuery}`;
608
680
  if (migrationData[tableName].recreate)
609
681
  continue;
610
682
  this.migrations.loopRenamedColumns(tableName, (oldColumnName, newColumnName) => {
683
+ Logger.log(`Column ${tableName}.${oldColumnName} will be renamed to ${tableName}.${newColumnName}!`);
611
684
  changes.up += this.dialect.renameColumn(tableName, oldColumnName, newColumnName);
612
685
  changes.down += this.dialect.renameColumn(tableName, newColumnName, oldColumnName);
613
686
  });
package/dist/index.mjs CHANGED
@@ -114,10 +114,10 @@ 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
122
  super(message);
123
123
  }
@@ -129,6 +129,7 @@ var Migrations = class {
129
129
  alwaysAllowed = {};
130
130
  fromVersion = 0;
131
131
  migrationData = {};
132
+ migrationDataForOldTableNames = {};
132
133
  notAllowedChanges = [];
133
134
  reset(dbInstructions, fromVersion) {
134
135
  this.fromVersion = fromVersion;
@@ -143,7 +144,8 @@ var Migrations = class {
143
144
  this.migrationData[tableName] = {
144
145
  recreate: false,
145
146
  renamedColumns: [],
146
- allowedMigrations: {}
147
+ allowedMigrations: {},
148
+ usedMigrations: {}
147
149
  };
148
150
  }
149
151
  return this.migrationData[tableName];
@@ -151,18 +153,47 @@ var Migrations = class {
151
153
  getTableName(table) {
152
154
  return typeof table == "string" ? table : table.name;
153
155
  }
154
- verifyMigration(tableName, type) {
155
- if (!this.migrationData[tableName]?.allowedMigrations[type] && !this.alwaysAllowed[type])
156
- this.notAllowedChanges.push({ version: this.toVersion, tableName, type });
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
+ }
157
174
  }
158
- checkIfAllowed(throwIfNotAllowed) {
159
- const exception = new NotAllowedException(this.notAllowedChanges);
160
- if (throwIfNotAllowed)
161
- throw exception;
162
- else {
163
- console.error(exception.message);
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
+ }
164
186
  }
165
- return !this.notAllowedChanges.length;
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;
166
197
  }
167
198
  allowMigration(version, table, ...allowedMigrations) {
168
199
  if (version < this.fromVersion || version > this.toVersion)
@@ -172,23 +203,30 @@ var Migrations = class {
172
203
  entry.allowedMigrations[key] = true;
173
204
  }
174
205
  }
175
- renameTable(version, oldTableName, newTable) {
206
+ renameTable(version, oldTableName, newTableName) {
176
207
  if (version < this.fromVersion || version > this.toVersion)
177
208
  return;
178
- const entry = this.getEntry(newTable);
179
- entry.recreate = true;
180
- if (!entry.oldTableName)
181
- 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;
182
220
  }
183
221
  renameColumn(version, table, oldColumn, newColumn) {
184
222
  if (version < this.fromVersion || version > this.toVersion)
185
223
  return;
186
224
  const entry = this.getEntry(table);
187
- const existingColumnEntry = entry.renamedColumns.find((entry2) => entry2[entry2.length - 1] == oldColumn);
225
+ const existingColumnEntry = entry.renamedColumns.find((entry2) => entry2.newName == oldColumn);
188
226
  if (existingColumnEntry)
189
- existingColumnEntry.push(newColumn);
227
+ existingColumnEntry.newName = newColumn;
190
228
  else
191
- entry.renamedColumns.push([oldColumn, newColumn]);
229
+ entry.renamedColumns.push({ oldName: oldColumn, newName: newColumn });
192
230
  }
193
231
  recreateTableImp(table) {
194
232
  const entry = this.getEntry(table);
@@ -204,17 +242,19 @@ var Migrations = class {
204
242
  }
205
243
  loopRenamedColumns(tableName, callback) {
206
244
  const migrationEntry = this.migrationData[tableName];
207
- for (const renamingArray of migrationEntry.renamedColumns) {
208
- if (renamingArray.length <= 1)
209
- continue;
210
- const oldColumnName = renamingArray[0];
211
- const newColumnName = renamingArray[renamingArray.length - 1];
212
- callback(oldColumnName, newColumnName);
245
+ for (const renamingData of migrationEntry.renamedColumns) {
246
+ callback(renamingData.oldName, renamingData.newName);
213
247
  }
214
248
  }
215
- getUpdatedColumnName(tableName, oldColumnName) {
216
- const columnNames = this.migrationData[tableName]?.renamedColumns.find((columns) => columns[0] == oldColumnName);
217
- 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;
218
258
  }
219
259
  willBeRecreated(tableName) {
220
260
  return this.migrationData[tableName]?.recreate;
@@ -225,6 +265,10 @@ var Migrations = class {
225
265
  var MigrationManager = class {
226
266
  migrations = new Migrations();
227
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
+ */
228
272
  existingTables = [];
229
273
  dialect;
230
274
  constructor(dialect) {
@@ -282,8 +326,9 @@ ${preSQL.down}`;
282
326
  changes.down += initialChanges.down;
283
327
  } else {
284
328
  Logger.log(`Creating migration SQL from version ${fromVersion} to ${toVersion}`);
285
- this.existingTables = await this.dialect.getTableNames();
329
+ this.existingTables = (await this.dialect.getTableNames()).map((oldTableName) => this.migrations.getNewestTableName(oldTableName));
286
330
  [
331
+ this.renameTables(),
287
332
  await this.createAndDropTables(),
288
333
  await this.migrateForeignKeys(),
289
334
  await this.migrateColumns(),
@@ -312,8 +357,18 @@ ${foreignKeyOnQuery}`;
312
357
  changes.down += `
313
358
 
314
359
  ${foreignKeyOnQuery}`;
315
- if (!this.migrations.checkIfAllowed(dbInstructions.throwIfNotAllowed)) {
316
- 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
+ }
317
372
  }
318
373
  return {
319
374
  fromVersion,
@@ -321,6 +376,22 @@ ${foreignKeyOnQuery}`;
321
376
  changes
322
377
  };
323
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
+ }
324
395
  /**
325
396
  * Generates SQL change statements for creating and dropping tables based on the current table structure
326
397
  * and existing table configurations in the database. The `up` changes include SQL statements for creating
@@ -332,8 +403,8 @@ ${foreignKeyOnQuery}`;
332
403
  */
333
404
  async createAndDropTables() {
334
405
  let changes = {
335
- up: "\n\n-- Create tables\n",
336
- down: "\n\n-- Create tables\n"
406
+ up: "\n\n-- Create and drop tables\n",
407
+ down: "\n\n-- Create and drop tables\n"
337
408
  };
338
409
  for (const tableName in this.newTables) {
339
410
  if (this.tableDoesNotExists(tableName)) {
@@ -346,12 +417,13 @@ ${foreignKeyOnQuery}`;
346
417
  }
347
418
  for (const tableName of this.existingTables) {
348
419
  if (!this.newTables[tableName]) {
349
- this.migrations.verifyMigration(tableName, "dropTable");
420
+ this.migrations.compareWithAllowedMigration(tableName, "dropTable");
350
421
  if (!this.dialect.canInspectForeignKeys || !this.dialect.canInspectPrimaryKey)
351
- this.migrations.verifyMigration(tableName, "continueWithoutRollback");
422
+ this.migrations.compareWithAllowedMigration(tableName, "continueWithoutRollback");
423
+ const dbTableName = this.migrations.getOldTableName(tableName);
352
424
  changes.up += `${this.dialect.dropTable(tableName)}
353
425
  `;
354
- 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";
355
427
  }
356
428
  }
357
429
  return changes;
@@ -402,10 +474,11 @@ ${foreignKeyOnQuery}`;
402
474
  const migrationEntry = migrationData[tableName];
403
475
  if (!migrationEntry.recreate)
404
476
  continue;
405
- this.migrations.verifyMigration(tableName, "recreateTable");
477
+ Logger.log(`Table ${tableName} will be recreated!`);
478
+ this.migrations.compareWithAllowedMigration(tableName, "recreateTable");
406
479
  if (!this.dialect.canInspectForeignKeys || !this.dialect.canInspectPrimaryKey)
407
- this.migrations.verifyMigration(tableName, "continueWithoutRollback");
408
- const oldColumnList = await this.dialect.getColumnInformation(tableName);
480
+ this.migrations.compareWithAllowedMigration(tableName, "continueWithoutRollback");
481
+ const oldColumnList = await this.dialect.getColumnInformation(this.migrations.getOldTableName(tableName));
409
482
  const newColumnList = this.newTables[tableName].columns;
410
483
  const moveableColumns = newColumnList.filter((entry) => oldColumnList.find((oldEntry) => oldEntry.name == entry.name) != void 0).map((entry) => entry.name);
411
484
  const backupTableName = `${tableName}__backup`;
@@ -415,8 +488,9 @@ ${foreignKeyOnQuery}`;
415
488
  );
416
489
  const moveDataQuery = insertQuery + "\n" + this.dialect.dropTable(tableName) + "\n" + this.dialect.renameTable(backupTableName, tableName);
417
490
  const structure = this.newTables[tableName];
418
- changes.up += this.createTableSql(backupTableName, structure.columns, structure.foreignKeys) + "\n" + moveDataQuery;
419
- 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";
420
494
  }
421
495
  return changes;
422
496
  }
@@ -424,8 +498,6 @@ ${foreignKeyOnQuery}`;
424
498
  * Migrates foreign key constraints for all defined tables.
425
499
  */
426
500
  async migrateForeignKeys() {
427
- if (!this.dialect.canAlterForeignKeys)
428
- return { up: "", down: "" };
429
501
  let changes = {
430
502
  up: "\n\n-- Foreign keys\n",
431
503
  down: "\n\n-- Foreign keys\n"
@@ -435,13 +507,13 @@ ${foreignKeyOnQuery}`;
435
507
  continue;
436
508
  const structure = this.newTables[tableName];
437
509
  const newForeignKeys = structure.foreignKeys ?? [];
438
- const oldForeignKeys = await this.dialect.getForeignKeys(tableName);
510
+ const oldForeignKeys = await this.dialect.getForeignKeys(this.migrations.getOldTableName(tableName));
439
511
  let checkForNewForeignKeys = true;
440
512
  for (const oldForeignKey of oldForeignKeys) {
441
513
  const newForeignKey = newForeignKeys.find((entry) => entry.fromColumn == oldForeignKey.fromColumn);
442
514
  if (!newForeignKey) {
443
- Logger.log(`Foreign key ${oldForeignKey.toTable}.${oldForeignKey.toColumn} to ${oldForeignKey.toTable}.${oldForeignKey.toColumn} was removed!`);
444
- 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");
445
517
  if (this.dialect.canAlterForeignKeys) {
446
518
  changes.up += this.dialect.removeForeignKey(oldForeignKey.fromTable, oldForeignKey.fromColumn);
447
519
  changes.down += this.dialect.addForeignKey(
@@ -454,8 +526,8 @@ ${foreignKeyOnQuery}`;
454
526
  }
455
527
  } else {
456
528
  if (!newForeignKey || oldForeignKey.toColumn != newForeignKey.toColumn || (oldForeignKey.onUpdate ?? "NO ACTION") != (newForeignKey.onUpdate ?? "NO ACTION") || (oldForeignKey.onDelete ?? "NO ACTION") != (newForeignKey.onDelete ?? "NO ACTION")) {
457
- Logger.log(`Foreign key ${oldForeignKey.toTable}.${oldForeignKey.toColumn} to ${oldForeignKey.toTable}.${oldForeignKey.toColumn} was changed!`);
458
- 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");
459
531
  if (this.dialect.canAlterForeignKeys) {
460
532
  changes.up += this.dialect.removeForeignKey(oldForeignKey.fromTable, oldForeignKey.fromColumn) + this.dialect.addForeignKey(
461
533
  newForeignKey.fromTable,
@@ -477,7 +549,7 @@ ${foreignKeyOnQuery}`;
477
549
  const oldForeignKey = oldForeignKeys.find((entry) => entry.fromColumn == newForeignKey.fromColumn);
478
550
  if (oldForeignKey)
479
551
  continue;
480
- 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!`);
481
553
  if (this.dialect.canAlterForeignKeys) {
482
554
  changes.up += this.dialect.addForeignKey(
483
555
  newForeignKey.toTable,
@@ -506,13 +578,13 @@ ${foreignKeyOnQuery}`;
506
578
  if (this.migrations.willBeRecreated(tableName) || this.tableDoesNotExists(tableName))
507
579
  continue;
508
580
  const newTableDefinition = this.newTables[tableName];
509
- const oldColumnList = await this.dialect.getColumnInformation(tableName);
581
+ const oldColumnList = await this.dialect.getColumnInformation(this.migrations.getOldTableName(tableName));
510
582
  const oldPrimaryKey = this.dialect.canInspectPrimaryKey ? this.getPrimaryKeyColumn(oldColumnList) : false;
511
583
  const newColumnList = newTableDefinition.columns;
512
584
  const newPrimaryKey = newTableDefinition.primaryKey;
513
585
  if (this.dialect.canInspectPrimaryKey && oldPrimaryKey != newPrimaryKey) {
514
- Logger.log(`Primary key in ${tableName} was changed from ${oldPrimaryKey} to ${newPrimaryKey}!`);
515
- 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");
516
588
  if (this.dialect.canAlterPrimaryKey) {
517
589
  if (oldPrimaryKey) {
518
590
  changes.up += this.dialect.removePrimaryKey(tableName, oldPrimaryKey);
@@ -528,7 +600,7 @@ ${foreignKeyOnQuery}`;
528
600
  }
529
601
  for (const newColumn of newColumnList) {
530
602
  const oldColumn = oldColumnList.find(
531
- (entry) => this.migrations.getUpdatedColumnName(tableName, entry.name) == newColumn.name
603
+ (entry) => this.migrations.getNewestColumnName(tableName, entry.name) == newColumn.name
532
604
  );
533
605
  if (oldColumn == void 0) {
534
606
  changes.up += this.dialect.createColumn(tableName, this.dialect.columnDefinition(newColumn.name, newColumn.type, newColumn.defaultValue, newColumn.isPrimaryKey)) + "\n";
@@ -539,10 +611,10 @@ ${foreignKeyOnQuery}`;
539
611
  }
540
612
  for (const oldColumn of oldColumnList) {
541
613
  const newColumn = newColumnList.find(
542
- (entry) => entry.name == this.migrations.getUpdatedColumnName(tableName, oldColumn.name)
614
+ (entry) => entry.name == this.migrations.getNewestColumnName(tableName, oldColumn.name)
543
615
  );
544
616
  if (newColumn == void 0) {
545
- this.migrations.verifyMigration(tableName, "dropColumn");
617
+ this.migrations.compareWithAllowedMigration(tableName, "dropColumn");
546
618
  changes.up += this.dialect.dropColumn(tableName, oldColumn.name) + "\n";
547
619
  changes.down += this.dialect.createColumn(tableName, this.dialect.columnDefinition(oldColumn.name, oldColumn.type, oldColumn.defaultValue, oldColumn.isPrimaryKey)) + "\n";
548
620
  }
@@ -576,6 +648,7 @@ ${foreignKeyOnQuery}`;
576
648
  if (migrationData[tableName].recreate)
577
649
  continue;
578
650
  this.migrations.loopRenamedColumns(tableName, (oldColumnName, newColumnName) => {
651
+ Logger.log(`Column ${tableName}.${oldColumnName} will be renamed to ${tableName}.${newColumnName}!`);
579
652
  changes.up += this.dialect.renameColumn(tableName, oldColumnName, newColumnName);
580
653
  changes.down += this.dialect.renameColumn(tableName, newColumnName, oldColumnName);
581
654
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sqlmorpheus",
3
- "version": "0.1.9",
3
+ "version": "0.2.0",
4
4
  "author": "JodliDev",
5
5
  "keywords": [],
6
6
  "license": "MIT",