sqlmorpheus 0.2.1 → 0.2.3

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.js CHANGED
@@ -55,42 +55,67 @@ var LoggerClass = class {
55
55
  };
56
56
  var Logger = new LoggerClass();
57
57
 
58
- // src/lib/tableInfo/TableInfo.ts
59
- var TABLE_INFO_PROPERTY_NAME = Symbol("tableInfo");
60
- function getTableInfo(table) {
61
- let metadata = table[Symbol.metadata] ?? table.prototype?.[Symbol.metadata];
62
- if (!metadata) {
63
- metadata = {};
64
- table[Symbol.metadata] = metadata;
65
- }
66
- return getTableInfoFromMetadata(metadata);
67
- }
68
- function getTableInfoFromMetadata(metadata) {
69
- if (!metadata[TABLE_INFO_PROPERTY_NAME])
70
- metadata[TABLE_INFO_PROPERTY_NAME] = { primaryKey: "", foreignKeys: [] };
71
- return metadata[TABLE_INFO_PROPERTY_NAME];
72
- }
73
-
74
58
  // src/lib/tableInfo/TableObj.ts
75
59
  var TableObj = class _TableObj {
76
60
  IS_TABLE_OBJ = true;
77
61
  tableName;
78
- columns;
79
- tableInfo = {
62
+ tableStructure = {
63
+ table: "",
80
64
  primaryKey: void 0,
81
- foreignKeys: [],
82
- dataTypes: {}
65
+ columns: {},
66
+ foreignKeys: []
83
67
  };
84
- constructor(tableName, columns) {
68
+ static getEmptyColumnEntry(key) {
69
+ return {
70
+ name: key,
71
+ type: "",
72
+ defaultValue: "",
73
+ isPrimaryKey: false
74
+ };
75
+ }
76
+ static getColumnEntry(key, value) {
77
+ let dataType = typeof value;
78
+ switch (typeof value) {
79
+ case "function":
80
+ return null;
81
+ case "object":
82
+ if (value instanceof Date) {
83
+ dataType = "date";
84
+ break;
85
+ } else if (value !== null) {
86
+ Logger.warn(`${key} was skipped because its type (${typeof value}) is not supported`);
87
+ return null;
88
+ }
89
+ dataType = "string";
90
+ break;
91
+ case "undefined":
92
+ case "symbol":
93
+ Logger.warn(`${key} was skipped because its type (${typeof value}) is not supported`);
94
+ return null;
95
+ }
96
+ return {
97
+ ..._TableObj.getEmptyColumnEntry(key),
98
+ inputType: dataType,
99
+ inputDefaultValue: value
100
+ };
101
+ }
102
+ constructor(tableName, defaultValues) {
85
103
  this.tableName = tableName;
86
- this.columns = columns;
104
+ for (const key in defaultValues) {
105
+ const value = defaultValues[key];
106
+ const columnEntry = _TableObj.getColumnEntry(key, value);
107
+ if (!columnEntry)
108
+ continue;
109
+ this.tableStructure.columns[key] = columnEntry;
110
+ }
87
111
  }
88
112
  primaryKey(key) {
89
- this.tableInfo.primaryKey = key.toString();
113
+ this.tableStructure.primaryKey = key.toString();
114
+ this.tableStructure.columns[key.toString()].isPrimaryKey = true;
90
115
  return this;
91
116
  }
92
117
  foreignKey(fromColumn, toTable, toColumn, options) {
93
- this.tableInfo.foreignKeys.push({
118
+ this.tableStructure.foreignKeys.push({
94
119
  fromTable: this.tableName,
95
120
  fromColumn: fromColumn.toString(),
96
121
  toTable: toTable.tableName,
@@ -101,17 +126,44 @@ var TableObj = class _TableObj {
101
126
  return this;
102
127
  }
103
128
  dataType(column, type) {
104
- this.tableInfo.dataTypes[column.toString()] = type;
129
+ this.tableStructure.columns[column.toString()].inputType = type;
130
+ return this;
131
+ }
132
+ maxCharacterLength(column, max) {
133
+ this.tableStructure.columns[column.toString()].maxLength = max;
105
134
  return this;
106
135
  }
107
136
  static create(tableName, columns) {
108
137
  return new _TableObj(tableName, columns);
109
138
  }
110
- static isDbTable(obj) {
139
+ static isTableObj(obj) {
111
140
  return !!obj?.IS_TABLE_OBJ;
112
141
  }
113
142
  };
114
143
 
144
+ // src/lib/tableInfo/getTableStructure.ts
145
+ var TABLE_INFO_PROPERTY_NAME = Symbol("tableInfo");
146
+ function getInputColumnInfo(table, context) {
147
+ const metadata = context?.metadata ? getTableStructureFromMetadata(context.metadata) : getTableStructure(table);
148
+ const key = context.name ?? context;
149
+ if (!metadata.columns.hasOwnProperty(key))
150
+ metadata.columns[key] = TableObj.getEmptyColumnEntry(key);
151
+ return metadata.columns[key];
152
+ }
153
+ function getTableStructure(table) {
154
+ let metadata = table[Symbol.metadata] ?? table.prototype?.[Symbol.metadata];
155
+ if (!metadata) {
156
+ metadata = {};
157
+ table[Symbol.metadata] = metadata;
158
+ }
159
+ return getTableStructureFromMetadata(metadata);
160
+ }
161
+ function getTableStructureFromMetadata(metadata) {
162
+ if (!metadata[TABLE_INFO_PROPERTY_NAME])
163
+ metadata[TABLE_INFO_PROPERTY_NAME] = { table: "", primaryKey: "", foreignKeys: [], columns: {} };
164
+ return metadata[TABLE_INFO_PROPERTY_NAME];
165
+ }
166
+
115
167
  // src/lib/TableStructureGenerator.ts
116
168
  var TableStructureGenerator = class {
117
169
  dialect;
@@ -126,75 +178,31 @@ var TableStructureGenerator = class {
126
178
  * @return An object where keys are table names, and values are their corresponding table structures.
127
179
  */
128
180
  generateTableStructure() {
129
- const tableObjects = {};
181
+ const tables = {};
130
182
  for (const table of this.dbInstructions.tables) {
131
- if (TableObj.isDbTable(table))
132
- tableObjects[table.tableName] = table;
133
- else {
183
+ let structure;
184
+ if (TableObj.isTableObj(table)) {
185
+ structure = table.tableStructure;
186
+ tables[table.tableName] = table.tableStructure;
187
+ } else {
134
188
  const classTable = table;
135
- tableObjects[classTable.name] = { columns: new classTable(), tableInfo: getTableInfo(classTable) };
189
+ structure = getTableStructure(classTable);
190
+ tables[classTable.name] = getTableStructure(classTable);
136
191
  }
137
- }
138
- const tables = {};
139
- for (const tableName in tableObjects) {
140
- const obj = tableObjects[tableName];
141
- const tableInfo = obj.tableInfo;
142
- tables[tableName] = {
143
- table: tableName,
144
- primaryKey: tableInfo?.primaryKey,
145
- columns: this.getColumns(obj.columns, tableInfo),
146
- foreignKeys: tableInfo?.foreignKeys
147
- };
148
- }
149
- return tables;
150
- }
151
- /**
152
- * Retrieves the columns for a table
153
- *
154
- * @param obj - The table class interface object containing properties that represent the table's fields.
155
- * @param tableInfo - Optional metadata about the table. Can be undefined.
156
- * @return An array of {@link ColumnInfo} representing the detailed column information.
157
- */
158
- getColumns(obj, tableInfo) {
159
- const columns = [];
160
- for (const property in obj) {
161
- const propertyKey = property;
162
- const value = obj[propertyKey];
163
- const columnData = {
164
- name: property,
165
- isPrimaryKey: property == tableInfo?.primaryKey,
166
- type: this.dialect.types.string,
167
- defaultValue: this.dialect.types.null
168
- };
169
- let dataType = tableInfo?.dataTypes?.[property] ?? typeof value;
170
- switch (dataType) {
171
- case "function":
172
- continue;
173
- case "object":
174
- if (value instanceof Date) {
175
- dataType = "date";
176
- break;
177
- } else {
178
- Logger.warn(`${property} was skipped because its type (${typeof value}) is not supported`);
179
- continue;
180
- }
181
- case "undefined":
182
- case "symbol":
183
- Logger.warn(`${property} was skipped because its type (${typeof value}) is not supported`);
184
- continue;
192
+ for (const key in structure.columns) {
193
+ const entry = structure.columns[key];
194
+ entry.defaultValue = entry.inputDefaultValue === null ? this.dialect.types.null : this.dialect.formatValueToSql(entry.inputDefaultValue, entry.inputType);
195
+ entry.type = this.dialect.getSqlType(entry.inputType, entry);
185
196
  }
186
- columnData.defaultValue = value === null ? this.dialect.types.null : this.dialect.formatValueToSql(value, dataType);
187
- columnData.type = this.dialect.types[dataType];
188
- columns.push(columnData);
189
197
  }
190
- return columns;
198
+ return tables;
191
199
  }
192
200
  };
193
201
 
194
202
  // src/lib/exceptions/NotAllowedException.ts
195
203
  var NotAllowedException = class extends Error {
196
204
  constructor(entries) {
197
- let message = "Some destructive changes need to be confirmed. In preMigration() run:\n";
205
+ let message = "Some destructive changes need to be confirmed. To confirm, add to preMigration():\n";
198
206
  for (const entry of entries) {
199
207
  message += ` migrations.allowMigration(${entry.version}, ${entry.tableName}, "${entry.type}");
200
208
  `;
@@ -212,6 +220,13 @@ var Migrations = class {
212
220
  migrationDataForOldTableNames = {};
213
221
  alwaysAllowed = {};
214
222
  notAllowedChanges = [];
223
+ /**
224
+ * Resets the migration state to its initial values.
225
+ * Only used internally.
226
+ *
227
+ * @param dbInstructions - The instructions containing database metadata and migration details.
228
+ * @param fromVersion - The version of the actual database.
229
+ */
215
230
  reset(dbInstructions, fromVersion) {
216
231
  this.fromVersion = fromVersion;
217
232
  this.toVersion = dbInstructions.version;
@@ -220,10 +235,23 @@ var Migrations = class {
220
235
  this.alwaysAllowed = dbInstructions.alwaysAllowedMigrations ?? {};
221
236
  this.notAllowedChanges = [];
222
237
  }
238
+ /**
239
+ * Retrieves the migration instructions for the specified table.
240
+ * @see getEntryFromTableName
241
+ *
242
+ * @param table - The {@link TableInput} object from which the table name will be retrieved.
243
+ * @return The migration instructions corresponding to the given table input.
244
+ */
223
245
  getEntry(table) {
224
246
  const tableName = this.getTableName(table);
225
247
  return this.getEntryFromTableName(tableName);
226
248
  }
249
+ /**
250
+ * Retrieves the migration instructions for the specified table.
251
+ *
252
+ * @param tableName - The name of the table for which the entry is to be retrieved or created.
253
+ * @return The migration instructions corresponding to the given table input.
254
+ */
227
255
  getEntryFromTableName(tableName) {
228
256
  if (!this.migrationData.hasOwnProperty(tableName)) {
229
257
  this.migrationData[tableName] = {
@@ -235,17 +263,39 @@ var Migrations = class {
235
263
  }
236
264
  return this.migrationData[tableName];
237
265
  }
266
+ /**
267
+ * Retrieves the table name from the given table input.
268
+ *
269
+ * @param table - The {@link TableInput} object.
270
+ * @return The name of the table derived from either {@link TableObj} or a class.
271
+ */
238
272
  getTableName(table) {
239
- return TableObj.isDbTable(table) ? table.tableName : table.name;
273
+ return TableObj.isTableObj(table) ? table.tableName : table.name;
240
274
  }
275
+ /**
276
+ * Checks whether a provided version is relevant based on database version ({@link fromVersion}) and target version ({@link toVersion}).
277
+ * Also makes sure that version checks happen in order.
278
+ *
279
+ * @param version - The version to check for relevance.
280
+ * @return Returns true if the version is relevant, otherwise false.
281
+ * @throws Error if versions are not properly ordered
282
+ */
241
283
  versionIsRelevant(version) {
242
- if (version < this.fromVersion || version > this.toVersion)
284
+ if (version <= this.fromVersion || version > this.toVersion)
243
285
  return false;
244
286
  if (version < this.lastUsedVersion)
245
287
  throw new Error("Migrations in preMigration() have to be ordered by version (beginning with the lowest version).");
246
288
  this.lastUsedVersion = version;
247
289
  return true;
248
290
  }
291
+ /**
292
+ * Verifies the renaming tasks specified in {@link DatabaseInstructions.preMigration} that were considered are valid.
293
+ * Called after all SQL queries have been generated.
294
+ * Only used internally.
295
+ *
296
+ * @param newTables - The table structures extracted from {@link DatabaseInstructions.tables}.
297
+ * @throws Error if a renaming task is invalid.
298
+ */
249
299
  verifyRenamingTasks(newTables) {
250
300
  for (const tableName in this.migrationData) {
251
301
  const migrationEntry = this.migrationData[tableName];
@@ -262,11 +312,18 @@ var Migrations = class {
262
312
  const newColumnName = renamingData.newName;
263
313
  if (oldColumnName == newColumnName)
264
314
  return new Error(`You set column ${tableName}.${oldColumnName} to be renamed to itself!`);
265
- else if (!newTables[tableName]?.columns.find((column) => column.name == newColumnName))
315
+ else if (!newTables[tableName]?.columns[newColumnName])
266
316
  return new Error(`You set column ${tableName}.${oldColumnName} to be renamed to ${tableName}.${newColumnName}. But ${tableName}.${newColumnName} does not exist in your structure.`);
267
317
  }
268
318
  }
269
319
  }
320
+ /**
321
+ * Making sure all considered calls to {@link allowMigration()} where necessary to prevent input mistakes.
322
+ * Called after all SQL queries have been generated.
323
+ * Only used internally.
324
+ *
325
+ * @throws Error if unnecessary calls were discovered. All discovered calls are collected and thrown as one Error.
326
+ */
270
327
  verifyAllowedMigrations() {
271
328
  if (this.notAllowedChanges.length)
272
329
  return new NotAllowedException(this.notAllowedChanges);
@@ -282,6 +339,14 @@ var Migrations = class {
282
339
  if (errorMsg)
283
340
  return new Error(errorMsg);
284
341
  }
342
+ /**
343
+ * Called by {@link MigrationManager} to check if a specific destructive query is allowed.
344
+ * Only used internally.
345
+ *
346
+ * @see allowMigration()
347
+ * @param tableName - The name of the table to check the migration against.
348
+ * @param type - The type of destructive migration being checked.
349
+ */
285
350
  compareWithAllowedMigration(tableName, type) {
286
351
  const migrationEntry = this.migrationData[tableName];
287
352
  if (!migrationEntry?.allowedMigrations[type]) {
@@ -290,41 +355,114 @@ var Migrations = class {
290
355
  } else if (migrationEntry)
291
356
  migrationEntry.usedMigrations[type] = true;
292
357
  }
358
+ /**
359
+ * Retrieves the migration data containing instructions for data migration.
360
+ * Only used internally.
361
+ *
362
+ * @return An object where each key corresponds to the table name,
363
+ * and the value is the associated migration instructions.
364
+ */
293
365
  getMigrationData() {
294
366
  return this.migrationData;
295
367
  }
368
+ /**
369
+ * Iterates over renamed columns for the specified table and executes a callback for each pair of old and new column names.
370
+ * Only used internally.
371
+ *
372
+ * @param tableName - Name of the table whose renamed columns should be processed.
373
+ * @param callback - A function to execute for each renamed column, receiving the old and new column names as arguments.
374
+ */
296
375
  loopRenamedColumns(tableName, callback) {
297
376
  const migrationEntry = this.migrationData[tableName];
298
377
  for (const renamingData of migrationEntry.renamedColumns) {
299
378
  callback(renamingData.oldName, renamingData.newName);
300
379
  }
301
380
  }
381
+ /**
382
+ * Considers the renaming of a table and returns its (newest) name after the migration or
383
+ * the original name if no renaming is queued.
384
+ * Only used internally.
385
+ *
386
+ * @see getOldTableName()
387
+ * @param tableName - The current table name in the database.
388
+ * @return The newest table name if available, otherwise the current table name.
389
+ */
302
390
  getNewestTableName(tableName) {
303
391
  return this.migrationDataForOldTableNames[tableName]?.tableRenaming?.newName ?? tableName;
304
392
  }
393
+ /**
394
+ * Retrieves the current table name in the database.
395
+ * Only used internally.
396
+ *
397
+ * @see getNewestTableName()
398
+ * @param tableName - The name of the newest table name.
399
+ * @return The current table name in the database.
400
+ */
305
401
  getOldTableName(tableName) {
306
402
  return this.migrationData[tableName]?.tableRenaming?.oldName ?? tableName;
307
403
  }
404
+ /**
405
+ * Considers the renaming of a column in a table and returns its (newest) name after the migration or
406
+ * the original name if no renaming is queued.
407
+ * Only used internally.
408
+ *
409
+ * @param tableName - The name of the table containing the column.
410
+ * @param oldColumnName - The current name of the column in the database.
411
+ * @return The newest column name if available, otherwise the original column name.
412
+ */
308
413
  getNewestColumnName(tableName, oldColumnName) {
309
414
  const columnNames = this.migrationData[tableName]?.renamedColumns.find((columns) => columns.oldName == oldColumnName);
310
415
  return columnNames ? columnNames.newName : oldColumnName;
311
416
  }
417
+ /**
418
+ * Determines if the specified table is marked to be recreated.
419
+ * Only used internally.
420
+ *
421
+ * @param tableName The name of the table to check.
422
+ * @return Returns true if the table will be recreated, false otherwise.
423
+ */
312
424
  willBeRecreated(tableName) {
313
425
  return this.migrationData[tableName]?.recreate;
314
426
  }
427
+ /**
428
+ * Marks a table to be recreated and logs the recreation reason for the user.
429
+ * Only used internally.
430
+ *
431
+ * @param tableName - The name of the table to be marked for recreation.
432
+ * @param reason - The reason why the table is being marked for recreation.
433
+ */
315
434
  internalRecreate(tableName, reason) {
316
435
  const entry = this.getEntryFromTableName(tableName);
317
436
  entry.recreate = true;
318
437
  Logger.log(`Table ${tableName} will be recreated(${reason})!`);
319
438
  }
439
+ /**
440
+ * SqlMorpheus only allows destructive statements if it was specifically allowed in {@link DatabaseInstructions.preMigration()}.
441
+ * Use this method to allow a destructive statement for a specific version.
442
+ * This method will be ignored if {@link version} is smaller than the current database version or higher than the target version of {@link DatabaseInstructions}.
443
+ *
444
+ * @param version - The target version for which the specific migration is allowed. Must be provided to make sure this method will only have an effect when specified.
445
+ * @param table - Either a {@link TableObj} or a class decorated with @TableClass.
446
+ * @param allowedMigrations - The keys representing the migrations to be allowed. Multiple migrations can be provided
447
+ */
320
448
  allowMigration(version, table, ...allowedMigrations) {
321
- if (version < this.fromVersion || version > this.toVersion)
449
+ if (!this.versionIsRelevant(version))
322
450
  return;
323
451
  const entry = this.getEntry(table);
324
452
  for (const key of allowedMigrations) {
325
453
  entry.allowedMigrations[key] = true;
326
454
  }
327
455
  }
456
+ /**
457
+ * When you change the name of a table, SqlMorpheus will assume the original table was meant to be dropped
458
+ * and the new table was meant to be added, which would lead to data loss.
459
+ * Use this method to mark a table to be renamed instead.
460
+ * This method will be ignored if {@link version} is smaller than the current database version or higher than the target version of {@link DatabaseInstructions}.
461
+ *
462
+ * @param version - The target version for which the table should be renamed. Must be provided to make sure this method will only have an effect when specified.
463
+ * @param oldTableName - The current name in the database at the time of the migration.
464
+ * @param newTableName - The new table name or its equivalent input format.
465
+ */
328
466
  renameTable(version, oldTableName, newTableName) {
329
467
  if (!this.versionIsRelevant(version))
330
468
  return;
@@ -336,6 +474,17 @@ var Migrations = class {
336
474
  else
337
475
  entry.tableRenaming.newName = newTableNameString;
338
476
  }
477
+ /**
478
+ * When you change the name of a column, SqlMorpheus will assume the original column was meant to be removed
479
+ * and the new column was meant to be added, which would lead to data loss.
480
+ * Use this method to mark a column to be renamed instead.
481
+ * This method will be ignored if {@link version} is smaller than the current database version or higher than the target version of {@link DatabaseInstructions}.
482
+ *
483
+ * @param version - The target version for which the table should be renamed. Must be provided to make sure this method will only have an effect when specified.
484
+ * @param table Either a {@link TableObj} or a class decorated with @TableClass containing the column to be renamed.
485
+ * @param oldColumn The current name in the database at the time of the migration.
486
+ * @param newColumn The new name to assign to the column.
487
+ */
339
488
  renameColumn(version, table, oldColumn, newColumn) {
340
489
  if (!this.versionIsRelevant(version))
341
490
  return;
@@ -346,6 +495,15 @@ var Migrations = class {
346
495
  else
347
496
  entry.renamedColumns.push({ oldName: oldColumn, newName: newColumn });
348
497
  }
498
+ /**
499
+ * Should not be needed most of the time.
500
+ * Marks a table to be recreated
501
+ * (a copy of the table will be created, all data will be moved over, the original table will be dropped and the new table will be renamed to the original name).
502
+ * This method will be ignored if {@link version} is smaller than the current database version or higher than the target version of {@link DatabaseInstructions}.
503
+ *
504
+ * @param version - The target version for which the table should be renamed. Must be provided to make sure this method will only have an effect when specified.
505
+ * @param table Either a {@link TableObj} or a class decorated with @TableClass.
506
+ */
349
507
  recreateTable(version, table) {
350
508
  if (!this.versionIsRelevant(version))
351
509
  return;
@@ -534,8 +692,9 @@ ${changes.up}
534
692
  */
535
693
  createTableSql(tableName, columns, foreignKeys) {
536
694
  const queryLines = [];
537
- for (const columnInfo of columns) {
538
- queryLines.push(this.dialect.columnDefinition(columnInfo.name, columnInfo.type, columnInfo.defaultValue, columnInfo.isPrimaryKey));
695
+ for (const key in columns) {
696
+ const columnInfo = columns[key];
697
+ queryLines.push(this.dialect.columnDefinition(columnInfo.name, columnInfo.type, columnInfo.isPrimaryKey, columnInfo.defaultValue));
539
698
  }
540
699
  if (foreignKeys) {
541
700
  for (const foreignKeyInfo of foreignKeys) {
@@ -573,7 +732,11 @@ ${changes.up}
573
732
  this.migrations.compareWithAllowedMigration(tableName, "continueWithoutRollback");
574
733
  const oldColumnList = await this.dialect.getColumnInformation(this.migrations.getOldTableName(tableName));
575
734
  const newColumnList = this.newTables[tableName].columns;
576
- const moveableColumns = newColumnList.filter((entry) => oldColumnList.find((oldEntry) => oldEntry.name == entry.name) != void 0).map((entry) => entry.name);
735
+ const moveableColumns = [];
736
+ for (const key in newColumnList) {
737
+ if (oldColumnList.hasOwnProperty(key))
738
+ moveableColumns.push(newColumnList[key].name);
739
+ }
577
740
  const backupTableName = `${tableName}__backup`;
578
741
  const insertQuery = this.dialect.insert(
579
742
  backupTableName,
@@ -581,7 +744,7 @@ ${changes.up}
581
744
  );
582
745
  const moveDataQuery = insertQuery + "\n" + this.dialect.dropTable(tableName) + "\n" + this.dialect.renameTable(backupTableName, tableName);
583
746
  const structure = this.newTables[tableName];
584
- changes.up += this.createTableSql(backupTableName, structure.columns, structure.foreignKeys) + "\n" + moveDataQuery + "\n";
747
+ changes.up += this.createTableSql(backupTableName, structure.columns, structure.foreignKeys) + "\n" + moveDataQuery + "\n\n";
585
748
  const dbTableName = this.migrations.getOldTableName(tableName);
586
749
  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";
587
750
  }
@@ -673,6 +836,10 @@ ${changes.up}
673
836
  const newTableDefinition = this.newTables[tableName];
674
837
  const oldColumnList = await this.dialect.getColumnInformation(this.migrations.getOldTableName(tableName));
675
838
  const oldPrimaryKey = this.dialect.canInspectPrimaryKey ? this.getPrimaryKeyColumn(oldColumnList) : false;
839
+ const oldColumnNewNameIndex = {};
840
+ for (const key in oldColumnList) {
841
+ oldColumnNewNameIndex[this.migrations.getNewestColumnName(tableName, key)] = oldColumnList[key];
842
+ }
676
843
  const newColumnList = newTableDefinition.columns;
677
844
  const newPrimaryKey = newTableDefinition.primaryKey;
678
845
  if (this.dialect.canInspectPrimaryKey && oldPrimaryKey != newPrimaryKey) {
@@ -691,25 +858,23 @@ ${changes.up}
691
858
  this.migrations.internalRecreate(newTableDefinition.table, "Dialect does not support altering primary keys");
692
859
  continue;
693
860
  }
694
- for (const newColumn of newColumnList) {
695
- const oldColumn = oldColumnList.find(
696
- (entry) => this.migrations.getNewestColumnName(tableName, entry.name) == newColumn.name
697
- );
861
+ for (const key in newColumnList) {
862
+ const newColumn = newColumnList[key];
863
+ const oldColumn = oldColumnNewNameIndex[newColumn.name];
698
864
  if (oldColumn == void 0) {
699
- changes.up += this.dialect.createColumn(tableName, this.dialect.columnDefinition(newColumn.name, newColumn.type, newColumn.defaultValue, newColumn.isPrimaryKey)) + "\n";
865
+ changes.up += this.dialect.createColumn(tableName, this.dialect.columnDefinition(newColumn.name, newColumn.type, newColumn.isPrimaryKey, newColumn.defaultValue)) + "\n";
700
866
  changes.down += this.dialect.dropColumn(tableName, newColumn.name) + "\n";
701
867
  } else if (newColumn.type != oldColumn.type || newColumn.defaultValue != oldColumn.defaultValue) {
702
868
  this.migrations.internalRecreate(newTableDefinition.table, "Table structure was changed");
703
869
  }
704
870
  }
705
- for (const oldColumn of oldColumnList) {
706
- const newColumn = newColumnList.find(
707
- (entry) => entry.name == this.migrations.getNewestColumnName(tableName, oldColumn.name)
708
- );
871
+ for (const key in oldColumnList) {
872
+ const oldColumn = oldColumnList[key];
873
+ const newColumn = newColumnList[this.migrations.getNewestColumnName(tableName, oldColumn.name)];
709
874
  if (newColumn == void 0) {
710
875
  this.migrations.compareWithAllowedMigration(tableName, "dropColumn");
711
876
  changes.up += this.dialect.dropColumn(tableName, oldColumn.name) + "\n";
712
- changes.down += this.dialect.createColumn(tableName, this.dialect.columnDefinition(oldColumn.name, oldColumn.type, oldColumn.defaultValue, oldColumn.isPrimaryKey)) + "\n";
877
+ changes.down += this.dialect.createColumn(tableName, this.dialect.columnDefinition(oldColumn.name, oldColumn.type, oldColumn.isPrimaryKey, oldColumn.defaultValue)) + "\n";
713
878
  }
714
879
  }
715
880
  }
@@ -718,11 +883,12 @@ ${changes.up}
718
883
  /**
719
884
  * Retrieves the name of the primary key column from a list of column information.
720
885
  *
721
- * @param columnInfoList - An array of ColumnInfo objects containing details about each column.
886
+ * @param columnInfoEntries - An array of ColumnInfo objects containing details about each column.
722
887
  * @return The name of the primary key column if found; otherwise, undefined.
723
888
  */
724
- getPrimaryKeyColumn(columnInfoList) {
725
- for (const columnInfo of columnInfoList) {
889
+ getPrimaryKeyColumn(columnInfoEntries) {
890
+ for (const key in columnInfoEntries) {
891
+ const columnInfo = columnInfoEntries[key];
726
892
  if (columnInfo.isPrimaryKey)
727
893
  return columnInfo.name;
728
894
  }
@@ -812,15 +978,27 @@ ${changes.down}`, { encoding: "utf-8" });
812
978
  var import_polyfill_symbol_metadata = require("polyfill-symbol-metadata");
813
979
  function TableClass(tableName, primaryKey) {
814
980
  return (table, context) => {
815
- const tableInfo = context?.metadata ? getTableInfoFromMetadata(context.metadata) : getTableInfo(table);
816
- tableInfo.primaryKey = primaryKey?.toString();
817
- if (tableInfo.foreignKeys) {
818
- for (const foreignKey of tableInfo.foreignKeys) {
981
+ const tableStructure = context?.metadata ? getTableStructureFromMetadata(context.metadata) : getTableStructure(table);
982
+ tableStructure.primaryKey = primaryKey?.toString();
983
+ tableStructure.table = tableName;
984
+ if (tableStructure.foreignKeys) {
985
+ for (const foreignKey of tableStructure.foreignKeys) {
819
986
  foreignKey.fromTable = tableName;
820
987
  if (foreignKey.toTable == table.name)
821
988
  foreignKey.toTable = tableName;
822
989
  }
823
990
  }
991
+ for (const key in table) {
992
+ const value = table[key];
993
+ const existingEntry = tableStructure.columns[key];
994
+ const defaultEntry = TableObj.getColumnEntry(key, value);
995
+ if (!defaultEntry)
996
+ continue;
997
+ tableStructure.columns[key] = {
998
+ ...defaultEntry,
999
+ ...existingEntry
1000
+ };
1001
+ }
824
1002
  Object.defineProperty(table, "name", { value: tableName, writable: false });
825
1003
  };
826
1004
  }
@@ -829,10 +1007,8 @@ function TableClass(tableName, primaryKey) {
829
1007
  var import_polyfill_symbol_metadata2 = require("polyfill-symbol-metadata");
830
1008
  function DataType(type) {
831
1009
  return (table, context) => {
832
- const metadata = context?.metadata ? getTableInfoFromMetadata(context.metadata) : getTableInfo(table);
833
- if (!metadata.dataTypes)
834
- metadata.dataTypes = {};
835
- metadata.dataTypes[context.name ?? context] = type;
1010
+ const entry = getInputColumnInfo(table, context);
1011
+ entry.inputType = type;
836
1012
  };
837
1013
  }
838
1014
 
@@ -840,7 +1016,7 @@ function DataType(type) {
840
1016
  var import_polyfill_symbol_metadata3 = require("polyfill-symbol-metadata");
841
1017
  function ForeignKey(toTable, toColumn, options) {
842
1018
  return (table, context) => {
843
- const metadata = context?.metadata ? getTableInfoFromMetadata(context.metadata) : getTableInfo(table);
1019
+ const metadata = context?.metadata ? getTableStructureFromMetadata(context.metadata) : getTableStructure(table);
844
1020
  if (!metadata.foreignKeys)
845
1021
  metadata.foreignKeys = [];
846
1022
  metadata.foreignKeys.push({
@@ -880,7 +1056,7 @@ var DefaultSql = class {
880
1056
  * Formats a given value to a SQL-equivalent string based on the provided data type.
881
1057
  *
882
1058
  * @param value - The value to be formatted.
883
- * @param type - The data type of the value. Either determined through typeof or {@link TableInfo} setting
1059
+ * @param type - The data type of the value. Either determined through typeof or {@link TableStructure} setting
884
1060
  * @return A string representation of the value formatted for SQL.
885
1061
  */
886
1062
  formatValueToSql(value, type) {
@@ -891,65 +1067,68 @@ var DefaultSql = class {
891
1067
  case "string":
892
1068
  return `"${value}"`;
893
1069
  case "time":
894
- return toDate(value).toISOString().slice(11, 19);
1070
+ return `"${toDate(value).toISOString().slice(11, 19)}"`;
895
1071
  case "date":
896
- return toDate(value).toISOString().slice(0, 10);
1072
+ return `"${toDate(value).toISOString().slice(0, 10)}"`;
897
1073
  case "dateTime":
898
- return toDate(value).toISOString().slice(0, 19).replace("T", " ");
1074
+ return `"${toDate(value).toISOString().slice(0, 19).replace("T", " ")}"`;
899
1075
  default:
900
1076
  return value.toString();
901
1077
  }
902
1078
  }
1079
+ getSqlType(dataType, _) {
1080
+ return this.types[dataType];
1081
+ }
903
1082
  /**
904
- * Query to enable / disable foreign keys in the database.
1083
+ * Statement to enable / disable foreign keys in the database.
905
1084
  * Is dialect specific.
906
1085
  *
907
1086
  * @param enabled - A boolean indicating whether to enable or disable foreign key constraints.
908
- * @return The query
1087
+ * @return The SQL statement as a string.
909
1088
  */
910
1089
  changeForeignKeysState(enabled) {
911
1090
  return "";
912
1091
  }
913
1092
  /**
914
- * Query to add a foreign key to a specified table.
1093
+ * Statement to add a foreign key to a specified table.
915
1094
  * Is only used if {@link canAlterForeignKeys} is true.
916
1095
  *
917
1096
  * @param fromTableName - The name of the table to which the foreign key will be added.
918
1097
  * @param foreignKey - The foreign key definition to be added, see {@link foreignKey()}.
919
- * @return The SQL statement that adds the foreign key to the specified table.
1098
+ * @return The SQL statement as a string.
920
1099
  */
921
1100
  addForeignKey(fromTableName, foreignKey) {
922
1101
  throw new Error("Adding foreign keys is not supported!");
923
1102
  }
924
1103
  /**
925
- * Query to remove a foreign key from a specified table.
1104
+ * Statement to remove a foreign key from a specified table.
926
1105
  * Is only used if {@link canAlterForeignKeys} is true.
927
1106
  *
928
1107
  * @param tableName - The name of the table to which the foreign key will be added.
929
1108
  * @param foreignKeyName - The name of the foreign key definition.
930
- * @return The SQL statement that removes the foreign key from the specified table.
1109
+ * @return The SQL statement as a string.
931
1110
  */
932
1111
  removeForeignKey(tableName, foreignKeyName) {
933
1112
  throw new Error("Foreign key removal is not supported!");
934
1113
  }
935
1114
  /**
936
- * Query to add a primary key to the specified table.
1115
+ * Statement to add a primary key to the specified table.
937
1116
  * Is only used if {@link canAlterPrimaryKey} is true.
938
1117
  *
939
1118
  * @param tableName - The name of the table to which the primary key will be added.
940
1119
  * @param columnName - The name of the column that will be set as the primary key.
941
- * @return A SQL statement to add a primary key to the specified table and column.
1120
+ * @return The SQL statement as a string.
942
1121
  */
943
1122
  addPrimaryKey(tableName, columnName) {
944
1123
  throw new Error("Adding foreign keys is not supported!");
945
1124
  }
946
1125
  /**
947
- * Query to remove a primary key from the specified table.
1126
+ * Statement to remove a primary key from the specified table.
948
1127
  * Is only used if {@link canAlterPrimaryKey} is true.
949
1128
  *
950
1129
  * @param tableName - The name of the table to which the primary key will be added.
951
1130
  * @param columnName - The name of the column that will be set as the primary key.
952
- * @return A SQL statement to remove a primary key from the specified table and column.
1131
+ * @return The SQL statement as a string.
953
1132
  */
954
1133
  removePrimaryKey(tableName, columnName) {
955
1134
  throw new Error("Foreign key removal is not supported!");
@@ -973,64 +1152,164 @@ var DefaultSql = class {
973
1152
  query += ` ON DELETE ${onDelete}`;
974
1153
  return query;
975
1154
  }
1155
+ /**
1156
+ * Statement to create a table if it does not already exist.
1157
+ *
1158
+ * @param tableName - The name of the table to be created.
1159
+ * @param entries - An array containing the column definitions for the table.
1160
+ * @return The SQL statement as a string.
1161
+ */
976
1162
  createTable(tableName, entries) {
977
1163
  return `CREATE TABLE IF NOT EXISTS ${tableName} (
978
1164
  ${entries.join(",\n ")}
979
1165
  );`;
980
1166
  }
1167
+ /**
1168
+ * Statement to rename a table.
1169
+ *
1170
+ * @param tableName - The name of the existing table to be renamed.
1171
+ * @param newTableName - The new name for the table.
1172
+ * @return The SQL statement as a string.
1173
+ */
981
1174
  renameTable(tableName, newTableName) {
982
1175
  return `ALTER TABLE ${tableName} RENAME TO ${newTableName};`;
983
1176
  }
1177
+ /**
1178
+ * Statement to drop a table if it exists.
1179
+ *
1180
+ * @param tableName - The name of the table to be dropped.
1181
+ * @return The SQL statement as a string.
1182
+ */
984
1183
  dropTable(tableName) {
985
1184
  return `DROP TABLE IF EXISTS ${tableName};`;
986
1185
  }
987
- columnDefinition(columnName, type, defaultValue, isPrimaryKey) {
988
- const query = `${columnName} ${type} DEFAULT ${defaultValue}`;
1186
+ /**
1187
+ * Constructs a SQL column definition based on the provided parameters.
1188
+ *
1189
+ * @param columnName - The name of the column.
1190
+ * @param type - The data type of the column.
1191
+ * @param defaultValue - The default value for the column.
1192
+ * @param isPrimaryKey - Indicates whether the column is a primary key.
1193
+ * @return The constructed SQL column definition string.
1194
+ */
1195
+ columnDefinition(columnName, type, isPrimaryKey, defaultValue) {
1196
+ const query = `${columnName} ${type}${defaultValue ? ` DEFAULT ${defaultValue}` : ""}`;
989
1197
  return isPrimaryKey ? `${query} PRIMARY KEY` : query;
990
1198
  }
1199
+ /**
1200
+ * Statement to add a new column to a specified table.
1201
+ *
1202
+ * @param columnTable - The name of the table to which the column will be added.
1203
+ * @param entry - The column definition including the column name and its data type. See {@link columnDefinition()}
1204
+ * @return The SQL statement as a string.
1205
+ */
991
1206
  createColumn(columnTable, entry) {
992
1207
  return `ALTER TABLE ${columnTable} ADD ${entry};`;
993
1208
  }
1209
+ /**
1210
+ * Statement to rename a column in an existing table.
1211
+ *
1212
+ * @param tableName - The name of the table containing the column to rename.
1213
+ * @param oldColumnName - The current name of the column to be renamed.
1214
+ * @param newColumnName - The new name for the column.
1215
+ * @return The SQL statement as a string.
1216
+ */
994
1217
  renameColumn(tableName, oldColumnName, newColumnName) {
995
1218
  return `ALTER TABLE ${tableName} RENAME COLUMN ${oldColumnName} TO ${newColumnName};`;
996
1219
  }
997
- copyColumn(tableName, oldColumnName, newColumnName) {
998
- return `UPDATE ${tableName} SET ${newColumnName} = ${oldColumnName};`;
999
- }
1220
+ /**
1221
+ * Statement to drop a column from a specified table.
1222
+ *
1223
+ * @param tableName - The name of the table from which the column will be dropped.
1224
+ * @param columnName - The name of the column to be dropped.
1225
+ * @return The SQL statement as a string.
1226
+ */
1000
1227
  dropColumn(tableName, columnName) {
1001
1228
  return `ALTER TABLE ${tableName} DROP COLUMN ${columnName};`;
1002
1229
  }
1230
+ /**
1231
+ * Statement to return data from a table.
1232
+ *
1233
+ * @param tableName - The name of the database table to select data from.
1234
+ * @param select - An array of column names to include in the SELECT clause.
1235
+ * @param where - An optional condition.
1236
+ * @return The SQL statement as a string.
1237
+ */
1003
1238
  select(tableName, select, where) {
1004
1239
  let query = `SELECT ${select.join(",")} FROM ${tableName}`;
1005
1240
  if (where)
1006
1241
  query += ` WHERE ${where}`;
1007
1242
  return `${query};`;
1008
1243
  }
1244
+ /**
1245
+ * Statement to insert data into a table.
1246
+ *
1247
+ * @param tableName - The name of the table where the data will be inserted.
1248
+ * @param content - The value query. See {@link insertValues()}.
1249
+ * @return The SQL statement as a string.
1250
+ */
1009
1251
  insert(tableName, content) {
1010
1252
  return `INSERT INTO ${tableName} ${content};`;
1011
1253
  }
1254
+ /**
1255
+ * A SQL insert query string. See {@link insert()}.
1256
+ *
1257
+ * @param keys - An array of column names to be used in the query.
1258
+ * @param [valueString] - An optional preformatted value string to be included in the query.
1259
+ * If not provided, the method generates a default placeholder string with "?" for each key.
1260
+ * @return The SQL statement as a string.
1261
+ */
1012
1262
  insertValues(keys, valueString) {
1013
1263
  return `(${keys}) ${valueString ?? `VALUES (${keys.map(() => "?").join(",")})`}`;
1014
1264
  }
1265
+ /**
1266
+ * Returns a SQL query string to create a migration table.
1267
+ * The table is used to store migration data, specifically the version of the migration.
1268
+ *
1269
+ * @return The SQL query string for creating the migration table.
1270
+ */
1015
1271
  migrationTableQuery() {
1016
1272
  return this.createTable(MIGRATION_DATA_TABLE_NAME, [
1017
- this.columnDefinition("version", this.types.number, "0", false)
1273
+ this.columnDefinition("version", this.types.number, false, "0")
1018
1274
  ]);
1019
1275
  }
1276
+ /**
1277
+ * Fetches the foreign keys for the specified table.
1278
+ * This method is only used if {@link canInspectForeignKeys} is true
1279
+ *
1280
+ * @param tableName - The name of the table for which to retrieve foreign key information.
1281
+ * @return {Promise<ForeignKeyInfo[]>} A promise that resolves to an array of {@link ForeignKeyInfo}.
1282
+ */
1020
1283
  async getForeignKeys(tableName) {
1021
1284
  throw new Error("Inspecting foreign keys is not supported!");
1022
1285
  }
1286
+ /**
1287
+ * Ensures that the migration table exists in the database.
1288
+ * If the table does not exist, it creates the table using the defined migration table query.
1289
+ *
1290
+ * @return A promise that resolves when the migration table is created successfully.
1291
+ */
1023
1292
  async createMigrationTableIfNeeded() {
1024
1293
  await this.db.runMultipleWriteStatements(this.migrationTableQuery());
1025
1294
  }
1026
- //TODO: untested
1295
+ /**
1296
+ * Retrieves the current version from the migration data table.
1297
+ *
1298
+ * @return A promise that resolves to the current version number. Returns 0 if no version is found.
1299
+ */
1027
1300
  async getVersion() {
1028
1301
  await this.createMigrationTableIfNeeded();
1029
1302
  const query = this.select(MIGRATION_DATA_TABLE_NAME, ["version"]);
1030
1303
  const data = await this.db.runGetStatement(query);
1031
1304
  return data.length ? data[0].version : 0;
1032
1305
  }
1033
- //TODO: untested
1306
+ /**
1307
+ * Updates the migration version in the database. If the version entry does not exist, it inserts a new one;
1308
+ * if it exists, it updates the version to the specified value.
1309
+ *
1310
+ * @param newVersion - The new migration version to set in the database.
1311
+ * @return A promise that resolves when the operation is complete.
1312
+ */
1034
1313
  async setVersion(newVersion) {
1035
1314
  const query = `${this.migrationTableQuery()};
1036
1315
  INSERT INTO ${MIGRATION_DATA_TABLE_NAME} (version) VALUES ${newVersion} WHERE NOT EXISTS (SELECT 1 FROM ${MIGRATION_DATA_TABLE_NAME})
@@ -1048,9 +1327,9 @@ var SqliteDialect = class extends DefaultSql {
1048
1327
  number: "INTEGER",
1049
1328
  bigint: "INTEGER",
1050
1329
  boolean: "INTEGER",
1051
- date: "DATE",
1052
- time: "TIME",
1053
- dateTime: "DATETIME",
1330
+ date: "INTEGER",
1331
+ time: "INTEGER",
1332
+ dateTime: "INTEGER",
1054
1333
  null: "NULL"
1055
1334
  };
1056
1335
  canAlterForeignKeys = false;
@@ -1065,14 +1344,16 @@ var SqliteDialect = class extends DefaultSql {
1065
1344
  }
1066
1345
  async getColumnInformation(tableName) {
1067
1346
  const data = await this.db.runGetStatement(`PRAGMA table_info(${tableName})`);
1068
- return data.map((entry) => {
1069
- return {
1347
+ const output = {};
1348
+ for (const entry of data) {
1349
+ output[entry["name"]] = {
1070
1350
  name: entry["name"],
1071
1351
  type: entry["type"],
1072
1352
  defaultValue: entry["dflt_value"],
1073
1353
  isPrimaryKey: entry["pk"] == "1"
1074
1354
  };
1075
- });
1355
+ }
1356
+ return output;
1076
1357
  }
1077
1358
  formatValueToSql(value, type) {
1078
1359
  function toDate(value2) {
@@ -1097,8 +1378,8 @@ var SqliteDialect = class extends DefaultSql {
1097
1378
  fromColumn: entry["from"],
1098
1379
  toTable: entry["table"],
1099
1380
  toColumn: entry["to"],
1100
- on_update: entry["on_update"],
1101
- on_delete: entry["on_delete"]
1381
+ onUpdate: entry["on_update"] ?? "NO ACTION",
1382
+ onDelete: entry["on_delete"] ?? "NO ACTION"
1102
1383
  };
1103
1384
  });
1104
1385
  }
@@ -1131,14 +1412,17 @@ var PostgresDialect = class extends DefaultSql {
1131
1412
  }
1132
1413
  async getColumnInformation(tableName) {
1133
1414
  const data = await this.db.runGetStatement(`SELECT column_name, data_type, column_default FROM information_schema.columns WHERE table_schema = 'public' AND table_name = '${tableName}';`);
1134
- return data.map((entry) => {
1135
- return {
1415
+ const output = {};
1416
+ for (const entry of data) {
1417
+ output[entry["name"]] = {
1136
1418
  name: entry["column_name"],
1137
1419
  type: entry["data_type"],
1420
+ maxLength: 0,
1138
1421
  defaultValue: entry["column_default"],
1139
1422
  isPrimaryKey: false
1140
1423
  };
1141
- });
1424
+ }
1425
+ return output;
1142
1426
  }
1143
1427
  addPrimaryKey(tableName, columnName) {
1144
1428
  return `ALTER TABLE ${tableName} ADD PRIMARY KEY (${columnName});
@@ -1183,18 +1467,21 @@ var MsSqlDialect = class extends DefaultSql {
1183
1467
  });
1184
1468
  }
1185
1469
  async getTableNames() {
1186
- return await this.db.runGetStatement("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'");
1470
+ return (await this.db.runGetStatement("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'")).map((entry) => entry.name);
1187
1471
  }
1188
1472
  async getColumnInformation(tableName) {
1189
1473
  const data = await this.db.runGetStatement(`SELECT COLUMN_NAME, DATA_TYPE, COLUMN_DEFAULT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = N'${tableName};'`);
1190
- return data.map((entry) => {
1191
- return {
1192
- name: entry["COLUMN_NAME"],
1474
+ const output = {};
1475
+ for (const entry of data) {
1476
+ output[entry["name"]] = {
1477
+ name: entry["name"],
1193
1478
  type: entry["DATA_TYPE"],
1479
+ maxLength: 0,
1194
1480
  defaultValue: entry["COLUMN_DEFAULT"],
1195
- isPrimaryKey: false
1481
+ isPrimaryKey: entry["pk"] == "1"
1196
1482
  };
1197
- });
1483
+ }
1484
+ return output;
1198
1485
  }
1199
1486
  };
1200
1487
 
@@ -1204,9 +1491,26 @@ var MySqlDialect = class extends DefaultSql {
1204
1491
  canAlterPrimaryKey = true;
1205
1492
  canInspectForeignKeys = true;
1206
1493
  canInspectPrimaryKey = true;
1494
+ types = {
1495
+ string: "VARCHAR",
1496
+ number: "INT",
1497
+ bigint: "BIGINT",
1498
+ boolean: "BOOLEAN",
1499
+ date: "DATE",
1500
+ time: "TIME",
1501
+ dateTime: "DATETIME",
1502
+ null: "NULL"
1503
+ };
1504
+ getSqlType(dataType, columnInfo) {
1505
+ switch (dataType) {
1506
+ case "string":
1507
+ return this.types[dataType] + `(${columnInfo?.maxLength})`;
1508
+ default:
1509
+ return super.getSqlType(dataType, columnInfo);
1510
+ }
1511
+ }
1207
1512
  changeForeignKeysState(enabled) {
1208
- return `SET FOREIGN_KEY_CHECKS ${enabled ? "1" : "0"}
1209
- ;`;
1513
+ return `SET FOREIGN_KEY_CHECKS ${enabled ? "1" : "0"};`;
1210
1514
  }
1211
1515
  addForeignKey(fromTableName, foreignKey) {
1212
1516
  return `ALTER TABLE ${fromTableName} ADD ${foreignKey};`;
@@ -1232,18 +1536,22 @@ var MySqlDialect = class extends DefaultSql {
1232
1536
  });
1233
1537
  }
1234
1538
  async getTableNames() {
1235
- return await this.db.runGetStatement("SHOW TABLES;");
1539
+ const t = await this.db.runGetStatement("SELECT table_name FROM information_schema.tables;");
1540
+ return (await this.db.runGetStatement("SELECT table_name FROM information_schema.tables;")).map((entry) => entry.name);
1236
1541
  }
1237
1542
  async getColumnInformation(tableName) {
1238
1543
  const data = await this.db.runGetStatement(`SHOW COLUMNS FROM ${tableName};`);
1239
- return data.map((entry) => {
1240
- return {
1241
- name: entry["Field"],
1242
- type: entry["Type"],
1243
- defaultValue: entry["Default"],
1244
- isPrimaryKey: entry["Key"] == "PRI"
1544
+ const output = {};
1545
+ for (const entry of data) {
1546
+ output[entry["name"]] = {
1547
+ name: entry["name"],
1548
+ type: entry["type"],
1549
+ maxLength: 0,
1550
+ defaultValue: entry["dflt_value"],
1551
+ isPrimaryKey: entry["pk"] == "1"
1245
1552
  };
1246
- });
1553
+ }
1554
+ return output;
1247
1555
  }
1248
1556
  };
1249
1557