sqlmorpheus 0.2.1 → 0.2.2

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