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.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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
tableObjects[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
|
|
111
|
+
columns: this.getColumns(obj.columns, tableInfo),
|
|
69
112
|
foreignKeys: tableInfo?.foreignKeys
|
|
70
113
|
};
|
|
71
114
|
}
|
|
72
115
|
return tables;
|
|
73
116
|
}
|
|
74
|
-
|
|
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:
|
|
83
|
-
defaultValue: this.dialect.
|
|
131
|
+
isPrimaryKey: property == tableInfo?.primaryKey,
|
|
132
|
+
type: this.dialect.types.string,
|
|
133
|
+
defaultValue: this.dialect.types.null
|
|
84
134
|
};
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
105
|
-
|
|
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,60 +160,129 @@ 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. In
|
|
163
|
+
let message = "Some destructive changes need to be confirmed. In preMigration() run:\n";
|
|
118
164
|
for (const entry of entries) {
|
|
119
|
-
message += `
|
|
120
|
-
|
|
165
|
+
message += ` migrations.allowMigration(${entry.version}, ${entry.tableName}, "${entry.type}");
|
|
166
|
+
`;
|
|
121
167
|
}
|
|
122
|
-
super(
|
|
123
|
-
|
|
124
|
-
`);
|
|
168
|
+
super(message);
|
|
125
169
|
}
|
|
126
170
|
};
|
|
127
171
|
|
|
128
|
-
// src/lib/
|
|
172
|
+
// src/lib/Migrations.ts
|
|
129
173
|
var Migrations = class {
|
|
130
|
-
toVersion = 0;
|
|
131
|
-
alwaysAllowed = {};
|
|
132
174
|
fromVersion = 0;
|
|
175
|
+
toVersion = 0;
|
|
176
|
+
lastUsedVersion = 0;
|
|
133
177
|
migrationData = {};
|
|
178
|
+
migrationDataForOldTableNames = {};
|
|
179
|
+
alwaysAllowed = {};
|
|
134
180
|
notAllowedChanges = [];
|
|
135
181
|
reset(dbInstructions, fromVersion) {
|
|
136
182
|
this.fromVersion = fromVersion;
|
|
137
|
-
this.migrationData = {};
|
|
138
183
|
this.toVersion = dbInstructions.version;
|
|
184
|
+
this.migrationData = {};
|
|
185
|
+
this.migrationDataForOldTableNames = {};
|
|
139
186
|
this.alwaysAllowed = dbInstructions.alwaysAllowedMigrations ?? {};
|
|
140
187
|
this.notAllowedChanges = [];
|
|
141
188
|
}
|
|
142
189
|
getEntry(table) {
|
|
143
190
|
const tableName = this.getTableName(table);
|
|
191
|
+
return this.getEntryFromTableName(tableName);
|
|
192
|
+
}
|
|
193
|
+
getEntryFromTableName(tableName) {
|
|
144
194
|
if (!this.migrationData.hasOwnProperty(tableName)) {
|
|
145
195
|
this.migrationData[tableName] = {
|
|
146
196
|
recreate: false,
|
|
147
197
|
renamedColumns: [],
|
|
148
|
-
allowedMigrations: {}
|
|
198
|
+
allowedMigrations: {},
|
|
199
|
+
usedMigrations: {}
|
|
149
200
|
};
|
|
150
201
|
}
|
|
151
202
|
return this.migrationData[tableName];
|
|
152
203
|
}
|
|
153
204
|
getTableName(table) {
|
|
154
|
-
return
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (
|
|
158
|
-
this.notAllowedChanges.push({ version: this.toVersion, tableName, type });
|
|
159
|
-
}
|
|
160
|
-
checkIfAllowed(throwIfNotAllowed) {
|
|
161
|
-
if (!this.notAllowedChanges.length)
|
|
162
|
-
return true;
|
|
163
|
-
const exception = new NotAllowedException(this.notAllowedChanges);
|
|
164
|
-
if (throwIfNotAllowed)
|
|
165
|
-
throw exception;
|
|
166
|
-
else {
|
|
167
|
-
console.error(exception.message);
|
|
205
|
+
return TableObj.isDbTable(table) ? table.tableName : table.name;
|
|
206
|
+
}
|
|
207
|
+
versionIsRelevant(version) {
|
|
208
|
+
if (version < this.fromVersion || version > this.toVersion)
|
|
168
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;
|
|
214
|
+
}
|
|
215
|
+
verifyRenamingTasks(newTables) {
|
|
216
|
+
for (const tableName in this.migrationData) {
|
|
217
|
+
const migrationEntry = this.migrationData[tableName];
|
|
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
|
+
}
|
|
226
|
+
for (const renamingData of migrationEntry.renamedColumns) {
|
|
227
|
+
const oldColumnName = renamingData.oldName;
|
|
228
|
+
const newColumnName = renamingData.newName;
|
|
229
|
+
if (oldColumnName == newColumnName)
|
|
230
|
+
return new Error(`You set column ${tableName}.${oldColumnName} to be renamed to itself!`);
|
|
231
|
+
else if (!newTables[tableName]?.columns.find((column) => column.name == newColumnName))
|
|
232
|
+
return new Error(`You set column ${tableName}.${oldColumnName} to be renamed to ${tableName}.${newColumnName}. But ${tableName}.${newColumnName} does not exist in your structure.`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
verifyAllowedMigrations() {
|
|
237
|
+
if (this.notAllowedChanges.length)
|
|
238
|
+
return new NotAllowedException(this.notAllowedChanges);
|
|
239
|
+
let errorMsg = "";
|
|
240
|
+
for (const tableName in this.migrationData) {
|
|
241
|
+
const migration = this.migrationData[tableName];
|
|
242
|
+
for (const type in migration.allowedMigrations) {
|
|
243
|
+
if (!migration.usedMigrations[type])
|
|
244
|
+
errorMsg += `Migration "${type}" for ${tableName} was allowed but not needed.
|
|
245
|
+
`;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (errorMsg)
|
|
249
|
+
return new Error(errorMsg);
|
|
250
|
+
}
|
|
251
|
+
compareWithAllowedMigration(tableName, type) {
|
|
252
|
+
const migrationEntry = this.migrationData[tableName];
|
|
253
|
+
if (!migrationEntry?.allowedMigrations[type]) {
|
|
254
|
+
if (!this.alwaysAllowed[type])
|
|
255
|
+
this.notAllowedChanges.push({ version: this.toVersion, tableName, type });
|
|
256
|
+
} else if (migrationEntry)
|
|
257
|
+
migrationEntry.usedMigrations[type] = true;
|
|
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);
|
|
169
266
|
}
|
|
170
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
|
+
}
|
|
171
286
|
allowMigration(version, table, ...allowedMigrations) {
|
|
172
287
|
if (version < this.fromVersion || version > this.toVersion)
|
|
173
288
|
return;
|
|
@@ -176,52 +291,33 @@ var Migrations = class {
|
|
|
176
291
|
entry.allowedMigrations[key] = true;
|
|
177
292
|
}
|
|
178
293
|
}
|
|
179
|
-
renameTable(version, oldTableName,
|
|
180
|
-
if (
|
|
294
|
+
renameTable(version, oldTableName, newTableName) {
|
|
295
|
+
if (!this.versionIsRelevant(version))
|
|
181
296
|
return;
|
|
182
|
-
const
|
|
183
|
-
entry
|
|
184
|
-
|
|
185
|
-
|
|
297
|
+
const newTableNameString = this.getTableName(newTableName);
|
|
298
|
+
const entry = this.getEntry(newTableName);
|
|
299
|
+
this.migrationDataForOldTableNames[oldTableName] = entry;
|
|
300
|
+
if (!entry.tableRenaming)
|
|
301
|
+
entry.tableRenaming = { oldName: oldTableName, newName: newTableNameString };
|
|
302
|
+
else
|
|
303
|
+
entry.tableRenaming.newName = newTableNameString;
|
|
186
304
|
}
|
|
187
305
|
renameColumn(version, table, oldColumn, newColumn) {
|
|
188
|
-
if (
|
|
306
|
+
if (!this.versionIsRelevant(version))
|
|
189
307
|
return;
|
|
190
308
|
const entry = this.getEntry(table);
|
|
191
|
-
const existingColumnEntry = entry.renamedColumns.find((entry2) => entry2
|
|
309
|
+
const existingColumnEntry = entry.renamedColumns.find((entry2) => entry2.newName == oldColumn);
|
|
192
310
|
if (existingColumnEntry)
|
|
193
|
-
existingColumnEntry.
|
|
311
|
+
existingColumnEntry.newName = newColumn;
|
|
194
312
|
else
|
|
195
|
-
entry.renamedColumns.push(
|
|
196
|
-
}
|
|
197
|
-
recreateTableImp(table) {
|
|
198
|
-
const entry = this.getEntry(table);
|
|
199
|
-
entry.recreate = true;
|
|
313
|
+
entry.renamedColumns.push({ oldName: oldColumn, newName: newColumn });
|
|
200
314
|
}
|
|
201
315
|
recreateTable(version, table) {
|
|
202
|
-
if (
|
|
316
|
+
if (!this.versionIsRelevant(version))
|
|
203
317
|
return;
|
|
204
|
-
this.
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
return this.migrationData;
|
|
208
|
-
}
|
|
209
|
-
loopRenamedColumns(tableName, callback) {
|
|
210
|
-
const migrationEntry = this.migrationData[tableName];
|
|
211
|
-
for (const renamingArray of migrationEntry.renamedColumns) {
|
|
212
|
-
if (renamingArray.length <= 1)
|
|
213
|
-
continue;
|
|
214
|
-
const oldColumnName = renamingArray[0];
|
|
215
|
-
const newColumnName = renamingArray[renamingArray.length - 1];
|
|
216
|
-
callback(oldColumnName, newColumnName);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
getUpdatedColumnName(tableName, oldColumnName) {
|
|
220
|
-
const columnNames = this.migrationData[tableName]?.renamedColumns.find((columns) => columns[0] == oldColumnName);
|
|
221
|
-
return columnNames ? columnNames[columnNames.length - 1] : oldColumnName;
|
|
222
|
-
}
|
|
223
|
-
willBeRecreated(tableName) {
|
|
224
|
-
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!`);
|
|
225
321
|
}
|
|
226
322
|
};
|
|
227
323
|
|
|
@@ -229,6 +325,10 @@ var Migrations = class {
|
|
|
229
325
|
var MigrationManager = class {
|
|
230
326
|
migrations = new Migrations();
|
|
231
327
|
newTables = {};
|
|
328
|
+
/**
|
|
329
|
+
* Table names that currently exist in the database
|
|
330
|
+
* Note: If tables are set to be renamed, then names in this array will be corrected to their future name.
|
|
331
|
+
*/
|
|
232
332
|
existingTables = [];
|
|
233
333
|
dialect;
|
|
234
334
|
constructor(dialect) {
|
|
@@ -286,8 +386,9 @@ ${preSQL.down}`;
|
|
|
286
386
|
changes.down += initialChanges.down;
|
|
287
387
|
} else {
|
|
288
388
|
Logger.log(`Creating migration SQL from version ${fromVersion} to ${toVersion}`);
|
|
289
|
-
this.existingTables = await this.dialect.getTableNames();
|
|
389
|
+
this.existingTables = (await this.dialect.getTableNames()).map((oldTableName) => this.migrations.getNewestTableName(oldTableName));
|
|
290
390
|
[
|
|
391
|
+
this.renameTables(),
|
|
291
392
|
await this.createAndDropTables(),
|
|
292
393
|
await this.migrateForeignKeys(),
|
|
293
394
|
await this.migrateColumns(),
|
|
@@ -316,8 +417,18 @@ ${foreignKeyOnQuery}`;
|
|
|
316
417
|
changes.down += `
|
|
317
418
|
|
|
318
419
|
${foreignKeyOnQuery}`;
|
|
319
|
-
|
|
320
|
-
|
|
420
|
+
const exception = this.migrations.verifyRenamingTasks(this.newTables) ?? this.migrations.verifyAllowedMigrations();
|
|
421
|
+
if (exception) {
|
|
422
|
+
Logger.debug(`
|
|
423
|
+
Canceled changes:
|
|
424
|
+
${changes.up}
|
|
425
|
+
`);
|
|
426
|
+
if (dbInstructions.throwIfNotAllowed)
|
|
427
|
+
throw exception;
|
|
428
|
+
else {
|
|
429
|
+
console.error(exception.message);
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
321
432
|
}
|
|
322
433
|
return {
|
|
323
434
|
fromVersion,
|
|
@@ -325,6 +436,22 @@ ${foreignKeyOnQuery}`;
|
|
|
325
436
|
changes
|
|
326
437
|
};
|
|
327
438
|
}
|
|
439
|
+
renameTables() {
|
|
440
|
+
const changes = {
|
|
441
|
+
up: "\n\n-- Rename tables\n",
|
|
442
|
+
down: "\n\n-- Rename tables\n"
|
|
443
|
+
};
|
|
444
|
+
const data = this.migrations.getMigrationData();
|
|
445
|
+
for (const tableName in data) {
|
|
446
|
+
const migrationEntry = data[tableName];
|
|
447
|
+
if (migrationEntry.tableRenaming) {
|
|
448
|
+
Logger.log(`Table "${migrationEntry.tableRenaming.oldName}" will be renamed to "${tableName}"!`);
|
|
449
|
+
changes.up += this.dialect.renameTable(migrationEntry.tableRenaming.oldName, tableName);
|
|
450
|
+
changes.down += this.dialect.renameTable(tableName, migrationEntry.tableRenaming.oldName);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
return changes;
|
|
454
|
+
}
|
|
328
455
|
/**
|
|
329
456
|
* Generates SQL change statements for creating and dropping tables based on the current table structure
|
|
330
457
|
* and existing table configurations in the database. The `up` changes include SQL statements for creating
|
|
@@ -336,8 +463,8 @@ ${foreignKeyOnQuery}`;
|
|
|
336
463
|
*/
|
|
337
464
|
async createAndDropTables() {
|
|
338
465
|
let changes = {
|
|
339
|
-
up: "\n\n-- Create tables\n",
|
|
340
|
-
down: "\n\n-- Create tables\n"
|
|
466
|
+
up: "\n\n-- Create and drop tables\n",
|
|
467
|
+
down: "\n\n-- Create and drop tables\n"
|
|
341
468
|
};
|
|
342
469
|
for (const tableName in this.newTables) {
|
|
343
470
|
if (this.tableDoesNotExists(tableName)) {
|
|
@@ -350,12 +477,13 @@ ${foreignKeyOnQuery}`;
|
|
|
350
477
|
}
|
|
351
478
|
for (const tableName of this.existingTables) {
|
|
352
479
|
if (!this.newTables[tableName]) {
|
|
353
|
-
this.migrations.
|
|
480
|
+
this.migrations.compareWithAllowedMigration(tableName, "dropTable");
|
|
354
481
|
if (!this.dialect.canInspectForeignKeys || !this.dialect.canInspectPrimaryKey)
|
|
355
|
-
this.migrations.
|
|
482
|
+
this.migrations.compareWithAllowedMigration(tableName, "continueWithoutRollback");
|
|
483
|
+
const dbTableName = this.migrations.getOldTableName(tableName);
|
|
356
484
|
changes.up += `${this.dialect.dropTable(tableName)}
|
|
357
485
|
`;
|
|
358
|
-
changes.down += this.dialect.canInspectForeignKeys && this.dialect.canInspectPrimaryKey ? this.createTableSql(tableName, await this.dialect.getColumnInformation(
|
|
486
|
+
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";
|
|
359
487
|
}
|
|
360
488
|
}
|
|
361
489
|
return changes;
|
|
@@ -406,10 +534,10 @@ ${foreignKeyOnQuery}`;
|
|
|
406
534
|
const migrationEntry = migrationData[tableName];
|
|
407
535
|
if (!migrationEntry.recreate)
|
|
408
536
|
continue;
|
|
409
|
-
this.migrations.
|
|
537
|
+
this.migrations.compareWithAllowedMigration(tableName, "recreateTable");
|
|
410
538
|
if (!this.dialect.canInspectForeignKeys || !this.dialect.canInspectPrimaryKey)
|
|
411
|
-
this.migrations.
|
|
412
|
-
const oldColumnList = await this.dialect.getColumnInformation(tableName);
|
|
539
|
+
this.migrations.compareWithAllowedMigration(tableName, "continueWithoutRollback");
|
|
540
|
+
const oldColumnList = await this.dialect.getColumnInformation(this.migrations.getOldTableName(tableName));
|
|
413
541
|
const newColumnList = this.newTables[tableName].columns;
|
|
414
542
|
const moveableColumns = newColumnList.filter((entry) => oldColumnList.find((oldEntry) => oldEntry.name == entry.name) != void 0).map((entry) => entry.name);
|
|
415
543
|
const backupTableName = `${tableName}__backup`;
|
|
@@ -419,8 +547,9 @@ ${foreignKeyOnQuery}`;
|
|
|
419
547
|
);
|
|
420
548
|
const moveDataQuery = insertQuery + "\n" + this.dialect.dropTable(tableName) + "\n" + this.dialect.renameTable(backupTableName, tableName);
|
|
421
549
|
const structure = this.newTables[tableName];
|
|
422
|
-
changes.up += this.createTableSql(backupTableName, structure.columns, structure.foreignKeys) + "\n" + moveDataQuery;
|
|
423
|
-
|
|
550
|
+
changes.up += this.createTableSql(backupTableName, structure.columns, structure.foreignKeys) + "\n" + moveDataQuery + "\n";
|
|
551
|
+
const dbTableName = this.migrations.getOldTableName(tableName);
|
|
552
|
+
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";
|
|
424
553
|
}
|
|
425
554
|
return changes;
|
|
426
555
|
}
|
|
@@ -428,8 +557,6 @@ ${foreignKeyOnQuery}`;
|
|
|
428
557
|
* Migrates foreign key constraints for all defined tables.
|
|
429
558
|
*/
|
|
430
559
|
async migrateForeignKeys() {
|
|
431
|
-
if (!this.dialect.canAlterForeignKeys)
|
|
432
|
-
return { up: "", down: "" };
|
|
433
560
|
let changes = {
|
|
434
561
|
up: "\n\n-- Foreign keys\n",
|
|
435
562
|
down: "\n\n-- Foreign keys\n"
|
|
@@ -439,13 +566,13 @@ ${foreignKeyOnQuery}`;
|
|
|
439
566
|
continue;
|
|
440
567
|
const structure = this.newTables[tableName];
|
|
441
568
|
const newForeignKeys = structure.foreignKeys ?? [];
|
|
442
|
-
const oldForeignKeys = await this.dialect.getForeignKeys(tableName);
|
|
569
|
+
const oldForeignKeys = await this.dialect.getForeignKeys(this.migrations.getOldTableName(tableName));
|
|
443
570
|
let checkForNewForeignKeys = true;
|
|
444
571
|
for (const oldForeignKey of oldForeignKeys) {
|
|
445
572
|
const newForeignKey = newForeignKeys.find((entry) => entry.fromColumn == oldForeignKey.fromColumn);
|
|
446
573
|
if (!newForeignKey) {
|
|
447
|
-
Logger.log(`Foreign key ${oldForeignKey.
|
|
448
|
-
this.migrations.
|
|
574
|
+
Logger.log(`Foreign key ${oldForeignKey.fromTable}.${oldForeignKey.fromColumn} to ${oldForeignKey.toTable}.${oldForeignKey.toColumn} will be removed!`);
|
|
575
|
+
this.migrations.compareWithAllowedMigration(tableName, "removeForeignKey");
|
|
449
576
|
if (this.dialect.canAlterForeignKeys) {
|
|
450
577
|
changes.up += this.dialect.removeForeignKey(oldForeignKey.fromTable, oldForeignKey.fromColumn);
|
|
451
578
|
changes.down += this.dialect.addForeignKey(
|
|
@@ -453,13 +580,13 @@ ${foreignKeyOnQuery}`;
|
|
|
453
580
|
this.dialect.foreignKey(oldForeignKey.fromColumn, oldForeignKey.toTable, oldForeignKey.toColumn, oldForeignKey.onUpdate, oldForeignKey.onDelete)
|
|
454
581
|
);
|
|
455
582
|
} else {
|
|
456
|
-
this.migrations.
|
|
583
|
+
this.migrations.internalRecreate(structure.table, "Dialect does not support altering foreign keys");
|
|
457
584
|
checkForNewForeignKeys = false;
|
|
458
585
|
}
|
|
459
586
|
} else {
|
|
460
587
|
if (!newForeignKey || oldForeignKey.toColumn != newForeignKey.toColumn || (oldForeignKey.onUpdate ?? "NO ACTION") != (newForeignKey.onUpdate ?? "NO ACTION") || (oldForeignKey.onDelete ?? "NO ACTION") != (newForeignKey.onDelete ?? "NO ACTION")) {
|
|
461
|
-
Logger.log(`Foreign key ${oldForeignKey.
|
|
462
|
-
this.migrations.
|
|
588
|
+
Logger.log(`Foreign key ${oldForeignKey.fromTable}.${oldForeignKey.fromColumn} to ${oldForeignKey.toTable}.${oldForeignKey.toColumn} will be changed!`);
|
|
589
|
+
this.migrations.compareWithAllowedMigration(tableName, "alterForeignKey");
|
|
463
590
|
if (this.dialect.canAlterForeignKeys) {
|
|
464
591
|
changes.up += this.dialect.removeForeignKey(oldForeignKey.fromTable, oldForeignKey.fromColumn) + this.dialect.addForeignKey(
|
|
465
592
|
newForeignKey.fromTable,
|
|
@@ -470,7 +597,7 @@ ${foreignKeyOnQuery}`;
|
|
|
470
597
|
this.dialect.foreignKey(oldForeignKey.fromColumn, oldForeignKey.toTable, oldForeignKey.toColumn, oldForeignKey.onUpdate, oldForeignKey.onDelete)
|
|
471
598
|
) + this.dialect.removeForeignKey(newForeignKey.fromTable, newForeignKey.fromColumn);
|
|
472
599
|
} else {
|
|
473
|
-
this.migrations.
|
|
600
|
+
this.migrations.internalRecreate(structure.table, "Dialect does not support altering foreign keys");
|
|
474
601
|
checkForNewForeignKeys = false;
|
|
475
602
|
}
|
|
476
603
|
}
|
|
@@ -481,7 +608,7 @@ ${foreignKeyOnQuery}`;
|
|
|
481
608
|
const oldForeignKey = oldForeignKeys.find((entry) => entry.fromColumn == newForeignKey.fromColumn);
|
|
482
609
|
if (oldForeignKey)
|
|
483
610
|
continue;
|
|
484
|
-
Logger.log(`Foreign key ${newForeignKey.
|
|
611
|
+
Logger.log(`Foreign key ${newForeignKey.fromTable}.${newForeignKey.fromColumn} to ${newForeignKey.toTable}.${newForeignKey.toColumn} will be added!`);
|
|
485
612
|
if (this.dialect.canAlterForeignKeys) {
|
|
486
613
|
changes.up += this.dialect.addForeignKey(
|
|
487
614
|
newForeignKey.toTable,
|
|
@@ -489,7 +616,7 @@ ${foreignKeyOnQuery}`;
|
|
|
489
616
|
);
|
|
490
617
|
changes.down += this.dialect.removeForeignKey(newForeignKey.fromTable, newForeignKey.fromColumn);
|
|
491
618
|
} else {
|
|
492
|
-
this.migrations.
|
|
619
|
+
this.migrations.internalRecreate(structure.table, "Dialect does not support altering foreign keys");
|
|
493
620
|
break;
|
|
494
621
|
}
|
|
495
622
|
}
|
|
@@ -510,13 +637,13 @@ ${foreignKeyOnQuery}`;
|
|
|
510
637
|
if (this.migrations.willBeRecreated(tableName) || this.tableDoesNotExists(tableName))
|
|
511
638
|
continue;
|
|
512
639
|
const newTableDefinition = this.newTables[tableName];
|
|
513
|
-
const oldColumnList = await this.dialect.getColumnInformation(tableName);
|
|
640
|
+
const oldColumnList = await this.dialect.getColumnInformation(this.migrations.getOldTableName(tableName));
|
|
514
641
|
const oldPrimaryKey = this.dialect.canInspectPrimaryKey ? this.getPrimaryKeyColumn(oldColumnList) : false;
|
|
515
642
|
const newColumnList = newTableDefinition.columns;
|
|
516
643
|
const newPrimaryKey = newTableDefinition.primaryKey;
|
|
517
644
|
if (this.dialect.canInspectPrimaryKey && oldPrimaryKey != newPrimaryKey) {
|
|
518
|
-
Logger.log(`Primary key in ${tableName}
|
|
519
|
-
this.migrations.
|
|
645
|
+
Logger.log(`Primary key in ${tableName} will be changed from ${oldPrimaryKey} to ${newPrimaryKey}!`);
|
|
646
|
+
this.migrations.compareWithAllowedMigration(tableName, "alterPrimaryKey");
|
|
520
647
|
if (this.dialect.canAlterPrimaryKey) {
|
|
521
648
|
if (oldPrimaryKey) {
|
|
522
649
|
changes.up += this.dialect.removePrimaryKey(tableName, oldPrimaryKey);
|
|
@@ -527,26 +654,26 @@ ${foreignKeyOnQuery}`;
|
|
|
527
654
|
changes.down += this.dialect.removePrimaryKey(tableName, newPrimaryKey.toString());
|
|
528
655
|
}
|
|
529
656
|
} else
|
|
530
|
-
this.migrations.
|
|
657
|
+
this.migrations.internalRecreate(newTableDefinition.table, "Dialect does not support altering primary keys");
|
|
531
658
|
continue;
|
|
532
659
|
}
|
|
533
660
|
for (const newColumn of newColumnList) {
|
|
534
661
|
const oldColumn = oldColumnList.find(
|
|
535
|
-
(entry) => this.migrations.
|
|
662
|
+
(entry) => this.migrations.getNewestColumnName(tableName, entry.name) == newColumn.name
|
|
536
663
|
);
|
|
537
664
|
if (oldColumn == void 0) {
|
|
538
665
|
changes.up += this.dialect.createColumn(tableName, this.dialect.columnDefinition(newColumn.name, newColumn.type, newColumn.defaultValue, newColumn.isPrimaryKey)) + "\n";
|
|
539
666
|
changes.down += this.dialect.dropColumn(tableName, newColumn.name) + "\n";
|
|
540
667
|
} else if (newColumn.type != oldColumn.type || newColumn.defaultValue != oldColumn.defaultValue) {
|
|
541
|
-
this.migrations.
|
|
668
|
+
this.migrations.internalRecreate(newTableDefinition.table, "Table structure was changed");
|
|
542
669
|
}
|
|
543
670
|
}
|
|
544
671
|
for (const oldColumn of oldColumnList) {
|
|
545
672
|
const newColumn = newColumnList.find(
|
|
546
|
-
(entry) => entry.name == this.migrations.
|
|
673
|
+
(entry) => entry.name == this.migrations.getNewestColumnName(tableName, oldColumn.name)
|
|
547
674
|
);
|
|
548
675
|
if (newColumn == void 0) {
|
|
549
|
-
this.migrations.
|
|
676
|
+
this.migrations.compareWithAllowedMigration(tableName, "dropColumn");
|
|
550
677
|
changes.up += this.dialect.dropColumn(tableName, oldColumn.name) + "\n";
|
|
551
678
|
changes.down += this.dialect.createColumn(tableName, this.dialect.columnDefinition(oldColumn.name, oldColumn.type, oldColumn.defaultValue, oldColumn.isPrimaryKey)) + "\n";
|
|
552
679
|
}
|
|
@@ -580,6 +707,7 @@ ${foreignKeyOnQuery}`;
|
|
|
580
707
|
if (migrationData[tableName].recreate)
|
|
581
708
|
continue;
|
|
582
709
|
this.migrations.loopRenamedColumns(tableName, (oldColumnName, newColumnName) => {
|
|
710
|
+
Logger.log(`Column ${tableName}.${oldColumnName} will be renamed to ${tableName}.${newColumnName}!`);
|
|
583
711
|
changes.up += this.dialect.renameColumn(tableName, oldColumnName, newColumnName);
|
|
584
712
|
changes.down += this.dialect.renameColumn(tableName, newColumnName, oldColumnName);
|
|
585
713
|
});
|
|
@@ -646,24 +774,37 @@ ${changes.down}`, { encoding: "utf-8" });
|
|
|
646
774
|
}
|
|
647
775
|
};
|
|
648
776
|
|
|
649
|
-
// src/lib/tableInfo/decorators/
|
|
777
|
+
// src/lib/tableInfo/decorators/TableClass.ts
|
|
650
778
|
import "polyfill-symbol-metadata";
|
|
651
|
-
function
|
|
779
|
+
function TableClass(tableName, primaryKey) {
|
|
652
780
|
return (table, context) => {
|
|
653
|
-
Object.defineProperty(table, "name", { value: tableName, writable: false });
|
|
654
781
|
const tableInfo = context?.metadata ? getTableInfoFromMetadata(context.metadata) : getTableInfo(table);
|
|
655
782
|
tableInfo.primaryKey = primaryKey?.toString();
|
|
656
783
|
if (tableInfo.foreignKeys) {
|
|
657
784
|
for (const foreignKey of tableInfo.foreignKeys) {
|
|
658
785
|
foreignKey.fromTable = tableName;
|
|
786
|
+
if (foreignKey.toTable == table.name)
|
|
787
|
+
foreignKey.toTable = tableName;
|
|
659
788
|
}
|
|
660
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;
|
|
661
802
|
};
|
|
662
803
|
}
|
|
663
804
|
|
|
664
805
|
// src/lib/tableInfo/decorators/ForeignKey.ts
|
|
665
806
|
import "polyfill-symbol-metadata";
|
|
666
|
-
function ForeignKey(toTable, toColumn,
|
|
807
|
+
function ForeignKey(toTable, toColumn, options) {
|
|
667
808
|
return (table, context) => {
|
|
668
809
|
const metadata = context?.metadata ? getTableInfoFromMetadata(context.metadata) : getTableInfo(table);
|
|
669
810
|
if (!metadata.foreignKeys)
|
|
@@ -674,8 +815,8 @@ function ForeignKey(toTable, toColumn, onDelete, onUpdate) {
|
|
|
674
815
|
//to stay compatible with old decorator structure (see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#decorator-metadata)
|
|
675
816
|
toTable: toTable.name,
|
|
676
817
|
toColumn: toColumn.toString(),
|
|
677
|
-
onDelete,
|
|
678
|
-
onUpdate
|
|
818
|
+
onDelete: options?.onDelete,
|
|
819
|
+
onUpdate: options?.onUpdate
|
|
679
820
|
});
|
|
680
821
|
};
|
|
681
822
|
}
|
|
@@ -688,32 +829,108 @@ var DefaultSql = class {
|
|
|
688
829
|
canAlterPrimaryKey = false;
|
|
689
830
|
canInspectForeignKeys = false;
|
|
690
831
|
canInspectPrimaryKey = false;
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
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
|
+
};
|
|
696
842
|
constructor(db) {
|
|
697
843
|
this.db = db;
|
|
698
844
|
}
|
|
699
|
-
|
|
700
|
-
|
|
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
|
+
}
|
|
701
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
|
+
*/
|
|
702
876
|
changeForeignKeysState(enabled) {
|
|
703
877
|
return "";
|
|
704
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
|
+
*/
|
|
705
887
|
addForeignKey(fromTableName, foreignKey) {
|
|
706
888
|
throw new Error("Adding foreign keys is not supported!");
|
|
707
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
|
+
*/
|
|
708
898
|
removeForeignKey(tableName, foreignKeyName) {
|
|
709
899
|
throw new Error("Foreign key removal is not supported!");
|
|
710
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
|
+
*/
|
|
711
909
|
addPrimaryKey(tableName, columnName) {
|
|
712
910
|
throw new Error("Adding foreign keys is not supported!");
|
|
713
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
|
+
*/
|
|
714
920
|
removePrimaryKey(tableName, columnName) {
|
|
715
921
|
throw new Error("Foreign key removal is not supported!");
|
|
716
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
|
+
*/
|
|
717
934
|
foreignKey(column, foreignTable, foreignColumn, onUpdate, onDelete) {
|
|
718
935
|
let query = `FOREIGN KEY (${column}) REFERENCES ${foreignTable} (${foreignColumn})`;
|
|
719
936
|
if (onUpdate)
|
|
@@ -763,7 +980,7 @@ var DefaultSql = class {
|
|
|
763
980
|
}
|
|
764
981
|
migrationTableQuery() {
|
|
765
982
|
return this.createTable(MIGRATION_DATA_TABLE_NAME, [
|
|
766
|
-
this.columnDefinition("version", this.
|
|
983
|
+
this.columnDefinition("version", this.types.number, "0", false)
|
|
767
984
|
]);
|
|
768
985
|
}
|
|
769
986
|
async getForeignKeys(tableName) {
|
|
@@ -792,8 +1009,16 @@ UPDATE ${MIGRATION_DATA_TABLE_NAME} SET version = ${newVersion} WHERE EXISTS (SE
|
|
|
792
1009
|
|
|
793
1010
|
// src/lib/dialects/SqliteDialect.ts
|
|
794
1011
|
var SqliteDialect = class extends DefaultSql {
|
|
795
|
-
|
|
796
|
-
|
|
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
|
+
};
|
|
797
1022
|
canAlterForeignKeys = false;
|
|
798
1023
|
canAlterPrimaryKey = false;
|
|
799
1024
|
canInspectForeignKeys = true;
|
|
@@ -815,12 +1040,19 @@ var SqliteDialect = class extends DefaultSql {
|
|
|
815
1040
|
};
|
|
816
1041
|
});
|
|
817
1042
|
}
|
|
818
|
-
formatValueToSql(value) {
|
|
819
|
-
|
|
1043
|
+
formatValueToSql(value, type) {
|
|
1044
|
+
function toDate(value2) {
|
|
1045
|
+
return value2 instanceof Date ? value2 : new Date(value2);
|
|
1046
|
+
}
|
|
1047
|
+
switch (type) {
|
|
820
1048
|
case "boolean":
|
|
821
1049
|
return value ? "1" : "0";
|
|
1050
|
+
case "date":
|
|
1051
|
+
case "time":
|
|
1052
|
+
case "dateTime":
|
|
1053
|
+
return toDate(value).getTime().toString();
|
|
822
1054
|
default:
|
|
823
|
-
return
|
|
1055
|
+
return super.formatValueToSql(value, type);
|
|
824
1056
|
}
|
|
825
1057
|
}
|
|
826
1058
|
async getForeignKeys(tableName) {
|
|
@@ -1057,8 +1289,10 @@ async function rollback(db, dbInstructions, toVersion) {
|
|
|
1057
1289
|
await dialect.setVersion(toVersion);
|
|
1058
1290
|
}
|
|
1059
1291
|
export {
|
|
1060
|
-
|
|
1292
|
+
DataType,
|
|
1061
1293
|
ForeignKey,
|
|
1294
|
+
TableClass,
|
|
1295
|
+
TableObj,
|
|
1062
1296
|
prepareAndRunMigration,
|
|
1063
1297
|
prepareMigration,
|
|
1064
1298
|
rollback,
|