sqlmorpheus 0.2.0 → 0.2.1

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.mjs CHANGED
@@ -37,6 +37,47 @@ function getTableInfoFromMetadata(metadata) {
37
37
  return metadata[TABLE_INFO_PROPERTY_NAME];
38
38
  }
39
39
 
40
+ // src/lib/tableInfo/TableObj.ts
41
+ var TableObj = class _TableObj {
42
+ IS_TABLE_OBJ = true;
43
+ tableName;
44
+ columns;
45
+ tableInfo = {
46
+ primaryKey: void 0,
47
+ foreignKeys: [],
48
+ dataTypes: {}
49
+ };
50
+ constructor(tableName, columns) {
51
+ this.tableName = tableName;
52
+ this.columns = columns;
53
+ }
54
+ primaryKey(key) {
55
+ this.tableInfo.primaryKey = key.toString();
56
+ return this;
57
+ }
58
+ foreignKey(fromColumn, toTable, toColumn, options) {
59
+ this.tableInfo.foreignKeys.push({
60
+ fromTable: this.tableName,
61
+ fromColumn: fromColumn.toString(),
62
+ toTable: toTable.tableName,
63
+ toColumn: toColumn.toString(),
64
+ onUpdate: options?.onUpdate,
65
+ onDelete: options?.onDelete
66
+ });
67
+ return this;
68
+ }
69
+ dataType(column, type) {
70
+ this.tableInfo.dataTypes[column.toString()] = type;
71
+ return this;
72
+ }
73
+ static create(tableName, columns) {
74
+ return new _TableObj(tableName, columns);
75
+ }
76
+ static isDbTable(obj) {
77
+ return !!obj?.IS_TABLE_OBJ;
78
+ }
79
+ };
80
+
40
81
  // src/lib/TableStructureGenerator.ts
