sqlmorpheus 0.1.10 → 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 +98 -37
- package/dist/index.d.ts +98 -37
- package/dist/index.js +385 -149
- package/dist/index.mjs +381 -147
- 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,60 +194,129 @@ 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. In
|
|
197
|
+
let message = "Some destructive changes need to be confirmed. In preMigration() run:\n";
|
|
150
198
|
for (const entry of entries) {
|
|
151
|
-
message += `
|
|
152
|
-
|
|
199
|
+
message += ` migrations.allowMigration(${entry.version}, ${entry.tableName}, "${entry.type}");
|
|
200
|
+
`;
|
|
153
201
|
}
|
|
154
|
-
super(
|
|
155
|
-
|
|
156
|
-
`);
|
|
202
|
+
super(message);
|
|
157
203
|
}
|
|
158
204
|
};
|
|
159
205
|
|
|
160
|
-
// src/lib/
|
|
206
|
+
// src/lib/Migrations.ts
|
|
161
207
|
var Migrations = class {
|
|
162
|
-
toVersion = 0;
|
|
163
|
-
alwaysAllowed = {};
|
|
164
208
|
fromVersion = 0;
|
|
209
|
+
toVersion = 0;
|
|
210
|
+
lastUsedVersion = 0;
|
|
165
211
|
migrationData = {};
|
|
212
|
+
migrationDataForOldTableNames = {};
|
|
213
|
+
alwaysAllowed = {};
|
|
166
214
|
notAllowedChanges = [];
|
|
167
215
|
reset(dbInstructions, fromVersion) {
|
|
168
216
|
this.fromVersion = fromVersion;
|
|
169
|
-
this.migrationData = {};
|
|
170
217
|
this.toVersion = dbInstructions.version;
|
|
218
|
+
this.migrationData = {};
|
|
219
|
+
this.migrationDataForOldTableNames = {};
|
|
171
220
|
this.alwaysAllowed = dbInstructions.alwaysAllowedMigrations ?? {};
|
|
172
221
|
this.notAllowedChanges = [];
|
|
173
222
|
}
|
|
174
223
|
getEntry(table) {
|
|
175
224
|
const tableName = this.getTableName(table);
|
|
225
|
+
return this.getEntryFromTableName(tableName);
|
|
226
|
+
}
|
|
227
|
+
getEntryFromTableName(tableName) {
|
|
176
228
|
if (!this.migrationData.hasOwnProperty(tableName)) {
|
|
177
229
|
this.migrationData[tableName] = {
|
|
178
230
|
recreate: false,
|
|
179
231
|
renamedColumns: [],
|
|
180
|
-
allowedMigrations: {}
|
|
232
|
+
allowedMigrations: {},
|
|
233
|
+
usedMigrations: {}
|
|
181
234
|
};
|
|
182
235
|
}
|
|
183
236
|
return this.migrationData[tableName];
|
|
184
237
|
}
|
|
185
238
|
getTableName(table) {
|
|
186
|
-
return
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
if (
|
|
190
|
-
this.notAllowedChanges.push({ version: this.toVersion, tableName, type });
|
|
191
|
-
}
|
|
192
|
-
checkIfAllowed(throwIfNotAllowed) {
|
|
193
|
-
if (!this.notAllowedChanges.length)
|
|
194
|
-
return true;
|
|
195
|
-
const exception = new NotAllowedException(this.notAllowedChanges);
|
|
196
|
-
if (throwIfNotAllowed)
|
|
197
|
-
throw exception;
|
|
198
|
-
else {
|
|
199
|
-
console.error(exception.message);
|
|
239
|
+
return TableObj.isDbTable(table) ? table.tableName : table.name;
|
|
240
|
+
}
|
|
241
|
+
versionIsRelevant(version) {
|
|
242
|
+
if (version < this.fromVersion || version > this.toVersion)
|
|
200
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;
|
|
248
|
+
}
|
|
249
|
+
verifyRenamingTasks(newTables) {
|
|
250
|
+
for (const tableName in this.migrationData) {
|
|
251
|
+
const migrationEntry = this.migrationData[tableName];
|
|
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
|
+
}
|
|
260
|
+
for (const renamingData of migrationEntry.renamedColumns) {
|
|
261
|
+
const oldColumnName = renamingData.oldName;
|
|
262
|
+
const newColumnName = renamingData.newName;
|
|
263
|
+
if (oldColumnName == newColumnName)
|
|
264
|
+
return new Error(`You set column ${tableName}.${oldColumnName} to be renamed to itself!`);
|
|
265
|
+
else if (!newTables[tableName]?.columns.find((column) => column.name == newColumnName))
|
|
266
|
+
return new Error(`You set column ${tableName}.${oldColumnName} to be renamed to ${tableName}.${newColumnName}. But ${tableName}.${newColumnName} does not exist in your structure.`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
verifyAllowedMigrations() {
|
|
271
|
+
if (this.notAllowedChanges.length)
|
|
272
|
+
return new NotAllowedException(this.notAllowedChanges);
|
|
273
|
+
let errorMsg = "";
|
|
274
|
+
for (const tableName in this.migrationData) {
|
|
275
|
+
const migration = this.migrationData[tableName];
|
|
276
|
+
for (const type in migration.allowedMigrations) {
|
|
277
|
+
if (!migration.usedMigrations[type])
|
|
278
|
+
errorMsg += `Migration "${type}" for ${tableName} was allowed but not needed.
|
|
279
|
+
`;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (errorMsg)
|
|
283
|
+
return new Error(errorMsg);
|
|
284
|
+
}
|
|
285
|
+
compareWithAllowedMigration(tableName, type) {
|
|
286
|
+
const migrationEntry = this.migrationData[tableName];
|
|
287
|
+
if (!migrationEntry?.allowedMigrations[type]) {
|
|
288
|
+
if (!this.alwaysAllowed[type])
|
|
289
|
+
this.notAllowedChanges.push({ version: this.toVersion, tableName, type });
|
|
290
|
+
} else if (migrationEntry)
|
|
291
|
+
migrationEntry.usedMigrations[type] = true;
|
|
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);
|
|
201
300
|
}
|
|
202
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
|
+
}
|
|
203
320
|
allowMigration(version, table, ...allowedMigrations) {
|
|
204
321
|
if (version < this.fromVersion || version > this.toVersion)
|
|
205
322
|
return;
|
|
@@ -208,52 +325,33 @@ var Migrations = class {
|
|
|
208
325
|
entry.allowedMigrations[key] = true;
|
|
209
326
|
}
|
|
210
327
|
}
|
|
211
|
-
renameTable(version, oldTableName,
|
|
212
|
-
if (
|
|
328
|
+
renameTable(version, oldTableName, newTableName) {
|
|
329
|
+
if (!this.versionIsRelevant(version))
|
|
213
330
|
return;
|
|
214
|
-
const
|
|
215
|
-
entry
|
|
216
|
-
|
|
217
|
-
|
|
331
|
+
const newTableNameString = this.getTableName(newTableName);
|
|
332
|
+
const entry = this.getEntry(newTableName);
|
|
333
|
+
this.migrationDataForOldTableNames[oldTableName] = entry;
|
|
334
|
+
if (!entry.tableRenaming)
|
|
335
|
+
entry.tableRenaming = { oldName: oldTableName, newName: newTableNameString };
|
|
336
|
+
else
|
|
337
|
+
entry.tableRenaming.newName = newTableNameString;
|
|
218
338
|
}
|
|
219
339
|
renameColumn(version, table, oldColumn, newColumn) {
|
|
220
|
-
if (
|
|
340
|
+
if (!this.versionIsRelevant(version))
|
|
221
341
|
return;
|
|
222
342
|
const entry = this.getEntry(table);
|
|
223
|
-
const existingColumnEntry = entry.renamedColumns.find((entry2) => entry2
|
|
343
|
+
const existingColumnEntry = entry.renamedColumns.find((entry2) => entry2.newName == oldColumn);
|
|
224
344
|
if (existingColumnEntry)
|
|
225
|
-
existingColumnEntry.
|
|
345
|
+
existingColumnEntry.newName = newColumn;
|
|
226
346
|
else
|
|
227
|
-
entry.renamedColumns.push(
|
|
228
|
-
}
|
|
229
|
-
recreateTableImp(table) {
|
|
230
|
-
const entry = this.getEntry(table);
|
|
231
|
-
entry.recreate = true;
|
|
347
|
+
entry.renamedColumns.push({ oldName: oldColumn, newName: newColumn });
|
|
232
348
|
}
|
|
233
349
|
recreateTable(version, table) {
|
|
234
|
-
if (
|
|
350
|
+
if (!this.versionIsRelevant(version))
|
|
235
351
|
return;
|
|
236
|
-
this.
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
return this.migrationData;
|
|
240
|
-
}
|
|
241
|
-
loopRenamedColumns(tableName, callback) {
|
|
242
|
-
const migrationEntry = this.migrationData[tableName];
|
|
243
|
-
for (const renamingArray of migrationEntry.renamedColumns) {
|
|
244
|
-
if (renamingArray.length <= 1)
|
|
245
|
-
continue;
|
|
246
|
-
const oldColumnName = renamingArray[0];
|
|
247
|
-
const newColumnName = renamingArray[renamingArray.length - 1];
|
|
248
|
-
callback(oldColumnName, newColumnName);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
getUpdatedColumnName(tableName, oldColumnName) {
|
|
252
|
-
const columnNames = this.migrationData[tableName]?.renamedColumns.find((columns) => columns[0] == oldColumnName);
|
|
253
|
-
return columnNames ? columnNames[columnNames.length - 1] : oldColumnName;
|
|
254
|
-
}
|
|
255
|
-
willBeRecreated(tableName) {
|
|
256
|
-
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!`);
|
|
257
355
|
}
|
|
258
356
|
};
|
|
259
357
|
|
|
@@ -261,6 +359,10 @@ var Migrations = class {
|
|
|
261
359
|
var MigrationManager = class {
|
|
262
360
|
migrations = new Migrations();
|
|
263
361
|
newTables = {};
|
|
362
|
+
/**
|
|
363
|
+
* Table names that currently exist in the database
|
|
364
|
+
* Note: If tables are set to be renamed, then names in this array will be corrected to their future name.
|
|
365
|
+
*/
|
|
264
366
|
existingTables = [];
|
|
265
367
|
dialect;
|
|
266
368
|
constructor(dialect) {
|
|
@@ -318,8 +420,9 @@ ${preSQL.down}`;
|
|
|
318
420
|
changes.down += initialChanges.down;
|
|
319
421
|
} else {
|
|
320
422
|
Logger.log(`Creating migration SQL from version ${fromVersion} to ${toVersion}`);
|
|
321
|
-
this.existingTables = await this.dialect.getTableNames();
|
|
423
|
+
this.existingTables = (await this.dialect.getTableNames()).map((oldTableName) => this.migrations.getNewestTableName(oldTableName));
|
|
322
424
|
[
|
|
425
|
+
this.renameTables(),
|
|
323
426
|
await this.createAndDropTables(),
|
|
324
427
|
await this.migrateForeignKeys(),
|
|
325
428
|
await this.migrateColumns(),
|
|
@@ -348,8 +451,18 @@ ${foreignKeyOnQuery}`;
|
|
|
348
451
|
changes.down += `
|
|
349
452
|
|
|
350
453
|
${foreignKeyOnQuery}`;
|
|
351
|
-
|
|
352
|
-
|
|
454
|
+
const exception = this.migrations.verifyRenamingTasks(this.newTables) ?? this.migrations.verifyAllowedMigrations();
|
|
455
|
+
if (exception) {
|
|
456
|
+
Logger.debug(`
|
|
457
|
+
Canceled changes:
|
|
458
|
+
${changes.up}
|
|
459
|
+
`);
|
|
460
|
+
if (dbInstructions.throwIfNotAllowed)
|
|
461
|
+
throw exception;
|
|
462
|
+
else {
|
|
463
|
+
console.error(exception.message);
|
|
464
|
+
return null;
|
|
465
|
+
}
|
|
353
466
|
}
|
|
354
467
|
return {
|
|
355
468
|
fromVersion,
|
|
@@ -357,6 +470,22 @@ ${foreignKeyOnQuery}`;
|
|
|
357
470
|
changes
|
|
358
471
|
};
|
|
359
472
|
}
|
|
473
|
+
renameTables() {
|
|
474
|
+
const changes = {
|
|
475
|
+
up: "\n\n-- Rename tables\n",
|
|
476
|
+
down: "\n\n-- Rename tables\n"
|
|
477
|
+
};
|
|
478
|
+
const data = this.migrations.getMigrationData();
|
|
479
|
+
for (const tableName in data) {
|
|
480
|
+
const migrationEntry = data[tableName];
|
|
481
|
+
if (migrationEntry.tableRenaming) {
|
|
482
|
+
Logger.log(`Table "${migrationEntry.tableRenaming.oldName}" will be renamed to "${tableName}"!`);
|
|
483
|
+
changes.up += this.dialect.renameTable(migrationEntry.tableRenaming.oldName, tableName);
|
|
484
|
+
changes.down += this.dialect.renameTable(tableName, migrationEntry.tableRenaming.oldName);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
return changes;
|
|
488
|
+
}
|
|
360
489
|
/**
|
|
361
490
|
* Generates SQL change statements for creating and dropping tables based on the current table structure
|
|
362
491
|
* and existing table configurations in the database. The `up` changes include SQL statements for creating
|
|
@@ -368,8 +497,8 @@ ${foreignKeyOnQuery}`;
|
|
|
368
497
|
*/
|
|
369
498
|
async createAndDropTables() {
|
|
370
499
|
let changes = {
|
|
371
|
-
up: "\n\n-- Create tables\n",
|
|
372
|
-
down: "\n\n-- Create tables\n"
|
|
500
|
+
up: "\n\n-- Create and drop tables\n",
|
|
501
|
+
down: "\n\n-- Create and drop tables\n"
|
|
373
502
|
};
|
|
374
503
|
for (const tableName in this.newTables) {
|
|
375
504
|
if (this.tableDoesNotExists(tableName)) {
|
|
@@ -382,12 +511,13 @@ ${foreignKeyOnQuery}`;
|
|
|
382
511
|
}
|
|
383
512
|
for (const tableName of this.existingTables) {
|
|
384
513
|
if (!this.newTables[tableName]) {
|
|
385
|
-
this.migrations.
|
|
514
|
+
this.migrations.compareWithAllowedMigration(tableName, "dropTable");
|
|
386
515
|
if (!this.dialect.canInspectForeignKeys || !this.dialect.canInspectPrimaryKey)
|
|
387
|
-
this.migrations.
|
|
516
|
+
this.migrations.compareWithAllowedMigration(tableName, "continueWithoutRollback");
|
|
517
|
+
const dbTableName = this.migrations.getOldTableName(tableName);
|
|
388
518
|
changes.up += `${this.dialect.dropTable(tableName)}
|
|
389
519
|
`;
|
|
390
|
-
changes.down += this.dialect.canInspectForeignKeys && this.dialect.canInspectPrimaryKey ? this.createTableSql(tableName, await this.dialect.getColumnInformation(
|
|
520
|
+
changes.down += this.dialect.canInspectForeignKeys && this.dialect.canInspectPrimaryKey ? this.createTableSql(tableName, await this.dialect.getColumnInformation(dbTableName), await this.dialect.getForeignKeys(dbTableName)) : "\n\n-- Cannot recreate foreign keys or load primary keys with this database! Table will not be recreated!\n";
|
|
391
521
|
}
|
|
392
522
|
}
|
|
393
523
|
return changes;
|
|
@@ -438,10 +568,10 @@ ${foreignKeyOnQuery}`;
|
|
|
438
568
|
const migrationEntry = migrationData[tableName];
|
|
439
569
|
if (!migrationEntry.recreate)
|
|
440
570
|
continue;
|
|
441
|
-
this.migrations.
|
|
571
|
+
this.migrations.compareWithAllowedMigration(tableName, "recreateTable");
|
|
442
572
|
if (!this.dialect.canInspectForeignKeys || !this.dialect.canInspectPrimaryKey)
|
|
443
|
-
this.migrations.
|
|
444
|
-
const oldColumnList = await this.dialect.getColumnInformation(tableName);
|
|
573
|
+
this.migrations.compareWithAllowedMigration(tableName, "continueWithoutRollback");
|
|
574
|
+
const oldColumnList = await this.dialect.getColumnInformation(this.migrations.getOldTableName(tableName));
|
|
445
575
|
const newColumnList = this.newTables[tableName].columns;
|
|
446
576
|
const moveableColumns = newColumnList.filter((entry) => oldColumnList.find((oldEntry) => oldEntry.name == entry.name) != void 0).map((entry) => entry.name);
|
|
447
577
|
const backupTableName = `${tableName}__backup`;
|
|
@@ -451,8 +581,9 @@ ${foreignKeyOnQuery}`;
|
|
|
451
581
|
);
|
|
452
582
|
const moveDataQuery = insertQuery + "\n" + this.dialect.dropTable(tableName) + "\n" + this.dialect.renameTable(backupTableName, tableName);
|
|
453
583
|
const structure = this.newTables[tableName];
|
|
454
|
-
changes.up += this.createTableSql(backupTableName, structure.columns, structure.foreignKeys) + "\n" + moveDataQuery;
|
|
455
|
-
|
|
584
|
+
changes.up += this.createTableSql(backupTableName, structure.columns, structure.foreignKeys) + "\n" + moveDataQuery + "\n";
|
|
585
|
+
const dbTableName = this.migrations.getOldTableName(tableName);
|
|
586
|
+
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";
|
|
456
587
|
}
|
|
457
588
|
return changes;
|
|
458
589
|
}
|
|
@@ -460,8 +591,6 @@ ${foreignKeyOnQuery}`;
|
|
|
460
591
|
* Migrates foreign key constraints for all defined tables.
|
|
461
592
|
*/
|
|
462
593
|
async migrateForeignKeys() {
|
|
463
|
-
if (!this.dialect.canAlterForeignKeys)
|
|
464
|
-
return { up: "", down: "" };
|
|
465
594
|
let changes = {
|
|
466
595
|
up: "\n\n-- Foreign keys\n",
|
|
467
596
|
down: "\n\n-- Foreign keys\n"
|
|
@@ -471,13 +600,13 @@ ${foreignKeyOnQuery}`;
|
|
|
471
600
|
continue;
|
|
472
601
|
const structure = this.newTables[tableName];
|
|
473
602
|
const newForeignKeys = structure.foreignKeys ?? [];
|
|
474
|
-
const oldForeignKeys = await this.dialect.getForeignKeys(tableName);
|
|
603
|
+
const oldForeignKeys = await this.dialect.getForeignKeys(this.migrations.getOldTableName(tableName));
|
|
475
604
|
let checkForNewForeignKeys = true;
|
|
476
605
|
for (const oldForeignKey of oldForeignKeys) {
|
|
477
606
|
const newForeignKey = newForeignKeys.find((entry) => entry.fromColumn == oldForeignKey.fromColumn);
|
|
478
607
|
if (!newForeignKey) {
|
|
479
|
-
Logger.log(`Foreign key ${oldForeignKey.
|
|
480
|
-
this.migrations.
|
|
608
|
+
Logger.log(`Foreign key ${oldForeignKey.fromTable}.${oldForeignKey.fromColumn} to ${oldForeignKey.toTable}.${oldForeignKey.toColumn} will be removed!`);
|
|
609
|
+
this.migrations.compareWithAllowedMigration(tableName, "removeForeignKey");
|
|
481
610
|
if (this.dialect.canAlterForeignKeys) {
|
|
482
611
|
changes.up += this.dialect.removeForeignKey(oldForeignKey.fromTable, oldForeignKey.fromColumn);
|
|
483
612
|
changes.down += this.dialect.addForeignKey(
|
|
@@ -485,13 +614,13 @@ ${foreignKeyOnQuery}`;
|
|
|
485
614
|
this.dialect.foreignKey(oldForeignKey.fromColumn, oldForeignKey.toTable, oldForeignKey.toColumn, oldForeignKey.onUpdate, oldForeignKey.onDelete)
|
|
486
615
|
);
|
|
487
616
|
} else {
|
|
488
|
-
this.migrations.
|
|
617
|
+
this.migrations.internalRecreate(structure.table, "Dialect does not support altering foreign keys");
|
|
489
618
|
checkForNewForeignKeys = false;
|
|
490
619
|
}
|
|
491
620
|
} else {
|
|
492
621
|
if (!newForeignKey || oldForeignKey.toColumn != newForeignKey.toColumn || (oldForeignKey.onUpdate ?? "NO ACTION") != (newForeignKey.onUpdate ?? "NO ACTION") || (oldForeignKey.onDelete ?? "NO ACTION") != (newForeignKey.onDelete ?? "NO ACTION")) {
|
|
493
|
-
Logger.log(`Foreign key ${oldForeignKey.
|
|
494
|
-
this.migrations.
|
|
622
|
+
Logger.log(`Foreign key ${oldForeignKey.fromTable}.${oldForeignKey.fromColumn} to ${oldForeignKey.toTable}.${oldForeignKey.toColumn} will be changed!`);
|
|
623
|
+
this.migrations.compareWithAllowedMigration(tableName, "alterForeignKey");
|
|
495
624
|
if (this.dialect.canAlterForeignKeys) {
|
|
496
625
|
changes.up += this.dialect.removeForeignKey(oldForeignKey.fromTable, oldForeignKey.fromColumn) + this.dialect.addForeignKey(
|
|
497
626
|
newForeignKey.fromTable,
|
|
@@ -502,7 +631,7 @@ ${foreignKeyOnQuery}`;
|
|
|
502
631
|
this.dialect.foreignKey(oldForeignKey.fromColumn, oldForeignKey.toTable, oldForeignKey.toColumn, oldForeignKey.onUpdate, oldForeignKey.onDelete)
|
|
503
632
|
) + this.dialect.removeForeignKey(newForeignKey.fromTable, newForeignKey.fromColumn);
|
|
504
633
|
} else {
|
|
505
|
-
this.migrations.
|
|
634
|
+
this.migrations.internalRecreate(structure.table, "Dialect does not support altering foreign keys");
|
|
506
635
|
checkForNewForeignKeys = false;
|
|
507
636
|
}
|
|
508
637
|
}
|
|
@@ -513,7 +642,7 @@ ${foreignKeyOnQuery}`;
|
|
|
513
642
|
const oldForeignKey = oldForeignKeys.find((entry) => entry.fromColumn == newForeignKey.fromColumn);
|
|
514
643
|
if (oldForeignKey)
|
|
515
644
|
continue;
|
|
516
|
-
Logger.log(`Foreign key ${newForeignKey.
|
|
645
|
+
Logger.log(`Foreign key ${newForeignKey.fromTable}.${newForeignKey.fromColumn} to ${newForeignKey.toTable}.${newForeignKey.toColumn} will be added!`);
|
|
517
646
|
if (this.dialect.canAlterForeignKeys) {
|
|
518
647
|
changes.up += this.dialect.addForeignKey(
|
|
519
648
|
newForeignKey.toTable,
|
|
@@ -521,7 +650,7 @@ ${foreignKeyOnQuery}`;
|
|
|
521
650
|
);
|
|
522
651
|
changes.down += this.dialect.removeForeignKey(newForeignKey.fromTable, newForeignKey.fromColumn);
|
|
523
652
|
} else {
|
|
524
|
-
this.migrations.
|
|
653
|
+
this.migrations.internalRecreate(structure.table, "Dialect does not support altering foreign keys");
|
|
525
654
|
break;
|
|
526
655
|
}
|
|
527
656
|
}
|
|
@@ -542,13 +671,13 @@ ${foreignKeyOnQuery}`;
|
|
|
542
671
|
if (this.migrations.willBeRecreated(tableName) || this.tableDoesNotExists(tableName))
|
|
543
672
|
continue;
|
|
544
673
|
const newTableDefinition = this.newTables[tableName];
|
|
545
|
-
const oldColumnList = await this.dialect.getColumnInformation(tableName);
|
|
674
|
+
const oldColumnList = await this.dialect.getColumnInformation(this.migrations.getOldTableName(tableName));
|
|
546
675
|
const oldPrimaryKey = this.dialect.canInspectPrimaryKey ? this.getPrimaryKeyColumn(oldColumnList) : false;
|
|
547
676
|
const newColumnList = newTableDefinition.columns;
|
|
548
677
|
const newPrimaryKey = newTableDefinition.primaryKey;
|
|
549
678
|
if (this.dialect.canInspectPrimaryKey && oldPrimaryKey != newPrimaryKey) {
|
|
550
|
-
Logger.log(`Primary key in ${tableName}
|
|
551
|
-
this.migrations.
|
|
679
|
+
Logger.log(`Primary key in ${tableName} will be changed from ${oldPrimaryKey} to ${newPrimaryKey}!`);
|
|
680
|
+
this.migrations.compareWithAllowedMigration(tableName, "alterPrimaryKey");
|
|
552
681
|
if (this.dialect.canAlterPrimaryKey) {
|
|
553
682
|
if (oldPrimaryKey) {
|
|
554
683
|
changes.up += this.dialect.removePrimaryKey(tableName, oldPrimaryKey);
|
|
@@ -559,26 +688,26 @@ ${foreignKeyOnQuery}`;
|
|
|
559
688
|
changes.down += this.dialect.removePrimaryKey(tableName, newPrimaryKey.toString());
|
|
560
689
|
}
|
|
561
690
|
} else
|
|
562
|
-
this.migrations.
|
|
691
|
+
this.migrations.internalRecreate(newTableDefinition.table, "Dialect does not support altering primary keys");
|
|
563
692
|
continue;
|
|
564
693
|
}
|
|
565
694
|
for (const newColumn of newColumnList) {
|
|
566
695
|
const oldColumn = oldColumnList.find(
|
|
567
|
-
(entry) => this.migrations.
|
|
696
|
+
(entry) => this.migrations.getNewestColumnName(tableName, entry.name) == newColumn.name
|
|
568
697
|
);
|
|
569
698
|
if (oldColumn == void 0) {
|
|
570
699
|
changes.up += this.dialect.createColumn(tableName, this.dialect.columnDefinition(newColumn.name, newColumn.type, newColumn.defaultValue, newColumn.isPrimaryKey)) + "\n";
|
|
571
700
|
changes.down += this.dialect.dropColumn(tableName, newColumn.name) + "\n";
|
|
572
701
|
} else if (newColumn.type != oldColumn.type || newColumn.defaultValue != oldColumn.defaultValue) {
|
|
573
|
-
this.migrations.
|
|
702
|
+
this.migrations.internalRecreate(newTableDefinition.table, "Table structure was changed");
|
|
574
703
|
}
|
|
575
704
|
}
|
|
576
705
|
for (const oldColumn of oldColumnList) {
|
|
577
706
|
const newColumn = newColumnList.find(
|
|
578
|
-
(entry) => entry.name == this.migrations.
|
|
707
|
+
(entry) => entry.name == this.migrations.getNewestColumnName(tableName, oldColumn.name)
|
|
579
708
|
);
|
|
580
709
|
if (newColumn == void 0) {
|
|
581
|
-
this.migrations.
|
|
710
|
+
this.migrations.compareWithAllowedMigration(tableName, "dropColumn");
|
|
582
711
|
changes.up += this.dialect.dropColumn(tableName, oldColumn.name) + "\n";
|
|
583
712
|
changes.down += this.dialect.createColumn(tableName, this.dialect.columnDefinition(oldColumn.name, oldColumn.type, oldColumn.defaultValue, oldColumn.isPrimaryKey)) + "\n";
|
|
584
713
|
}
|
|
@@ -612,6 +741,7 @@ ${foreignKeyOnQuery}`;
|
|
|
612
741
|
if (migrationData[tableName].recreate)
|
|
613
742
|
continue;
|
|
614
743
|
this.migrations.loopRenamedColumns(tableName, (oldColumnName, newColumnName) => {
|
|
744
|
+
Logger.log(`Column ${tableName}.${oldColumnName} will be renamed to ${tableName}.${newColumnName}!`);
|
|
615
745
|
changes.up += this.dialect.renameColumn(tableName, oldColumnName, newColumnName);
|
|
616
746
|
changes.down += this.dialect.renameColumn(tableName, newColumnName, oldColumnName);
|
|
617
747
|
});
|
|
@@ -678,24 +808,37 @@ ${changes.down}`, { encoding: "utf-8" });
|
|
|
678
808
|
}
|
|
679
809
|
};
|
|
680
810
|
|
|
681
|
-
// src/lib/tableInfo/decorators/
|
|
811
|
+
// src/lib/tableInfo/decorators/TableClass.ts
|
|
682
812
|
var import_polyfill_symbol_metadata = require("polyfill-symbol-metadata");
|
|
683
|
-
function
|
|
813
|
+
function TableClass(tableName, primaryKey) {
|
|
684
814
|
return (table, context) => {
|
|
685
|
-
Object.defineProperty(table, "name", { value: tableName, writable: false });
|
|
686
815
|
const tableInfo = context?.metadata ? getTableInfoFromMetadata(context.metadata) : getTableInfo(table);
|
|
687
816
|
tableInfo.primaryKey = primaryKey?.toString();
|
|
688
817
|
if (tableInfo.foreignKeys) {
|
|
689
818
|
for (const foreignKey of tableInfo.foreignKeys) {
|
|
690
819
|
foreignKey.fromTable = tableName;
|
|
820
|
+
if (foreignKey.toTable == table.name)
|
|
821
|
+
foreignKey.toTable = tableName;
|
|
691
822
|
}
|
|
692
823
|
}
|
|
824
|
+
Object.defineProperty(table, "name", { value: tableName, writable: false });
|
|
693
825
|
};
|
|
694
826
|
}
|
|
695
827
|
|
|
696
|
-
// src/lib/tableInfo/decorators/
|
|
828
|
+
// src/lib/tableInfo/decorators/DataType.ts
|
|
697
829
|
var import_polyfill_symbol_metadata2 = require("polyfill-symbol-metadata");
|
|
698
|
-
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) {
|
|
699
842
|
return (table, context) => {
|
|
700
843
|
const metadata = context?.metadata ? getTableInfoFromMetadata(context.metadata) : getTableInfo(table);
|
|
701
844
|
if (!metadata.foreignKeys)
|
|
@@ -706,8 +849,8 @@ function ForeignKey(toTable, toColumn, onDelete, onUpdate) {
|
|
|
706
849
|
//to stay compatible with old decorator structure (see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#decorator-metadata)
|
|
707
850
|
toTable: toTable.name,
|
|
708
851
|
toColumn: toColumn.toString(),
|
|
709
|
-
onDelete,
|
|
710
|
-
onUpdate
|
|
852
|
+
onDelete: options?.onDelete,
|
|
853
|
+
onUpdate: options?.onUpdate
|
|
711
854
|
});
|
|
712
855
|
};
|
|
713
856
|
}
|
|
@@ -720,32 +863,108 @@ var DefaultSql = class {
|
|
|
720
863
|
canAlterPrimaryKey = false;
|
|
721
864
|
canInspectForeignKeys = false;
|
|
722
865
|
canInspectPrimaryKey = false;
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
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
|
+
};
|
|
728
876
|
constructor(db) {
|
|
729
877
|
this.db = db;
|
|
730
878
|
}
|
|
731
|
-
|
|
732
|
-
|
|
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
|
+
}
|
|
733
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
|
+
*/
|
|
734
910
|
changeForeignKeysState(enabled) {
|
|
735
911
|
return "";
|
|
736
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
|
+
*/
|
|
737
921
|
addForeignKey(fromTableName, foreignKey) {
|
|
738
922
|
throw new Error("Adding foreign keys is not supported!");
|
|
739
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
|
+
*/
|
|
740
932
|
removeForeignKey(tableName, foreignKeyName) {
|
|
741
933
|
throw new Error("Foreign key removal is not supported!");
|
|
742
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
|
+
*/
|
|
743
943
|
addPrimaryKey(tableName, columnName) {
|
|
744
944
|
throw new Error("Adding foreign keys is not supported!");
|
|
745
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
|
+
*/
|
|
746
954
|
removePrimaryKey(tableName, columnName) {
|
|
747
955
|
throw new Error("Foreign key removal is not supported!");
|
|
748
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
|
+
*/
|
|
749
968
|
foreignKey(column, foreignTable, foreignColumn, onUpdate, onDelete) {
|
|
750
969
|
let query = `FOREIGN KEY (${column}) REFERENCES ${foreignTable} (${foreignColumn})`;
|
|
751
970
|
if (onUpdate)
|
|
@@ -795,7 +1014,7 @@ var DefaultSql = class {
|
|
|
795
1014
|
}
|
|
796
1015
|
migrationTableQuery() {
|
|
797
1016
|
return this.createTable(MIGRATION_DATA_TABLE_NAME, [
|
|
798
|
-
this.columnDefinition("version", this.
|
|
1017
|
+
this.columnDefinition("version", this.types.number, "0", false)
|
|
799
1018
|
]);
|
|
800
1019
|
}
|
|
801
1020
|
async getForeignKeys(tableName) {
|
|
@@ -824,8 +1043,16 @@ UPDATE ${MIGRATION_DATA_TABLE_NAME} SET version = ${newVersion} WHERE EXISTS (SE
|
|
|
824
1043
|
|
|
825
1044
|
// src/lib/dialects/SqliteDialect.ts
|
|
826
1045
|
var SqliteDialect = class extends DefaultSql {
|
|
827
|
-
|
|
828
|
-
|
|
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
|
+
};
|
|
829
1056
|
canAlterForeignKeys = false;
|
|
830
1057
|
canAlterPrimaryKey = false;
|
|
831
1058
|
canInspectForeignKeys = true;
|
|
@@ -847,12 +1074,19 @@ var SqliteDialect = class extends DefaultSql {
|
|
|
847
1074
|
};
|
|
848
1075
|
});
|
|
849
1076
|
}
|
|
850
|
-
formatValueToSql(value) {
|
|
851
|
-
|
|
1077
|
+
formatValueToSql(value, type) {
|
|
1078
|
+
function toDate(value2) {
|
|
1079
|
+
return value2 instanceof Date ? value2 : new Date(value2);
|
|
1080
|
+
}
|
|
1081
|
+
switch (type) {
|
|
852
1082
|
case "boolean":
|
|
853
1083
|
return value ? "1" : "0";
|
|
1084
|
+
case "date":
|
|
1085
|
+
case "time":
|
|
1086
|
+
case "dateTime":
|
|
1087
|
+
return toDate(value).getTime().toString();
|
|
854
1088
|
default:
|
|
855
|
-
return
|
|
1089
|
+
return super.formatValueToSql(value, type);
|
|
856
1090
|
}
|
|
857
1091
|
}
|
|
858
1092
|
async getForeignKeys(tableName) {
|
|
@@ -1090,8 +1324,10 @@ async function rollback(db, dbInstructions, toVersion) {
|
|
|
1090
1324
|
}
|
|
1091
1325
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1092
1326
|
0 && (module.exports = {
|
|
1093
|
-
|
|
1327
|
+
DataType,
|
|
1094
1328
|
ForeignKey,
|
|
1329
|
+
TableClass,
|
|
1330
|
+
TableObj,
|
|
1095
1331
|
prepareAndRunMigration,
|
|
1096
1332
|
prepareMigration,
|
|
1097
1333
|
rollback,
|