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.d.mts +60 -23
- package/dist/index.d.ts +60 -23
- package/dist/index.js +276 -109
- package/dist/index.mjs +272 -107
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20,8 +20,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
|
|
23
|
+
DataType: () => DataType,
|
|
24
24
|
ForeignKey: () => ForeignKey,
|
|
25
|
+
TableClass: () => TableClass,
|
|
26
|
+
TableObj: () => TableObj,
|
|
25
27
|
prepareAndRunMigration: () => prepareAndRunMigration,
|
|
26
28
|
prepareMigration: () => prepareMigration,
|
|
27
29
|
rollback: () => rollback,
|
|
@@ -69,6 +71,47 @@ function getTableInfoFromMetadata(metadata) {
|
|
|
69
71
|
return metadata[TABLE_INFO_PROPERTY_NAME];
|
|
70
72
|
}
|
|
71
73
|
|
|
74
|
+
// src/lib/tableInfo/TableObj.ts
|
|
75
|
+
var TableObj = class _TableObj {
|
|
76
|
+
IS_TABLE_OBJ = true;
|
|
77
|
+
tableName;
|
|
78
|
+
columns;
|
|
79
|
+
tableInfo = {
|
|
80
|
+
primaryKey: void 0,
|
|
81
|
+
foreignKeys: [],
|
|
82
|
+
dataTypes: {}
|
|
83
|
+
};
|
|
84
|
+
constructor(tableName, columns) {
|
|
85
|
+
this.tableName = tableName;
|
|
86
|
+
this.columns = columns;
|
|
87
|
+
}
|
|
88
|
+
primaryKey(key) {
|
|
89
|
+
this.tableInfo.primaryKey = key.toString();
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
foreignKey(fromColumn, toTable, toColumn, options) {
|
|
93
|
+
this.tableInfo.foreignKeys.push({
|
|
94
|
+
fromTable: this.tableName,
|
|
95
|
+
fromColumn: fromColumn.toString(),
|
|
96
|
+
toTable: toTable.tableName,
|
|
97
|
+
toColumn: toColumn.toString(),
|
|
98
|
+
onUpdate: options?.onUpdate,
|
|
99
|
+
onDelete: options?.onDelete
|
|
100
|
+
});
|
|
101
|
+
return this;
|
|
102
|
+
}
|
|
103
|
+
dataType(column, type) {
|
|
104
|
+
this.tableInfo.dataTypes[column.toString()] = type;
|
|
105
|
+
return this;
|
|
106
|
+
}
|
|
107
|
+
static create(tableName, columns) {
|
|
108
|
+
return new _TableObj(tableName, columns);
|
|
109
|
+
}
|
|
110
|
+
static isDbTable(obj) {
|
|
111
|
+
return !!obj?.IS_TABLE_OBJ;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
72
115
|
// src/lib/TableStructureGenerator.ts
|
|
73
116
|
var TableStructureGenerator = class {
|
|
74
117
|
dialect;
|
|
@@ -77,19 +120,21 @@ var TableStructureGenerator = class {
|
|
|
77
120
|
this.dialect = dialect;
|
|
78
121
|
this.dbInstructions = dbInstructions;
|
|
79
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Generates the structure of tables based on database instructions.
|
|
125
|
+
*
|
|
126
|
+
* @return An object where keys are table names, and values are their corresponding table structures.
|
|
127
|
+
*/
|
|
80
128
|
generateTableStructure() {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
tableObjects[table.
|
|
129
|
+
const tableObjects = {};
|
|
130
|
+
for (const table of this.dbInstructions.tables) {
|
|
131
|
+
if (TableObj.isDbTable(table))
|
|
132
|
+
tableObjects[table.tableName] = table;
|
|
133
|
+
else {
|
|
134
|
+
const classTable = table;
|
|
135
|
+
tableObjects[classTable.name] = { columns: new classTable(), tableInfo: getTableInfo(classTable) };
|
|
85
136
|
}
|
|
86
|
-
return this.getExpectedStructure(tableObjects);
|
|
87
|
-
} else {
|
|
88
|
-
const tableObjects = this.dbInstructions.tables;
|
|
89
|
-
return this.getExpectedStructure(tableObjects);
|
|
90
137
|
}
|
|
91
|
-
}
|
|
92
|
-
getExpectedStructure(tableObjects) {
|
|
93
138
|
const tables = {};
|
|
94
139
|
for (const tableName in tableObjects) {
|
|
95
140
|
const obj = tableObjects[tableName];
|
|
@@ -97,46 +142,49 @@ var TableStructureGenerator = class {
|
|
|
97
142
|
tables[tableName] = {
|
|
98
143
|
table: tableName,
|
|
99
144
|
primaryKey: tableInfo?.primaryKey,
|
|
100
|
-
columns: this.getColumns(obj.columns, tableInfo
|
|
145
|
+
columns: this.getColumns(obj.columns, tableInfo),
|
|
101
146
|
foreignKeys: tableInfo?.foreignKeys
|
|
102
147
|
};
|
|
103
148
|
}
|
|
104
149
|
return tables;
|
|
105
150
|
}
|
|
106
|
-
|
|
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) {
|
|
107
159
|
const columns = [];
|
|
108
160
|
for (const property in obj) {
|
|
109
161
|
const propertyKey = property;
|
|
110
162
|
const value = obj[propertyKey];
|
|
111
163
|
const columnData = {
|
|
112
164
|
name: property,
|
|
113
|
-
isPrimaryKey: property == primaryKey,
|
|
114
|
-
type:
|
|
115
|
-
defaultValue: this.dialect.
|
|
165
|
+
isPrimaryKey: property == tableInfo?.primaryKey,
|
|
166
|
+
type: this.dialect.types.string,
|
|
167
|
+
defaultValue: this.dialect.types.null
|
|
116
168
|
};
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
columnData.type = this.dialect.typeString;
|
|
120
|
-
columnData.defaultValue = value === null ? this.dialect.typeNull : `"${this.dialect.formatValueToSql(value)}"`;
|
|
121
|
-
break;
|
|
122
|
-
case "bigint":
|
|
123
|
-
columnData.type = this.dialect.typeBigInt;
|
|
124
|
-
columnData.defaultValue = value === null ? this.dialect.typeNull : this.dialect.formatValueToSql(value);
|
|
125
|
-
break;
|
|
126
|
-
case "number":
|
|
127
|
-
columnData.type = this.dialect.typeInt;
|
|
128
|
-
columnData.defaultValue = value === null ? this.dialect.typeNull : this.dialect.formatValueToSql(value);
|
|
129
|
-
break;
|
|
130
|
-
case "boolean":
|
|
131
|
-
columnData.type = this.dialect.typeBoolean;
|
|
132
|
-
columnData.defaultValue = value === null ? this.dialect.typeNull : this.dialect.formatValueToSql(value);
|
|
133
|
-
break;
|
|
169
|
+
let dataType = tableInfo?.dataTypes?.[property] ?? typeof value;
|
|
170
|
+
switch (dataType) {
|
|
134
171
|
case "function":
|
|
135
172
|
continue;
|
|
136
|
-
|
|
137
|
-
|
|
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`);
|
|
138
184
|
continue;
|
|
139
185
|
}
|
|
186
|
+
columnData.defaultValue = value === null ? this.dialect.types.null : this.dialect.formatValueToSql(value, dataType);
|
|
187
|
+
columnData.type = this.dialect.types[dataType];
|
|
140
188
|
columns.push(columnData);
|
|
141
189
|
}
|
|
142
190
|
return columns;
|
|
@@ -146,32 +194,37 @@ var TableStructureGenerator = class {
|
|
|
146
194
|
// src/lib/exceptions/NotAllowedException.ts
|
|
147
195
|
var NotAllowedException = class extends Error {
|
|
148
196
|
constructor(entries) {
|
|
149
|
-
let message = "Some destructive changes need to be confirmed
|
|
197
|
+
let message = "Some destructive changes need to be confirmed. In preMigration() run:\n";
|
|
150
198
|
for (const entry of entries) {
|
|
151
|
-
message += ` migrations.allowMigration(${entry.version},
|
|
199
|
+
message += ` migrations.allowMigration(${entry.version}, ${entry.tableName}, "${entry.type}");
|
|
152
200
|
`;
|
|
153
201
|
}
|
|
154
202
|
super(message);
|
|
155
203
|
}
|
|
156
204
|
};
|
|
157
205
|
|
|
158
|
-
// src/lib/
|
|
206
|
+
// src/lib/Migrations.ts
|
|
159
207
|
var Migrations = class {
|
|
160
|
-
toVersion = 0;
|
|
161
|
-
alwaysAllowed = {};
|
|
162
208
|
fromVersion = 0;
|
|
209
|
+
toVersion = 0;
|
|
210
|
+
lastUsedVersion = 0;
|
|
163
211
|
migrationData = {};
|
|
164
212
|
migrationDataForOldTableNames = {};
|
|
213
|
+
alwaysAllowed = {};
|
|
165
214
|
notAllowedChanges = [];
|
|
166
215
|
reset(dbInstructions, fromVersion) {
|
|
167
216
|
this.fromVersion = fromVersion;
|
|
168
|
-
this.migrationData = {};
|
|
169
217
|
this.toVersion = dbInstructions.version;
|
|
218
|
+
this.migrationData = {};
|
|
219
|
+
this.migrationDataForOldTableNames = {};
|
|
170
220
|
this.alwaysAllowed = dbInstructions.alwaysAllowedMigrations ?? {};
|
|
171
221
|
this.notAllowedChanges = [];
|
|
172
222
|
}
|
|
173
223
|
getEntry(table) {
|
|
174
224
|
const tableName = this.getTableName(table);
|
|
225
|
+
return this.getEntryFromTableName(tableName);
|
|
226
|
+
}
|
|
227
|
+
getEntryFromTableName(tableName) {
|
|
175
228
|
if (!this.migrationData.hasOwnProperty(tableName)) {
|
|
176
229
|
this.migrationData[tableName] = {
|
|
177
230
|
recreate: false,
|
|
@@ -183,17 +236,27 @@ var Migrations = class {
|
|
|
183
236
|
return this.migrationData[tableName];
|
|
184
237
|
}
|
|
185
238
|
getTableName(table) {
|
|
186
|
-
return
|
|
239
|
+
return TableObj.isDbTable(table) ? table.tableName : table.name;
|
|
240
|
+
}
|
|
241
|
+
versionIsRelevant(version) {
|
|
242
|
+
if (version < this.fromVersion || version > this.toVersion)
|
|
243
|
+
return false;
|
|
244
|
+
if (version < this.lastUsedVersion)
|
|
245
|
+
throw new Error("Migrations in preMigration() have to be ordered by version (beginning with the lowest version).");
|
|
246
|
+
this.lastUsedVersion = version;
|
|
247
|
+
return true;
|
|
187
248
|
}
|
|
188
249
|
verifyRenamingTasks(newTables) {
|
|
189
250
|
for (const tableName in this.migrationData) {
|
|
190
251
|
const migrationEntry = this.migrationData[tableName];
|
|
191
|
-
if (migrationEntry.tableRenaming
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
252
|
+
if (migrationEntry.tableRenaming) {
|
|
253
|
+
if (migrationEntry.tableRenaming.oldName == tableName)
|
|
254
|
+
return new Error(`You set table "${tableName}" to be renamed to itself!`);
|
|
255
|
+
if (migrationEntry.tableRenaming.newName != tableName)
|
|
256
|
+
return new Error(`You set table "${tableName}" to be renamed to a different name than the one in your structure (${migrationEntry.tableRenaming.newName})!`);
|
|
257
|
+
else if (!newTables[tableName])
|
|
258
|
+
return new Error(`You set table "${migrationEntry.tableRenaming}" migrations for "${tableName}". But "${tableName}" does not exist in your structure.`);
|
|
259
|
+
}
|
|
197
260
|
for (const renamingData of migrationEntry.renamedColumns) {
|
|
198
261
|
const oldColumnName = renamingData.oldName;
|
|
199
262
|
const newColumnName = renamingData.newName;
|
|
@@ -227,6 +290,33 @@ var Migrations = class {
|
|
|
227
290
|
} else if (migrationEntry)
|
|
228
291
|
migrationEntry.usedMigrations[type] = true;
|
|
229
292
|
}
|
|
293
|
+
getMigrationData() {
|
|
294
|
+
return this.migrationData;
|
|
295
|
+
}
|
|
296
|
+
loopRenamedColumns(tableName, callback) {
|
|
297
|
+
const migrationEntry = this.migrationData[tableName];
|
|
298
|
+
for (const renamingData of migrationEntry.renamedColumns) {
|
|
299
|
+
callback(renamingData.oldName, renamingData.newName);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
getNewestTableName(tableName) {
|
|
303
|
+
return this.migrationDataForOldTableNames[tableName]?.tableRenaming?.newName ?? tableName;
|
|
304
|
+
}
|
|
305
|
+
getOldTableName(tableName) {
|
|
306
|
+
return this.migrationData[tableName]?.tableRenaming?.oldName ?? tableName;
|
|
307
|
+
}
|
|
308
|
+
getNewestColumnName(tableName, oldColumnName) {
|
|
309
|
+
const columnNames = this.migrationData[tableName]?.renamedColumns.find((columns) => columns.oldName == oldColumnName);
|
|
310
|
+
return columnNames ? columnNames.newName : oldColumnName;
|
|
311
|
+
}
|
|
312
|
+
willBeRecreated(tableName) {
|
|
313
|
+
return this.migrationData[tableName]?.recreate;
|
|
314
|
+
}
|
|
315
|
+
internalRecreate(tableName, reason) {
|
|
316
|
+
const entry = this.getEntryFromTableName(tableName);
|
|
317
|
+
entry.recreate = true;
|
|
318
|
+
Logger.log(`Table ${tableName} will be recreated(${reason})!`);
|
|
319
|
+
}
|
|
230
320
|
allowMigration(version, table, ...allowedMigrations) {
|
|
231
321
|
if (version < this.fromVersion || version > this.toVersion)
|
|
232
322
|
return;
|
|
@@ -236,13 +326,9 @@ var Migrations = class {
|
|
|
236
326
|
}
|
|
237
327
|
}
|
|
238
328
|
renameTable(version, oldTableName, newTableName) {
|
|
239
|
-
if (
|
|
329
|
+
if (!this.versionIsRelevant(version))
|
|
240
330
|
return;
|
|
241
331
|
const newTableNameString = this.getTableName(newTableName);
|
|
242
|
-
if (this.migrationData.hasOwnProperty(oldTableName)) {
|
|
243
|
-
this.migrationData[newTableNameString] = this.getEntry(oldTableName);
|
|
244
|
-
delete this.migrationData[oldTableName];
|
|
245
|
-
}
|
|
246
332
|
const entry = this.getEntry(newTableName);
|
|
247
333
|
this.migrationDataForOldTableNames[oldTableName] = entry;
|
|
248
334
|
if (!entry.tableRenaming)
|
|
@@ -251,7 +337,7 @@ var Migrations = class {
|
|
|
251
337
|
entry.tableRenaming.newName = newTableNameString;
|
|
252
338
|
}
|
|
253
339
|
renameColumn(version, table, oldColumn, newColumn) {
|
|
254
|
-
if (
|
|
340
|
+
if (!this.versionIsRelevant(version))
|
|
255
341
|
return;
|
|
256
342
|
const entry = this.getEntry(table);
|
|
257
343
|
const existingColumnEntry = entry.renamedColumns.find((entry2) => entry2.newName == oldColumn);
|
|
@@ -260,36 +346,12 @@ var Migrations = class {
|
|
|
260
346
|
else
|
|
261
347
|
entry.renamedColumns.push({ oldName: oldColumn, newName: newColumn });
|
|
262
348
|
}
|
|
263
|
-
recreateTableImp(table) {
|
|
264
|
-
const entry = this.getEntry(table);
|
|
265
|
-
entry.recreate = true;
|
|
266
|
-
}
|
|
267
349
|
recreateTable(version, table) {
|
|
268
|
-
if (
|
|
350
|
+
if (!this.versionIsRelevant(version))
|
|
269
351
|
return;
|
|
270
|
-
this.
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
return this.migrationData;
|
|
274
|
-
}
|
|
275
|
-
loopRenamedColumns(tableName, callback) {
|
|
276
|
-
const migrationEntry = this.migrationData[tableName];
|
|
277
|
-
for (const renamingData of migrationEntry.renamedColumns) {
|
|
278
|
-
callback(renamingData.oldName, renamingData.newName);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
getNewestTableName(tableName) {
|
|
282
|
-
return this.migrationDataForOldTableNames[tableName]?.tableRenaming?.newName ?? tableName;
|
|
283
|
-
}
|
|
284
|
-
getOldTableName(tableName) {
|
|
285
|
-
return this.migrationData[tableName]?.tableRenaming?.oldName ?? tableName;
|
|
286
|
-
}
|
|
287
|
-
getNewestColumnName(tableName, oldColumnName) {
|
|
288
|
-
const columnNames = this.migrationData[tableName]?.renamedColumns.find((columns) => columns.oldName == oldColumnName);
|
|
289
|
-
return columnNames ? columnNames.newName : oldColumnName;
|
|
290
|
-
}
|
|
291
|
-
willBeRecreated(tableName) {
|
|
292
|
-
return this.migrationData[tableName]?.recreate;
|
|
352
|
+
const entry = this.getEntry(table);
|
|
353
|
+
entry.recreate = true;
|
|
354
|
+
Logger.log(`Table ${this.getTableName(table)} will be recreated!`);
|
|
293
355
|
}
|
|
294
356
|
};
|
|
295
357
|
|
|
@@ -506,7 +568,6 @@ ${changes.up}
|
|
|
506
568
|
const migrationEntry = migrationData[tableName];
|
|
507
569
|
if (!migrationEntry.recreate)
|
|
508
570
|
continue;
|
|
509
|
-
Logger.log(`Table ${tableName} will be recreated!`);
|
|
510
571
|
this.migrations.compareWithAllowedMigration(tableName, "recreateTable");
|
|
511
572
|
if (!this.dialect.canInspectForeignKeys || !this.dialect.canInspectPrimaryKey)
|
|
512
573
|
this.migrations.compareWithAllowedMigration(tableName, "continueWithoutRollback");
|
|
@@ -553,7 +614,7 @@ ${changes.up}
|
|
|
553
614
|
this.dialect.foreignKey(oldForeignKey.fromColumn, oldForeignKey.toTable, oldForeignKey.toColumn, oldForeignKey.onUpdate, oldForeignKey.onDelete)
|
|
554
615
|
);
|
|
555
616
|
} else {
|
|
556
|
-
this.migrations.
|
|
617
|
+
this.migrations.internalRecreate(structure.table, "Dialect does not support altering foreign keys");
|
|
557
618
|
checkForNewForeignKeys = false;
|
|
558
619
|
}
|
|
559
620
|
} else {
|
|
@@ -570,7 +631,7 @@ ${changes.up}
|
|
|
570
631
|
this.dialect.foreignKey(oldForeignKey.fromColumn, oldForeignKey.toTable, oldForeignKey.toColumn, oldForeignKey.onUpdate, oldForeignKey.onDelete)
|
|
571
632
|
) + this.dialect.removeForeignKey(newForeignKey.fromTable, newForeignKey.fromColumn);
|
|
572
633
|
} else {
|
|
573
|
-
this.migrations.
|
|
634
|
+
this.migrations.internalRecreate(structure.table, "Dialect does not support altering foreign keys");
|
|
574
635
|
checkForNewForeignKeys = false;
|
|
575
636
|
}
|
|
576
637
|
}
|
|
@@ -589,7 +650,7 @@ ${changes.up}
|
|
|
589
650
|
);
|
|
590
651
|
changes.down += this.dialect.removeForeignKey(newForeignKey.fromTable, newForeignKey.fromColumn);
|
|
591
652
|
} else {
|
|
592
|
-
this.migrations.
|
|
653
|
+
this.migrations.internalRecreate(structure.table, "Dialect does not support altering foreign keys");
|
|
593
654
|
break;
|
|
594
655
|
}
|
|
595
656
|
}
|
|
@@ -627,7 +688,7 @@ ${changes.up}
|
|
|
627
688
|
changes.down += this.dialect.removePrimaryKey(tableName, newPrimaryKey.toString());
|
|
628
689
|
}
|
|
629
690
|
} else
|
|
630
|
-
this.migrations.
|
|
691
|
+
this.migrations.internalRecreate(newTableDefinition.table, "Dialect does not support altering primary keys");
|
|
631
692
|
continue;
|
|
632
693
|
}
|
|
633
694
|
for (const newColumn of newColumnList) {
|
|
@@ -638,7 +699,7 @@ ${changes.up}
|
|
|
638
699
|
changes.up += this.dialect.createColumn(tableName, this.dialect.columnDefinition(newColumn.name, newColumn.type, newColumn.defaultValue, newColumn.isPrimaryKey)) + "\n";
|
|
639
700
|
changes.down += this.dialect.dropColumn(tableName, newColumn.name) + "\n";
|
|
640
701
|
} else if (newColumn.type != oldColumn.type || newColumn.defaultValue != oldColumn.defaultValue) {
|
|
641
|
-
this.migrations.
|
|
702
|
+
this.migrations.internalRecreate(newTableDefinition.table, "Table structure was changed");
|
|
642
703
|
}
|
|
643
704
|
}
|
|
644
705
|
for (const oldColumn of oldColumnList) {
|
|
@@ -747,24 +808,37 @@ ${changes.down}`, { encoding: "utf-8" });
|
|
|
747
808
|
}
|
|
748
809
|
};
|
|
749
810
|
|
|
750
|
-
// src/lib/tableInfo/decorators/
|
|
811
|
+
// src/lib/tableInfo/decorators/TableClass.ts
|
|
751
812
|
var import_polyfill_symbol_metadata = require("polyfill-symbol-metadata");
|
|
752
|
-
function
|
|
813
|
+
function TableClass(tableName, primaryKey) {
|
|
753
814
|
return (table, context) => {
|
|
754
|
-
Object.defineProperty(table, "name", { value: tableName, writable: false });
|
|
755
815
|
const tableInfo = context?.metadata ? getTableInfoFromMetadata(context.metadata) : getTableInfo(table);
|
|
756
816
|
tableInfo.primaryKey = primaryKey?.toString();
|
|
757
817
|
if (tableInfo.foreignKeys) {
|
|
758
818
|
for (const foreignKey of tableInfo.foreignKeys) {
|
|
759
819
|
foreignKey.fromTable = tableName;
|
|
820
|
+
if (foreignKey.toTable == table.name)
|
|
821
|
+
foreignKey.toTable = tableName;
|
|
760
822
|
}
|
|
761
823
|
}
|
|
824
|
+
Object.defineProperty(table, "name", { value: tableName, writable: false });
|
|
762
825
|
};
|
|
763
826
|
}
|
|
764
827
|
|
|
765
|
-
// src/lib/tableInfo/decorators/
|
|
828
|
+
// src/lib/tableInfo/decorators/DataType.ts
|
|
766
829
|
var import_polyfill_symbol_metadata2 = require("polyfill-symbol-metadata");
|
|
767
|
-
function
|
|
830
|
+
function DataType(type) {
|
|
831
|
+
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;
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
// src/lib/tableInfo/decorators/ForeignKey.ts
|
|
840
|
+
var import_polyfill_symbol_metadata3 = require("polyfill-symbol-metadata");
|
|
841
|
+
function ForeignKey(toTable, toColumn, options) {
|
|
768
842
|
return (table, context) => {
|
|
769
843
|
const metadata = context?.metadata ? getTableInfoFromMetadata(context.metadata) : getTableInfo(table);
|
|
770
844
|
if (!metadata.foreignKeys)
|
|
@@ -775,8 +849,8 @@ function ForeignKey(toTable, toColumn, onDelete, onUpdate) {
|
|
|
775
849
|
//to stay compatible with old decorator structure (see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#decorator-metadata)
|
|
776
850
|
toTable: toTable.name,
|
|
777
851
|
toColumn: toColumn.toString(),
|
|
778
|
-
onDelete,
|
|
779
|
-
onUpdate
|
|
852
|
+
onDelete: options?.onDelete,
|
|
853
|
+
onUpdate: options?.onUpdate
|
|
780
854
|
});
|
|
781
855
|
};
|
|
782
856
|
}
|
|
@@ -789,32 +863,108 @@ var DefaultSql = class {
|
|
|
789
863
|
canAlterPrimaryKey = false;
|
|
790
864
|
canInspectForeignKeys = false;
|
|
791
865
|
canInspectPrimaryKey = false;
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
866
|
+
types = {
|
|
867
|
+
string: "TEXT",
|
|
868
|
+
number: "INTEGER",
|
|
869
|
+
bigint: "BIGINT",
|
|
870
|
+
boolean: "BOOLEAN",
|
|
871
|
+
date: "DATE",
|
|
872
|
+
time: "TIME",
|
|
873
|
+
dateTime: "DATETIME",
|
|
874
|
+
null: "NULL"
|
|
875
|
+
};
|
|
797
876
|
constructor(db) {
|
|
798
877
|
this.db = db;
|
|
799
878
|
}
|
|
800
|
-
|
|
801
|
-
|
|
879
|
+
/**
|
|
880
|
+
* Formats a given value to a SQL-equivalent string based on the provided data type.
|
|
881
|
+
*
|
|
882
|
+
* @param value - The value to be formatted.
|
|
883
|
+
* @param type - The data type of the value. Either determined through typeof or {@link TableInfo} setting
|
|
884
|
+
* @return A string representation of the value formatted for SQL.
|
|
885
|
+
*/
|
|
886
|
+
formatValueToSql(value, type) {
|
|
887
|
+
function toDate(value2) {
|
|
888
|
+
return value2 instanceof Date ? value2 : new Date(value2);
|
|
889
|
+
}
|
|
890
|
+
switch (type) {
|
|
891
|
+
case "string":
|
|
892
|
+
return `"${value}"`;
|
|
893
|
+
case "time":
|
|
894
|
+
return toDate(value).toISOString().slice(11, 19);
|
|
895
|
+
case "date":
|
|
896
|
+
return toDate(value).toISOString().slice(0, 10);
|
|
897
|
+
case "dateTime":
|
|
898
|
+
return toDate(value).toISOString().slice(0, 19).replace("T", " ");
|
|
899
|
+
default:
|
|
900
|
+
return value.toString();
|
|
901
|
+
}
|
|
802
902
|
}
|
|
903
|
+
/**
|
|
904
|
+
* Query to enable / disable foreign keys in the database.
|
|
905
|
+
* Is dialect specific.
|
|
906
|
+
*
|
|
907
|
+
* @param enabled - A boolean indicating whether to enable or disable foreign key constraints.
|
|
908
|
+
* @return The query
|
|
909
|
+
*/
|
|
803
910
|
changeForeignKeysState(enabled) {
|
|
804
911
|
return "";
|
|
805
912
|
}
|
|
913
|
+
/**
|
|
914
|
+
* Query to add a foreign key to a specified table.
|
|
915
|
+
* Is only used if {@link canAlterForeignKeys} is true.
|
|
916
|
+
*
|
|
917
|
+
* @param fromTableName - The name of the table to which the foreign key will be added.
|
|
918
|
+
* @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.
|
|
920
|
+
*/
|
|
806
921
|
addForeignKey(fromTableName, foreignKey) {
|
|
807
922
|
throw new Error("Adding foreign keys is not supported!");
|
|
808
923
|
}
|
|
924
|
+
/**
|
|
925
|
+
* Query to remove a foreign key from a specified table.
|
|
926
|
+
* Is only used if {@link canAlterForeignKeys} is true.
|
|
927
|
+
*
|
|
928
|
+
* @param tableName - The name of the table to which the foreign key will be added.
|
|
929
|
+
* @param foreignKeyName - The name of the foreign key definition.
|
|
930
|
+
* @return The SQL statement that removes the foreign key from the specified table.
|
|
931
|
+
*/
|
|
809
932
|
removeForeignKey(tableName, foreignKeyName) {
|
|
810
933
|
throw new Error("Foreign key removal is not supported!");
|
|
811
934
|
}
|
|
935
|
+
/**
|
|
936
|
+
* Query to add a primary key to the specified table.
|
|
937
|
+
* Is only used if {@link canAlterPrimaryKey} is true.
|
|
938
|
+
*
|
|
939
|
+
* @param tableName - The name of the table to which the primary key will be added.
|
|
940
|
+
* @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.
|
|
942
|
+
*/
|
|
812
943
|
addPrimaryKey(tableName, columnName) {
|
|
813
944
|
throw new Error("Adding foreign keys is not supported!");
|
|
814
945
|
}
|
|
946
|
+
/**
|
|
947
|
+
* Query to remove a primary key from the specified table.
|
|
948
|
+
* Is only used if {@link canAlterPrimaryKey} is true.
|
|
949
|
+
*
|
|
950
|
+
* @param tableName - The name of the table to which the primary key will be added.
|
|
951
|
+
* @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.
|
|
953
|
+
*/
|
|
815
954
|
removePrimaryKey(tableName, columnName) {
|
|
816
955
|
throw new Error("Foreign key removal is not supported!");
|
|
817
956
|
}
|
|
957
|
+
/**
|
|
958
|
+
* Constructs a SQL FOREIGN KEY constraint clause.
|
|
959
|
+
* Used in combination with {@link addForeignKey} or {@link createTable}
|
|
960
|
+
*
|
|
961
|
+
* @param column - The name of the column in the current table to apply the foreign key constraint.
|
|
962
|
+
* @param foreignTable - The name of the referenced table.
|
|
963
|
+
* @param foreignColumn - The name of the referenced column in the foreign table.
|
|
964
|
+
* @param onUpdate - Optional action to specify the behavior on update (e.g., CASCADE, SET NULL).
|
|
965
|
+
* @param onDelete - Optional action to specify the behavior on delete (e.g., CASCADE, SET NULL).
|
|
966
|
+
* @return The SQL string representing the foreign key constraint.
|
|
967
|
+
*/
|
|
818
968
|
foreignKey(column, foreignTable, foreignColumn, onUpdate, onDelete) {
|
|
819
969
|
let query = `FOREIGN KEY (${column}) REFERENCES ${foreignTable} (${foreignColumn})`;
|
|
820
970
|
if (onUpdate)
|
|
@@ -864,7 +1014,7 @@ var DefaultSql = class {
|
|
|
864
1014
|
}
|
|
865
1015
|
migrationTableQuery() {
|
|
866
1016
|
return this.createTable(MIGRATION_DATA_TABLE_NAME, [
|
|
867
|
-
this.columnDefinition("version", this.
|
|
1017
|
+
this.columnDefinition("version", this.types.number, "0", false)
|
|
868
1018
|
]);
|
|
869
1019
|
}
|
|
870
1020
|
async getForeignKeys(tableName) {
|
|
@@ -893,8 +1043,16 @@ UPDATE ${MIGRATION_DATA_TABLE_NAME} SET version = ${newVersion} WHERE EXISTS (SE
|
|
|
893
1043
|
|
|
894
1044
|
// src/lib/dialects/SqliteDialect.ts
|
|
895
1045
|
var SqliteDialect = class extends DefaultSql {
|
|
896
|
-
|
|
897
|
-
|
|
1046
|
+
types = {
|
|
1047
|
+
string: "TEXT",
|
|
1048
|
+
number: "INTEGER",
|
|
1049
|
+
bigint: "INTEGER",
|
|
1050
|
+
boolean: "INTEGER",
|
|
1051
|
+
date: "DATE",
|
|
1052
|
+
time: "TIME",
|
|
1053
|
+
dateTime: "DATETIME",
|
|
1054
|
+
null: "NULL"
|
|
1055
|
+
};
|
|
898
1056
|
canAlterForeignKeys = false;
|
|
899
1057
|
canAlterPrimaryKey = false;
|
|
900
1058
|
canInspectForeignKeys = true;
|
|
@@ -916,12 +1074,19 @@ var SqliteDialect = class extends DefaultSql {
|
|
|
916
1074
|
};
|
|
917
1075
|
});
|
|
918
1076
|
}
|
|
919
|
-
formatValueToSql(value) {
|
|
920
|
-
|
|
1077
|
+
formatValueToSql(value, type) {
|
|
1078
|
+
function toDate(value2) {
|
|
1079
|
+
return value2 instanceof Date ? value2 : new Date(value2);
|
|
1080
|
+
}
|
|
1081
|
+
switch (type) {
|
|
921
1082
|
case "boolean":
|
|
922
1083
|
return value ? "1" : "0";
|
|
1084
|
+
case "date":
|
|
1085
|
+
case "time":
|
|
1086
|
+
case "dateTime":
|
|
1087
|
+
return toDate(value).getTime().toString();
|
|
923
1088
|
default:
|
|
924
|
-
return
|
|
1089
|
+
return super.formatValueToSql(value, type);
|
|
925
1090
|
}
|
|
926
1091
|
}
|
|
927
1092
|
async getForeignKeys(tableName) {
|
|
@@ -1159,8 +1324,10 @@ async function rollback(db, dbInstructions, toVersion) {
|
|
|
1159
1324
|
}
|
|
1160
1325
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1161
1326
|
0 && (module.exports = {
|
|
1162
|
-
|
|
1327
|
+
DataType,
|
|
1163
1328
|
ForeignKey,
|
|
1329
|
+
TableClass,
|
|
1330
|
+
TableObj,
|
|
1164
1331
|
prepareAndRunMigration,
|
|
1165
1332
|
prepareMigration,
|
|
1166
1333
|
rollback,
|