41
82
  var TableStructureGenerator = class {
42
83
  dialect;
@@ -45,19 +86,21 @@ var TableStructureGenerator = class {
45
86
  this.dialect = dialect;
46
87
  this.dbInstructions = dbInstructions;
47
88
  }
89
+ /**
90
+ * Generates the structure of tables based on database instructions.
91
+ *
92
+ * @return An object where keys are table names, and values are their corresponding table structures.
93
+ */
48
94
  generateTableStructure() {
49
- if (this.dbInstructions.tables.length) {
50
- const tableObjects = {};
51
- for (const table of this.dbInstructions.tables) {
52
- tableObjects[table.name] = { columns: new table(), tableInfo: getTableInfo(table) };
95
+ const tableObjects = {};
96
+ for (const table of this.dbInstructions.tables) {
97
+ if (TableObj.isDbTable(table))
98
+ tableObjects[table.tableName] = table;
99
+ else {
100
+ const classTable = table;
101
+ tableObjects[classTable.name] = { columns: new classTable(), tableInfo: getTableInfo(classTable) };
53
102
  }
54
- return this.getExpectedStructure(tableObjects);
55
- } else {
56
- const tableObjects = this.dbInstructions.tables;
57
- return this.getExpectedStructure(tableObjects);
58
103
  }
59
- }
60
- getExpectedStructure(tableObjects) {
61
104
  const tables = {};
62
105
  for (const tableName in tableObjects) {
63
106
  const obj = tableObjects[tableName];
@@ -65,46 +108,49 @@ var TableStructureGenerator = class {
65
108
  tables[tableName] = {
66
109
  table: tableName,
67
110
  primaryKey: tableInfo?.primaryKey,
68
- columns: this.getColumns(obj.columns, tableInfo?.primaryKey),
111
+ columns: this.getColumns(obj.columns, tableInfo),
69
112
  foreignKeys: tableInfo?.foreignKeys
70
113
  };
71
114
  }
72
115
  return tables;
73
116
  }
74
- getColumns(obj, primaryKey) {
117
+ /**
118
+ * Retrieves the columns for a table
119
+ *
120
+ * @param obj - The table class interface object containing properties that represent the table's fields.
121
+ * @param tableInfo - Optional metadata about the table. Can be undefined.
122
+ * @return An array of {@link ColumnInfo} representing the detailed column information.
123
+ */
124
+ getColumns(obj, tableInfo) {
75
125
  const columns = [];
76
126
  for (const property in obj) {
77
127
  const propertyKey = property;
78
128
  const value = obj[propertyKey];
79
129
  const columnData = {
80
130
  name: property,
81
- isPrimaryKey: property == primaryKey,
82
- type: "TEXT",
83
- defaultValue: this.dialect.typeNull
131
+ isPrimaryKey: property == tableInfo?.primaryKey,
132
+ type: this.dialect.types.string,
133
+ defaultValue: this.dialect.types.null
84
134
  };
85
- switch (typeof value) {
86
- case "string":
87
- columnData.type = this.dialect.typeString;
88
- columnData.defaultValue = value === null ? this.dialect.typeNull : `"${this.dialect.formatValueToSql(value)}"`;
89
- break;
90
- case "bigint":
91
- columnData.type = this.dialect.typeBigInt;
92
- columnData.defaultValue = value === null ? this.dialect.typeNull : this.dialect.formatValueToSql(value);
93
- break;
94
- case "number":
95
- columnData.type = this.dialect.typeInt;
96
- columnData.defaultValue = value === null ? this.dialect.typeNull : this.dialect.formatValueToSql(value);
97
- break;
98
- case "boolean":
99
- columnData.type = this.dialect.typeBoolean;
100
- columnData.defaultValue = value === null ? this.dialect.typeNull : this.dialect.formatValueToSql(value);
101
- break;
135
+ let dataType = tableInfo?.dataTypes?.[property] ?? typeof value;
136
+ switch (dataType) {
102
137
  case "function":
103
138
  continue;
104
- default:
105
- Logger.warn(`${obj.constructor.name}.${property} was skipped because its type is not supported (${typeof value})`);
139
+ case "object":
140
+ if (value instanceof Date) {
141
+ dataType = "date";
142
+ break;
143
+ } else {
144
+ Logger.warn(`${property} was skipped because its type (${typeof value}) is not supported`);
145
+ continue;
146
+ }
147
+ case "undefined":
148
+ case "symbol":
149
+ Logger.warn(`${property} was skipped because its type (${typeof value}) is not supported`);
106
150
  continue;
107
151
  }
152
+ columnData.defaultValue = value === null ? this.dialect.types.null : this.dialect.formatValueToSql(value, dataType);
153
+ columnData.type = this.dialect.types[dataType];
108
154
  columns.push(columnData);
109
155
  }
110
156
  return columns;
@@ -114,32 +160,37 @@ var TableStructureGenerator = class {
114
160
  // src/lib/exceptions/NotAllowedException.ts
115
161
  var NotAllowedException = class extends Error {
116
162
  constructor(entries) {
117
- let message = "Some destructive changes need to be confirmed.\n In preMigration() run:\n";
163
+ let message = "Some destructive changes need to be confirmed. In preMigration() run:\n";
118
164
  for (const entry of entries) {
119
- message += ` migrations.allowMigration(${entry.version}, "${entry.tableName}", "${entry.type}");
165
+ message += ` migrations.allowMigration(${entry.version}, ${entry.tableName}, "${entry.type}");
120
166
  `;
121
167
  }
122
168
  super(message);
123
169
  }
124
170
  };
125
171
 
126
- // src/lib/typings/Migrations.ts
172
+ // src/lib/Migrations.ts
127
173
  var Migrations = class {
128
- toVersion = 0;
129
- alwaysAllowed = {};
130
174
  fromVersion = 0;
175
+ toVersion = 0;
176
+ lastUsedVersion = 0;
131
177
  migrationData = {};
132
178
  migrationDataForOldTableNames = {};
179
+ alwaysAllowed = {};
133
180
  notAllowedChanges = [];
134
181
  reset(dbInstructions, fromVersion) {
135
182
  this.fromVersion = fromVersion;
136
- this.migrationData = {};
137
183
  this.toVersion = dbInstructions.version;
184
+ this.migrationData = {};
185
+ this.migrationDataForOldTableNames = {};
138
186
  this.alwaysAllowed = dbInstructions.alwaysAllowedMigrations ?? {};
139
187
  this.notAllowedChanges = [];
140
188
  }
141
189
  getEntry(table) {
142
190
  const tableName = this.getTableName(table);
191
+ return this.getEntryFromTableName(tableName);
192
+ }
193
+ getEntryFromTableName(tableName) {
143
194
  if (!this.migrationData.hasOwnProperty(tableName)) {
144
195
  this.migrationData[tableName] = {
145
196
  recreate: false,
@@ -151,17 +202,27 @@ var Migrations = class {
151
202
  return this.migrationData[tableName];
152
203
  }
153
204
  getTableName(table) {
154
- return typeof table == "string" ? table : table.name;
205
+ return TableObj.isDbTable(table) ? table.tableName : table.name;
206
+ }
207
+ versionIsRelevant(version) {
208
+ if (version < this.fromVersion || version > this.toVersion)
209
+ return false;
210
+ if (version < this.lastUsedVersion)
211
+ throw new Error("Migrations in preMigration() have to be ordered by version (beginning with the lowest version).");
212
+ this.lastUsedVersion = version;
213
+ return true;
155
214
  }
156
215
  verifyRenamingTasks(newTables) {
157
216
  for (const tableName in this.migrationData) {
158
217
  const migrationEntry = this.migrationData[tableName];
159
- if (migrationEntry.tableRenaming?.oldName == tableName)
160
- return new Error(`You set table "${tableName}" to be renamed to itself!`);
161
- if (migrationEntry.tableRenaming && migrationEntry.tableRenaming.newName != tableName)
162
- return new Error(`You set table "${tableName}" to be renamed to a different name than the one in your structure (${migrationEntry.tableRenaming.newName})!`);
163
- else if (!newTables[tableName])
164
- return new Error(`You set table "${migrationEntry.tableRenaming}" migrations for "${tableName}". But "${tableName}" does not exist in your structure.`);
218
+ if (migrationEntry.tableRenaming) {
219
+ if (migrationEntry.tableRenaming.oldName == tableName)
220
+ return new Error(`You set table "${tableName}" to be renamed to itself!`);
221
+ if (migrationEntry.tableRenaming.newName != tableName)
222
+ return new Error(`You set table "${tableName}" to be renamed to a different name than the one in your structure (${migrationEntry.tableRenaming.newName})!`);
223
+ else if (!newTables[tableName])
224
+ return new Error(`You set table "${migrationEntry.tableRenaming}" migrations for "${tableName}". But "${tableName}" does not exist in your structure.`);
225
+ }
165
226
  for (const renamingData of migrationEntry.renamedColumns) {
166
227
  const oldColumnName = renamingData.oldName;
167
228
  const newColumnName = renamingData.newName;
@@ -195,6 +256,33 @@ var Migrations = class {
195
256
  } else if (migrationEntry)
196
257
  migrationEntry.usedMigrations[type] = true;
197
258
  }
259
+ getMigrationData() {
260
+ return this.migrationData;
261
+ }
262
+ loopRenamedColumns(tableName, callback) {
263
+ const migrationEntry = this.migrationData[tableName];
264
+ for (const renamingData of migrationEntry.renamedColumns) {
265
+ callback(renamingData.oldName, renamingData.newName);
266
+ }
267
+ }
268
+ getNewestTableName(tableName) {
269
+ return this.migrationDataForOldTableNames[tableName]?.tableRenaming?.newName ?? tableName;
270
+ }
271
+ getOldTableName(tableName) {
272
+ return this.migrationData[tableName]?.tableRenaming?.oldName ?? tableName;
273
+ }
274
+ getNewestColumnName(tableName, oldColumnName) {
275
+ const columnNames = this.migrationData[tableName]?.renamedColumns.find((columns) => columns.oldName == oldColumnName);
276
+ return columnNames ? columnNames.newName : oldColumnName;
277
+ }
278
+ willBeRecreated(tableName) {
279
+ return this.migrationData[tableName]?.recreate;
280
+ }
281
+ internalRecreate(tableName, reason) {
282
+ const entry = this.getEntryFromTableName(tableName);
283
+ entry.recreate = true;
284
+ Logger.log(`Table ${tableName} will be recreated(${reason})!`);
285
+ }
198
286
  allowMigration(version, table, ...allowedMigrations) {
199
287
  if (version < this.fromVersion || version > this.toVersion)
200
288
  return;
@@ -204,13 +292,9 @@ var Migrations = class {
204
292
  }
205
293
  }
206
294
  renameTable(version, oldTableName, newTableName) {
207
- if (version < this.fromVersion || version > this.toVersion)
295
+ if (!this.versionIsRelevant(version))
208
296
  return;
209
297
  const newTableNameString = this.getTableName(newTableName);
210
- if (this.migrationData.hasOwnProperty(oldTableName)) {
211
- this.migrationData[newTableNameString] = this.getEntry(oldTableName);
212
- delete this.migrationData[oldTableName];
213
- }
214
298
  const entry = this.getEntry(newTableName);
215
299
  this.migrationDataForOldTableNames[oldTableName] = entry;
216
300
  if (!entry.tableRenaming)
@@ -219,7 +303,7 @@ var Migrations = class {
219
303
  entry.tableRenaming.newName = newTableNameString;
220
304
  }
221
305
  renameColumn(version, table, oldColumn, newColumn) {
222
- if (version < this.fromVersion || version > this.toVersion)
306
+ if (!this.versionIsRelevant(version))
223
307
  return;
224
308
  const entry = this.getEntry(table);
225
309
  const existingColumnEntry = entry.renamedColumns.find((entry2) => entry2.newName == oldColumn);
@@ -228,36 +312,12 @@ var Migrations = class {
228
312
  else
229
313
  entry.renamedColumns.push({ oldName: oldColumn, newName: newColumn });
230
314
  }
231
- recreateTableImp(table) {
232
- const entry = this.getEntry(table);
233
- entry.recreate = true;
234
- }
235
315
  recreateTable(version, table) {
236
- if (version < this.fromVersion || version > this.toVersion)
316
+ if (!this.versionIsRelevant(version))
237
317
  return;
238
- this.recreateTableImp(table);
239
- }
240
- getMigrationData() {
241
- return this.migrationData;
242
- }
243
- loopRenamedColumns(tableName, callback) {
244
- const migrationEntry = this.migrationData[tableName];
245
- for (const renamingData of migrationEntry.renamedColumns) {
246
- callback(renamingData.oldName, renamingData.newName);
247
- }
248
- }
249
- getNewestTableName(tableName) {
250
- return this.migrationDataForOldTableNames[tableName]?.tableRenaming?.newName ?? tableName;
251
- }
252
- getOldTableName(tableName) {
253
- return this.migrationData[tableName]?.tableRenaming?.oldName ?? tableName;
254
- }
255
- getNewestColumnName(tableName, oldColumnName) {
256
- const columnNames = this.migrationData[tableName]?.renamedColumns.find((columns) => columns.oldName == oldColumnName);
257
- return columnNames ? columnNames.newName : oldColumnName;
258
- }
259
- willBeRecreated(tableName) {
260
- return this.migrationData[tableName]?.recreate;
318
+ const entry = this.getEntry(table);
319
+ entry.recreate = true;
320
+ Logger.log(`Table ${this.getTableName(table)} will be recreated!`);
261
321
  }
262
322
  };
263
323
 
@@ -474,7 +534,6 @@ ${changes.up}
474
534
  const migrationEntry = migrationData[tableName];
475
535
  if (!migrationEntry.recreate)
476
536
  continue;
477
- Logger.log(`Table ${tableName} will be recreated!`);
478
537
  this.migrations.compareWithAllowedMigration(tableName, "recreateTable");
479
538
  if (!this.dialect.canInspectForeignKeys || !this.dialect.canInspectPrimaryKey)
480
539
  this.migrations.compareWithAllowedMigration(tableName, "continueWithoutRollback");
@@ -521,7 +580,7 @@ ${changes.up}
521
580
  this.dialect.foreignKey(oldForeignKey.fromColumn, oldForeignKey.toTable, oldForeignKey.toColumn, oldForeignKey.onUpdate, oldForeignKey.onDelete)
522
581
  );
523
582
  } else {
524
- this.migrations.recreateTableImp(structure.table);
583
+ this.migrations.internalRecreate(structure.table, "Dialect does not support altering foreign keys");
525
584
  checkForNewForeignKeys = false;
526
585
  }
527
586
  } else {
@@ -538,7 +597,7 @@ ${changes.up}
538
597
  this.dialect.foreignKey(oldForeignKey.fromColumn, oldForeignKey.toTable, oldForeignKey.toColumn, oldForeignKey.onUpdate, oldForeignKey.onDelete)
539
598
  ) + this.dialect.removeForeignKey(newForeignKey.fromTable, newForeignKey.fromColumn);
540
599
  } else {
541
- this.migrations.recreateTableImp(structure.table);
600
+ this.migrations.internalRecreate(structure.table, "Dialect does not support altering foreign keys");
542
601
  checkForNewForeignKeys = false;
543
602
  }
544
603
  }
@@ -557,7 +616,7 @@ ${changes.up}
557
616
  );
558
617
  changes.down += this.dialect.removeForeignKey(newForeignKey.fromTable, newForeignKey.fromColumn);
559
618
  } else {
560
- this.migrations.recreateTableImp(structure.table);
619
+ this.migrations.internalRecreate(structure.table, "Dialect does not support altering foreign keys");
561
620
  break;
562
621
  }
563
622
  }
@@ -595,7 +654,7 @@ ${changes.up}
595
654
  changes.down += this.dialect.removePrimaryKey(tableName, newPrimaryKey.toString());
596
655
  }
597
656
  } else
598
- this.migrations.recreateTableImp(newTableDefinition.table);
657
+ this.migrations.internalRecreate(newTableDefinition.table, "Dialect does not support altering primary keys");
599
658
  continue;
600
659
  }
601
660
  for (const newColumn of newColumnList) {
@@ -606,7 +665,7 @@ ${changes.up}
606
665
  changes.up += this.dialect.createColumn(tableName, this.dialect.columnDefinition(newColumn.name, newColumn.type, newColumn.defaultValue, newColumn.isPrimaryKey)) + "\n";
607
666
  changes.down += this.dialect.dropColumn(tableName, newColumn.name) + "\n";
608
667
  } else if (newColumn.type != oldColumn.type || newColumn.defaultValue != oldColumn.defaultValue) {
609
- this.migrations.recreateTableImp(newTableDefinition.table);
668
+ this.migrations.internalRecreate(newTableDefinition.table, "Table structure was changed");
610
669
  }
611
670
  }
612
671
  for (const oldColumn of oldColumnList) {
@@ -715,24 +774,37 @@ ${changes.down}`, { encoding: "utf-8" });
715
774
  }
716
775
  };
717
776
 
718
- // src/lib/tableInfo/decorators/DbTable.ts
777
+ // src/lib/tableInfo/decorators/TableClass.ts
719
778
  import "polyfill-symbol-metadata";
720
- function DbTable(tableName, primaryKey) {
779
+ function TableClass(tableName, primaryKey) {
721
780
  return (table, context) => {
722
- Object.defineProperty(table, "name", { value: tableName, writable: false });
723
781
  const tableInfo = context?.metadata ? getTableInfoFromMetadata(context.metadata) : getTableInfo(table);
724
782
  tableInfo.primaryKey = primaryKey?.toString();
725
783
  if (tableInfo.foreignKeys) {
726
784
  for (const foreignKey of tableInfo.foreignKeys) {
727
785
  foreignKey.fromTable = tableName;
786
+ if (foreignKey.toTable == table.name)
787
+ foreignKey.toTable = tableName;
728
788
  }
729
789
  }
790
+ Object.defineProperty(table, "name", { value: tableName, writable: false });
791
+ };
792
+ }
793
+
794
+ // src/lib/tableInfo/decorators/DataType.ts
795
+ import "polyfill-symbol-metadata";
796
+ function DataType(type) {
797
+ return (table, context) => {
798
+ const metadata = context?.metadata ? getTableInfoFromMetadata(context.metadata) : getTableInfo(table);
799
+ if (!metadata.dataTypes)
800
+ metadata.dataTypes = {};
801
+ metadata.dataTypes[context.name ?? context] = type;
730
802
  };
731
803
  }
732
804
 
733
805
  // src/lib/tableInfo/decorators/ForeignKey.ts
734
806
  import "polyfill-symbol-metadata";
735
- function ForeignKey(toTable, toColumn, onDelete, onUpdate) {
807
+ function ForeignKey(toTable, toColumn, options) {
736
808
  return (table, context) => {
737
809
  const metadata = context?.metadata ? getTableInfoFromMetadata(context.metadata) : getTableInfo(table);
738
810
  if (!metadata.foreignKeys)
@@ -743,8 +815,8 @@ function ForeignKey(toTable, toColumn, onDelete, onUpdate) {
743
815
  //to stay compatible with old decorator structure (see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#decorator-metadata)
744
816
  toTable: toTable.name,
745
817
  toColumn: toColumn.toString(),
746
- onDelete,
747
- onUpdate
818
+ onDelete: options?.onDelete,
819
+ onUpdate: options?.onUpdate
748
820
  });
749
821
  };
750
822
  }
@@ -757,32 +829,108 @@ var DefaultSql = class {
757
829
  canAlterPrimaryKey = false;
758
830
  canInspectForeignKeys = false;
759
831
  canInspectPrimaryKey = false;
760
- typeString = "TEXT";
761
- typeInt = "INTEGER";
762
- typeBigInt = "BIGINT";
763
- typeBoolean = "BOOLEAN";
764
- typeNull = "NULL";
832
+ types = {
833
+ string: "TEXT",
834
+ number: "INTEGER",
835
+ bigint: "BIGINT",
836
+ boolean: "BOOLEAN",
837
+ date: "DATE",
838
+ time: "TIME",
839
+ dateTime: "DATETIME",
840
+ null: "NULL"
841
+ };
765
842
  constructor(db) {
766
843
  this.db = db;
767
844
  }
768
- formatValueToSql(value) {
769
- return value.toString();
845
+ /**
846
+ * Formats a given value to a SQL-equivalent string based on the provided data type.
847
+ *
848
+ * @param value - The value to be formatted.
849
+ * @param type - The data type of the value. Either determined through typeof or {@link TableInfo} setting
850
+ * @return A string representation of the value formatted for SQL.
851
+ */
852
+ formatValueToSql(value, type) {
853
+ function toDate(value2) {
854
+ return value2 instanceof Date ? value2 : new Date(value2);
855
+ }
856
+ switch (type) {
857
+ case "string":
858
+ return `"${value}"`;
859
+ case "time":
860
+ return toDate(value).toISOString().slice(11, 19);
861
+ case "date":
862
+ return toDate(value).toISOString().slice(0, 10);
863
+ case "dateTime":
864
+ return toDate(value).toISOString().slice(0, 19).replace("T", " ");
865
+ default:
866
+ return value.toString();
867
+ }
770
868
  }
869
+ /**
870
+ * Query to enable / disable foreign keys in the database.
871
+ * Is dialect specific.
872
+ *
873
+ * @param enabled - A boolean indicating whether to enable or disable foreign key constraints.
874
+ * @return The query
875
+ */
771
876
  changeForeignKeysState(enabled) {
772
877
  return "";
773
878
  }
879
+ /**
880
+ * Query to add a foreign key to a specified table.
881
+ * Is only used if {@link canAlterForeignKeys} is true.
882
+ *
883
+ * @param fromTableName - The name of the table to which the foreign key will be added.
884
+ * @param foreignKey - The foreign key definition to be added, see {@link foreignKey()}.
885
+ * @return The SQL statement that adds the foreign key to the specified table.
886
+ */
774
887
  addForeignKey(fromTableName, foreignKey) {
775
888
  throw new Error("Adding foreign keys is not supported!");
776
889
  }
890
+ /**
891
+ * Query to remove a foreign key from a specified table.
892
+ * Is only used if {@link canAlterForeignKeys} is true.
893
+ *
894
+ * @param tableName - The name of the table to which the foreign key will be added.
895
+ * @param foreignKeyName - The name of the foreign key definition.
896
+ * @return The SQL statement that removes the foreign key from the specified table.
897
+ */
777
898
  removeForeignKey(tableName, foreignKeyName) {
778
899
  throw new Error("Foreign key removal is not supported!");
779
900
  }
901
+ /**
902
+ * Query to add a primary key to the specified table.
903
+ * Is only used if {@link canAlterPrimaryKey} is true.
904
+ *
905
+ * @param tableName - The name of the table to which the primary key will be added.
906
+ * @param columnName - The name of the column that will be set as the primary key.
907
+ * @return A SQL statement to add a primary key to the specified table and column.
908
+ */
780
909
  addPrimaryKey(tableName, columnName) {
781
910
  throw new Error("Adding foreign keys is not supported!");
782
911
  }
912
+ /**
913
+ * Query to remove a primary key from the specified table.
914
+ * Is only used if {@link canAlterPrimaryKey} is true.
915
+ *
916
+ * @param tableName - The name of the table to which the primary key will be added.
917
+ * @param columnName - The name of the column that will be set as the primary key.
918
+ * @return A SQL statement to remove a primary key from the specified table and column.
919
+ */
783
920
  removePrimaryKey(tableName, columnName) {
784
921
  throw new Error("Foreign key removal is not supported!");
785
922
  }
923
+ /**
924
+ * Constructs a SQL FOREIGN KEY constraint clause.
925
+ * Used in combination with {@link addForeignKey} or {@link createTable}
926
+ *
927
+ * @param column - The name of the column in the current table to apply the foreign key constraint.
928
+ * @param foreignTable - The name of the referenced table.
929
+ * @param foreignColumn - The name of the referenced column in the foreign table.
930
+ * @param onUpdate - Optional action to specify the behavior on update (e.g., CASCADE, SET NULL).
931
+ * @param onDelete - Optional action to specify the behavior on delete (e.g., CASCADE, SET NULL).
932
+ * @return The SQL string representing the foreign key constraint.
933
+ */
786
934
  foreignKey(column, foreignTable, foreignColumn, onUpdate, onDelete) {
787
935
  let query = `FOREIGN KEY (${column}) REFERENCES ${foreignTable} (${foreignColumn})`;
788
936
  if (onUpdate)
@@ -832,7 +980,7 @@ var DefaultSql = class {
832
980
  }
833
981
  migrationTableQuery() {
834
982
  return this.createTable(MIGRATION_DATA_TABLE_NAME, [
835
- this.columnDefinition("version", this.typeInt, "0", false)
983
+ this.columnDefinition("version", this.types.number, "0", false)
836
984
  ]);
837
985
  }
838
986
  async getForeignKeys(tableName) {
@@ -861,8 +1009,16 @@ UPDATE ${MIGRATION_DATA_TABLE_NAME} SET version = ${newVersion} WHERE EXISTS (SE
861
1009
 
862
1010
  // src/lib/dialects/SqliteDialect.ts
863
1011
  var SqliteDialect = class extends DefaultSql {
864
- typeBoolean = "INTEGER";
865
- typeBigInt = "INTEGER";
1012
+ types = {
1013
+ string: "TEXT",
1014
+ number: "INTEGER",
1015
+ bigint: "INTEGER",
1016
+ boolean: "INTEGER",
1017
+ date: "DATE",
1018
+ time: "TIME",
1019
+ dateTime: "DATETIME",
1020
+ null: "NULL"
1021
+ };
866
1022
  canAlterForeignKeys = false;
867
1023
  canAlterPrimaryKey = false;
868
1024
  canInspectForeignKeys = true;
@@ -884,12 +1040,19 @@ var SqliteDialect = class extends DefaultSql {
884
1040
  };
885
1041
  });
886
1042
  }
887
- formatValueToSql(value) {
888
- switch (typeof value) {
1043
+ formatValueToSql(value, type) {
1044
+ function toDate(value2) {
1045
+ return value2 instanceof Date ? value2 : new Date(value2);
1046
+ }
1047
+ switch (type) {
889
1048
  case "boolean":
890
1049
  return value ? "1" : "0";
1050
+ case "date":
1051
+ case "time":
1052
+ case "dateTime":
1053
+ return toDate(value).getTime().toString();
891
1054
  default:
892
- return value.toString();
1055
+ return super.formatValueToSql(value, type);
893
1056
  }
894
1057
  }
895
1058
  async getForeignKeys(tableName) {
@@ -1126,8 +1289,10 @@ async function rollback(db, dbInstructions, toVersion) {
1126
1289
  await dialect.setVersion(toVersion);
1127
1290
  }
1128
1291
  export {
1129
- DbTable,
1292
+ DataType,
1130
1293
  ForeignKey,
1294
+ TableClass,
1295
+ TableObj,
1131
1296
  prepareAndRunMigration,
1132
1297
  prepareMigration,
1133
1298
  rollback,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sqlmorpheus",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "author": "JodliDev",
5
5
  "keywords": [],
6
6
  "license": "MIT",