sqlmorpheus 0.1.5 → 0.1.7
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 +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +65 -51
- package/dist/index.mjs +65 -51
- package/package.json +39 -39
package/dist/index.d.mts
CHANGED
|
@@ -124,4 +124,4 @@ declare function prepareAndRunMigration(db: DatabaseAccess, instructions: Databa
|
|
|
124
124
|
declare function runMigrationWithoutHistory(db: DatabaseAccess, instructions: DatabaseInstructions): Promise<void>;
|
|
125
125
|
declare function rollback(db: DatabaseAccess, instructions: DatabaseInstructions, toVersion: number): Promise<void>;
|
|
126
126
|
|
|
127
|
-
export { type DatabaseInstructions, DbTable, ForeignKey, prepareAndRunMigration, prepareMigration, rollback, runMigrationWithoutHistory, runPreparedMigrations };
|
|
127
|
+
export { type DatabaseAccess, type DatabaseInstructions, DbTable, ForeignKey, prepareAndRunMigration, prepareMigration, rollback, runMigrationWithoutHistory, runPreparedMigrations };
|
package/dist/index.d.ts
CHANGED
|
@@ -124,4 +124,4 @@ declare function prepareAndRunMigration(db: DatabaseAccess, instructions: Databa
|
|
|
124
124
|
declare function runMigrationWithoutHistory(db: DatabaseAccess, instructions: DatabaseInstructions): Promise<void>;
|
|
125
125
|
declare function rollback(db: DatabaseAccess, instructions: DatabaseInstructions, toVersion: number): Promise<void>;
|
|
126
126
|
|
|
127
|
-
export { type DatabaseInstructions, DbTable, ForeignKey, prepareAndRunMigration, prepareMigration, rollback, runMigrationWithoutHistory, runPreparedMigrations };
|
|
127
|
+
export { type DatabaseAccess, type DatabaseInstructions, DbTable, ForeignKey, prepareAndRunMigration, prepareMigration, rollback, runMigrationWithoutHistory, runPreparedMigrations };
|
package/dist/index.js
CHANGED
|
@@ -115,7 +115,7 @@ var TableStructureGenerator = class {
|
|
|
115
115
|
columnData.defaultValue = value === null ? this.dialect.typeNull : `"${this.dialect.formatValueToSql(value)}"`;
|
|
116
116
|
break;
|
|
117
117
|
case "number":
|
|
118
|
-
columnData.type = this.dialect.
|
|
118
|
+
columnData.type = this.dialect.typeInt;
|
|
119
119
|
columnData.defaultValue = value === null ? this.dialect.typeNull : this.dialect.formatValueToSql(value);
|
|
120
120
|
break;
|
|
121
121
|
case "boolean":
|
|
@@ -247,43 +247,21 @@ var FILENAME_DOWN_PREFIX = "down_to_";
|
|
|
247
247
|
var MigrationHistoryManager = class {
|
|
248
248
|
configPath;
|
|
249
249
|
migrationsPath;
|
|
250
|
-
lastVersion = 0;
|
|
251
250
|
constructor(configPath) {
|
|
252
251
|
this.configPath = configPath;
|
|
253
252
|
this.migrationsPath = `${configPath}/migrations`;
|
|
254
253
|
(0, import_node_fs.mkdirSync)(this.configPath, { recursive: true });
|
|
255
254
|
(0, import_node_fs.mkdirSync)(this.migrationsPath, { recursive: true });
|
|
256
255
|
}
|
|
257
|
-
/**
|
|
258
|
-
* Retrieves the last recorded history version from the configuration path.
|
|
259
|
-
* If the version is not already cached in memory, this method reads it from a file on disk.
|
|
260
|
-
*
|
|
261
|
-
* @return The last version number, or 0 if the version file does not exist or cannot be parsed.
|
|
262
|
-
*/
|
|
263
|
-
getLastHistoryVersion() {
|
|
264
|
-
if (this.lastVersion)
|
|
265
|
-
return this.lastVersion;
|
|
266
|
-
const path = `${this.configPath}/last_version.txt`;
|
|
267
|
-
this.lastVersion = (0, import_node_fs.existsSync)(path) ? parseInt((0, import_fs.readFileSync)(`${this.configPath}/last_version.txt`, { encoding: "utf-8" })) ?? 0 : 0;
|
|
268
|
-
return this.lastVersion;
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Updates the "last history version" information by writing the given version to a file.
|
|
272
|
-
*
|
|
273
|
-
* @param version - The version number to set as the last history version.
|
|
274
|
-
*/
|
|
275
|
-
setLastHistoryVersion(version) {
|
|
276
|
-
(0, import_node_fs.writeFileSync)(`${this.configPath}/last_version.txt`, version.toString(), { encoding: "utf-8" });
|
|
277
|
-
}
|
|
278
256
|
/**
|
|
279
257
|
* Creates migration history files for upgrading and downgrading database schemas.
|
|
280
258
|
*
|
|
259
|
+
* @param fromVersion - The current version number of the database.
|
|
281
260
|
* @param toVersion - The target version number for the migration.
|
|
282
261
|
* @param changes - An object containing the SQL changes for upgrading (`changes.up`) and downgrading (`changes.down`).
|
|
283
262
|
* @param overwriteExisting - A flag that determines if existing migration files should be overwritten. Defaults to `false`.
|
|
284
263
|
*/
|
|
285
|
-
createMigrationHistory(toVersion, changes, overwriteExisting) {
|
|
286
|
-
const fromVersion = this.getLastHistoryVersion();
|
|
264
|
+
createMigrationHistory(fromVersion, toVersion, changes, overwriteExisting) {
|
|
287
265
|
const upPath = `${this.migrationsPath}/${FILENAME_UP_PREFIX}${toVersion}.sql`;
|
|
288
266
|
const downPath = `${this.migrationsPath}/${FILENAME_DOWN_PREFIX}${fromVersion}.sql`;
|
|
289
267
|
if ((0, import_node_fs.existsSync)(upPath) && !overwriteExisting)
|
|
@@ -306,7 +284,7 @@ ${changes.down}`, { encoding: "utf-8" });
|
|
|
306
284
|
* @return The content of the SQL migration script as a string.
|
|
307
285
|
*/
|
|
308
286
|
getUpMigration(toVersion) {
|
|
309
|
-
return (0, import_fs.readFileSync)(`${this.migrationsPath}/${FILENAME_UP_PREFIX}${toVersion
|
|
287
|
+
return (0, import_fs.readFileSync)(`${this.migrationsPath}/${FILENAME_UP_PREFIX}${toVersion}.sql`, { encoding: "utf-8" });
|
|
310
288
|
}
|
|
311
289
|
/**
|
|
312
290
|
* Retrieves the SQL migration script for downgrading to the specified version.
|
|
@@ -320,13 +298,14 @@ ${changes.down}`, { encoding: "utf-8" });
|
|
|
320
298
|
};
|
|
321
299
|
|
|
322
300
|
// src/lib/dialects/DefaultSql.ts
|
|
301
|
+
var MIGRATION_DATA_TABLE_NAME = "__sqlmorpheus_migrations";
|
|
323
302
|
var DefaultSql = class {
|
|
324
303
|
canAlterForeignKeys = false;
|
|
325
304
|
canAlterPrimaryKey = false;
|
|
326
305
|
canInspectForeignKeys = false;
|
|
327
306
|
canInspectPrimaryKey = false;
|
|
328
307
|
typeString = "TEXT";
|
|
329
|
-
|
|
308
|
+
typeInt = "INTEGER";
|
|
330
309
|
typeBoolean = "BOOLEAN";
|
|
331
310
|
typeNull = "NULL";
|
|
332
311
|
formatValueToSql(value) {
|
|
@@ -369,8 +348,8 @@ var DefaultSql = class {
|
|
|
369
348
|
dropTable(tableName) {
|
|
370
349
|
return `DROP TABLE IF EXISTS ${tableName};`;
|
|
371
350
|
}
|
|
372
|
-
columnDefinition(
|
|
373
|
-
const query = `${
|
|
351
|
+
columnDefinition(columnName, type, defaultValue, isPrimaryKey) {
|
|
352
|
+
const query = `${columnName} ${type} DEFAULT ${defaultValue}`;
|
|
374
353
|
return isPrimaryKey ? `${query} PRIMARY KEY` : query;
|
|
375
354
|
}
|
|
376
355
|
createColumn(columnTable, entry) {
|
|
@@ -397,6 +376,30 @@ var DefaultSql = class {
|
|
|
397
376
|
insertValues(keys, valueString) {
|
|
398
377
|
return `(${keys}) ${valueString ?? `VALUES (${keys.map(() => "?").join(",")})`}`;
|
|
399
378
|
}
|
|
379
|
+
migrationTableQuery() {
|
|
380
|
+
return this.createTable(MIGRATION_DATA_TABLE_NAME, [
|
|
381
|
+
this.columnDefinition("version", this.typeInt, "0", false)
|
|
382
|
+
]);
|
|
383
|
+
}
|
|
384
|
+
async createMigrationTableIfNeeded(db) {
|
|
385
|
+
await db.runMultipleWriteStatements(this.migrationTableQuery());
|
|
386
|
+
}
|
|
387
|
+
//TODO: untested
|
|
388
|
+
async getVersion(db) {
|
|
389
|
+
await this.createMigrationTableIfNeeded(db);
|
|
390
|
+
const query = this.select(MIGRATION_DATA_TABLE_NAME, ["version"]);
|
|
391
|
+
const data = await db.runGetStatement(query);
|
|
392
|
+
return data.length ? data[0].version : 0;
|
|
393
|
+
}
|
|
394
|
+
//TODO: untested
|
|
395
|
+
async setVersion(db, newVersion) {
|
|
396
|
+
const query = `${this.migrationTableQuery()};
|
|
397
|
+
INSERT INTO ${MIGRATION_DATA_TABLE_NAME} (version) VALUES ${newVersion} WHERE NOT EXISTS (SELECT 1 FROM ${MIGRATION_DATA_TABLE_NAME})
|
|
398
|
+
UNION ALL
|
|
399
|
+
UPDATE ${MIGRATION_DATA_TABLE_NAME} SET version = ${newVersion} WHERE EXISTS (SELECT 1 FROM ${MIGRATION_DATA_TABLE_NAME});
|
|
400
|
+
`;
|
|
401
|
+
await db.runMultipleWriteStatements(query);
|
|
402
|
+
}
|
|
400
403
|
};
|
|
401
404
|
|
|
402
405
|
// src/lib/dialects/SqliteDialect.ts
|
|
@@ -444,6 +447,13 @@ var SqliteDialect = class extends DefaultSql {
|
|
|
444
447
|
return value.toString();
|
|
445
448
|
}
|
|
446
449
|
}
|
|
450
|
+
async getVersion(db) {
|
|
451
|
+
const output = await db.runGetStatement(`PRAGMA user_version;`);
|
|
452
|
+
return output[0].user_version;
|
|
453
|
+
}
|
|
454
|
+
async setVersion(db, newVersion) {
|
|
455
|
+
await db.runMultipleWriteStatements(`PRAGMA user_version = ${newVersion};`);
|
|
456
|
+
}
|
|
447
457
|
};
|
|
448
458
|
|
|
449
459
|
// src/lib/dialects/PostgresDialect.ts
|
|
@@ -582,6 +592,22 @@ var MySqlDialect = class extends DefaultSql {
|
|
|
582
592
|
}
|
|
583
593
|
};
|
|
584
594
|
|
|
595
|
+
// src/lib/getDialect.ts
|
|
596
|
+
function getDialect(dbInstructions) {
|
|
597
|
+
switch (dbInstructions.dialect) {
|
|
598
|
+
case "Sqlite":
|
|
599
|
+
return new SqliteDialect();
|
|
600
|
+
case "Postgres":
|
|
601
|
+
return new PostgresDialect();
|
|
602
|
+
case "MsSql":
|
|
603
|
+
return new MsSqlDialect();
|
|
604
|
+
case "MySql":
|
|
605
|
+
return new MySqlDialect();
|
|
606
|
+
default:
|
|
607
|
+
throw new Error(`Unknown dialect ${dbInstructions.dialect}`);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
|
|
585
611
|
// src/lib/MigrationManager.ts
|
|
586
612
|
var MigrationManager = class {
|
|
587
613
|
migrations = new Migrations();
|
|
@@ -592,22 +618,7 @@ var MigrationManager = class {
|
|
|
592
618
|
migrationHistoryManager;
|
|
593
619
|
dialect;
|
|
594
620
|
constructor(db, dbInstructions) {
|
|
595
|
-
|
|
596
|
-
case "Sqlite":
|
|
597
|
-
this.dialect = new SqliteDialect();
|
|
598
|
-
break;
|
|
599
|
-
case "Postgres":
|
|
600
|
-
this.dialect = new PostgresDialect();
|
|
601
|
-
break;
|
|
602
|
-
case "MsSql":
|
|
603
|
-
this.dialect = new MsSqlDialect();
|
|
604
|
-
break;
|
|
605
|
-
case "MySql":
|
|
606
|
-
this.dialect = new MySqlDialect();
|
|
607
|
-
break;
|
|
608
|
-
default:
|
|
609
|
-
throw new Error(`Unknown dialect ${dbInstructions.dialect}`);
|
|
610
|
-
}
|
|
621
|
+
this.dialect = getDialect(dbInstructions);
|
|
611
622
|
this.db = db;
|
|
612
623
|
this.dbInstructions = dbInstructions;
|
|
613
624
|
this.tableStructureGenerator = new TableStructureGenerator(dbInstructions, this.dialect);
|
|
@@ -627,7 +638,7 @@ var MigrationManager = class {
|
|
|
627
638
|
async getMigrateSql() {
|
|
628
639
|
if (this.dbInstructions.version <= 0)
|
|
629
640
|
throw new Error("Cannot migrate to version 0 or lower");
|
|
630
|
-
const fromVersion = this.
|
|
641
|
+
const fromVersion = await this.dialect.getVersion(this.db);
|
|
631
642
|
if (fromVersion == 0) {
|
|
632
643
|
Logger.log(`Creating initial migration to version ${this.dbInstructions.version}`);
|
|
633
644
|
return this.createAndDropTables();
|
|
@@ -703,7 +714,8 @@ ${foreignKeyOnQuery}`;
|
|
|
703
714
|
const changes = await this.getMigrateSql();
|
|
704
715
|
if (!changes)
|
|
705
716
|
return;
|
|
706
|
-
this.
|
|
717
|
+
const fromVersion = await this.dialect.getVersion(this.db);
|
|
718
|
+
this.migrationHistoryManager.createMigrationHistory(fromVersion, this.dbInstructions.version, changes, overwriteExisting);
|
|
707
719
|
}
|
|
708
720
|
/**
|
|
709
721
|
* Generates SQL change statements for creating and dropping tables based on the current table structure
|
|
@@ -1007,7 +1019,8 @@ async function prepareMigration(db, instructions, overwriteExisting) {
|
|
|
1007
1019
|
async function runPreparedMigrations(db, instructions) {
|
|
1008
1020
|
Logger.setMode(instructions.loggerMode);
|
|
1009
1021
|
const migrationHistoryManager = new MigrationHistoryManager(instructions.configPath);
|
|
1010
|
-
const
|
|
1022
|
+
const dialect = getDialect(instructions);
|
|
1023
|
+
const fromVersion = await dialect.getVersion(db);
|
|
1011
1024
|
const toVersion = instructions.version;
|
|
1012
1025
|
if (fromVersion == toVersion)
|
|
1013
1026
|
return;
|
|
@@ -1018,7 +1031,7 @@ async function runPreparedMigrations(db, instructions) {
|
|
|
1018
1031
|
await db.runMultipleWriteStatements(upChanges);
|
|
1019
1032
|
instructions.version = i;
|
|
1020
1033
|
}
|
|
1021
|
-
|
|
1034
|
+
await dialect.setVersion(db, toVersion);
|
|
1022
1035
|
}
|
|
1023
1036
|
async function prepareAndRunMigration(db, instructions, overwriteExisting) {
|
|
1024
1037
|
Logger.setMode(instructions.loggerMode);
|
|
@@ -1035,7 +1048,8 @@ async function runMigrationWithoutHistory(db, instructions) {
|
|
|
1035
1048
|
async function rollback(db, instructions, toVersion) {
|
|
1036
1049
|
Logger.setMode(instructions.loggerMode);
|
|
1037
1050
|
const migrationHistoryManager = new MigrationHistoryManager(instructions.configPath);
|
|
1038
|
-
const
|
|
1051
|
+
const dialect = getDialect(instructions);
|
|
1052
|
+
const fromVersion = await dialect.getVersion(db);
|
|
1039
1053
|
Logger.log(`Rolling back from ${fromVersion} to ${toVersion}`);
|
|
1040
1054
|
for (let i = fromVersion - 1; i >= toVersion; --i) {
|
|
1041
1055
|
const upChanges = migrationHistoryManager.getDownMigration(i);
|
|
@@ -1043,7 +1057,7 @@ async function rollback(db, instructions, toVersion) {
|
|
|
1043
1057
|
await db.runMultipleWriteStatements(upChanges);
|
|
1044
1058
|
instructions.version = i;
|
|
1045
1059
|
}
|
|
1046
|
-
|
|
1060
|
+
await dialect.setVersion(db, toVersion);
|
|
1047
1061
|
}
|
|
1048
1062
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1049
1063
|
0 && (module.exports = {
|
package/dist/index.mjs
CHANGED
|
@@ -83,7 +83,7 @@ var TableStructureGenerator = class {
|
|
|
83
83
|
columnData.defaultValue = value === null ? this.dialect.typeNull : `"${this.dialect.formatValueToSql(value)}"`;
|
|
84
84
|
break;
|
|
85
85
|
case "number":
|
|
86
|
-
columnData.type = this.dialect.
|
|
86
|
+
columnData.type = this.dialect.typeInt;
|
|
87
87
|
columnData.defaultValue = value === null ? this.dialect.typeNull : this.dialect.formatValueToSql(value);
|
|
88
88
|
break;
|
|
89
89
|
case "boolean":
|
|
@@ -215,43 +215,21 @@ var FILENAME_DOWN_PREFIX = "down_to_";
|
|
|
215
215
|
var MigrationHistoryManager = class {
|
|
216
216
|
configPath;
|
|
217
217
|
migrationsPath;
|
|
218
|
-
lastVersion = 0;
|
|
219
218
|
constructor(configPath) {
|
|
220
219
|
this.configPath = configPath;
|
|
221
220
|
this.migrationsPath = `${configPath}/migrations`;
|
|
222
221
|
mkdirSync(this.configPath, { recursive: true });
|
|
223
222
|
mkdirSync(this.migrationsPath, { recursive: true });
|
|
224
223
|
}
|
|
225
|
-
/**
|
|
226
|
-
* Retrieves the last recorded history version from the configuration path.
|
|
227
|
-
* If the version is not already cached in memory, this method reads it from a file on disk.
|
|
228
|
-
*
|
|
229
|
-
* @return The last version number, or 0 if the version file does not exist or cannot be parsed.
|
|
230
|
-
*/
|
|
231
|
-
getLastHistoryVersion() {
|
|
232
|
-
if (this.lastVersion)
|
|
233
|
-
return this.lastVersion;
|
|
234
|
-
const path = `${this.configPath}/last_version.txt`;
|
|
235
|
-
this.lastVersion = existsSync(path) ? parseInt(readFileSync(`${this.configPath}/last_version.txt`, { encoding: "utf-8" })) ?? 0 : 0;
|
|
236
|
-
return this.lastVersion;
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Updates the "last history version" information by writing the given version to a file.
|
|
240
|
-
*
|
|
241
|
-
* @param version - The version number to set as the last history version.
|
|
242
|
-
*/
|
|
243
|
-
setLastHistoryVersion(version) {
|
|
244
|
-
writeFileSync(`${this.configPath}/last_version.txt`, version.toString(), { encoding: "utf-8" });
|
|
245
|
-
}
|
|
246
224
|
/**
|
|
247
225
|
* Creates migration history files for upgrading and downgrading database schemas.
|
|
248
226
|
*
|
|
227
|
+
* @param fromVersion - The current version number of the database.
|
|
249
228
|
* @param toVersion - The target version number for the migration.
|
|
250
229
|
* @param changes - An object containing the SQL changes for upgrading (`changes.up`) and downgrading (`changes.down`).
|
|
251
230
|
* @param overwriteExisting - A flag that determines if existing migration files should be overwritten. Defaults to `false`.
|
|
252
231
|
*/
|
|
253
|
-
createMigrationHistory(toVersion, changes, overwriteExisting) {
|
|
254
|
-
const fromVersion = this.getLastHistoryVersion();
|
|
232
|
+
createMigrationHistory(fromVersion, toVersion, changes, overwriteExisting) {
|
|
255
233
|
const upPath = `${this.migrationsPath}/${FILENAME_UP_PREFIX}${toVersion}.sql`;
|
|
256
234
|
const downPath = `${this.migrationsPath}/${FILENAME_DOWN_PREFIX}${fromVersion}.sql`;
|
|
257
235
|
if (existsSync(upPath) && !overwriteExisting)
|
|
@@ -274,7 +252,7 @@ ${changes.down}`, { encoding: "utf-8" });
|
|
|
274
252
|
* @return The content of the SQL migration script as a string.
|
|
275
253
|
*/
|
|
276
254
|
getUpMigration(toVersion) {
|
|
277
|
-
return readFileSync(`${this.migrationsPath}/${FILENAME_UP_PREFIX}${toVersion
|
|
255
|
+
return readFileSync(`${this.migrationsPath}/${FILENAME_UP_PREFIX}${toVersion}.sql`, { encoding: "utf-8" });
|
|
278
256
|
}
|
|
279
257
|
/**
|
|
280
258
|
* Retrieves the SQL migration script for downgrading to the specified version.
|
|
@@ -288,13 +266,14 @@ ${changes.down}`, { encoding: "utf-8" });
|
|
|
288
266
|
};
|
|
289
267
|
|
|
290
268
|
// src/lib/dialects/DefaultSql.ts
|
|
269
|
+
var MIGRATION_DATA_TABLE_NAME = "__sqlmorpheus_migrations";
|
|
291
270
|
var DefaultSql = class {
|
|
292
271
|
canAlterForeignKeys = false;
|
|
293
272
|
canAlterPrimaryKey = false;
|
|
294
273
|
canInspectForeignKeys = false;
|
|
295
274
|
canInspectPrimaryKey = false;
|
|
296
275
|
typeString = "TEXT";
|
|
297
|
-
|
|
276
|
+
typeInt = "INTEGER";
|
|
298
277
|
typeBoolean = "BOOLEAN";
|
|
299
278
|
typeNull = "NULL";
|
|
300
279
|
formatValueToSql(value) {
|
|
@@ -337,8 +316,8 @@ var DefaultSql = class {
|
|
|
337
316
|
dropTable(tableName) {
|
|
338
317
|
return `DROP TABLE IF EXISTS ${tableName};`;
|
|
339
318
|
}
|
|
340
|
-
columnDefinition(
|
|
341
|
-
const query = `${
|
|
319
|
+
columnDefinition(columnName, type, defaultValue, isPrimaryKey) {
|
|
320
|
+
const query = `${columnName} ${type} DEFAULT ${defaultValue}`;
|
|
342
321
|
return isPrimaryKey ? `${query} PRIMARY KEY` : query;
|
|
343
322
|
}
|
|
344
323
|
createColumn(columnTable, entry) {
|
|
@@ -365,6 +344,30 @@ var DefaultSql = class {
|
|
|
365
344
|
insertValues(keys, valueString) {
|
|
366
345
|
return `(${keys}) ${valueString ?? `VALUES (${keys.map(() => "?").join(",")})`}`;
|
|
367
346
|
}
|
|
347
|
+
migrationTableQuery() {
|
|
348
|
+
return this.createTable(MIGRATION_DATA_TABLE_NAME, [
|
|
349
|
+
this.columnDefinition("version", this.typeInt, "0", false)
|
|
350
|
+
]);
|
|
351
|
+
}
|
|
352
|
+
async createMigrationTableIfNeeded(db) {
|
|
353
|
+
await db.runMultipleWriteStatements(this.migrationTableQuery());
|
|
354
|
+
}
|
|
355
|
+
//TODO: untested
|
|
356
|
+
async getVersion(db) {
|
|
357
|
+
await this.createMigrationTableIfNeeded(db);
|
|
358
|
+
const query = this.select(MIGRATION_DATA_TABLE_NAME, ["version"]);
|
|
359
|
+
const data = await db.runGetStatement(query);
|
|
360
|
+
return data.length ? data[0].version : 0;
|
|
361
|
+
}
|
|
362
|
+
//TODO: untested
|
|
363
|
+
async setVersion(db, newVersion) {
|
|
364
|
+
const query = `${this.migrationTableQuery()};
|
|
365
|
+
INSERT INTO ${MIGRATION_DATA_TABLE_NAME} (version) VALUES ${newVersion} WHERE NOT EXISTS (SELECT 1 FROM ${MIGRATION_DATA_TABLE_NAME})
|
|
366
|
+
UNION ALL
|
|
367
|
+
UPDATE ${MIGRATION_DATA_TABLE_NAME} SET version = ${newVersion} WHERE EXISTS (SELECT 1 FROM ${MIGRATION_DATA_TABLE_NAME});
|
|
368
|
+
`;
|
|
369
|
+
await db.runMultipleWriteStatements(query);
|
|
370
|
+
}
|
|
368
371
|
};
|
|
369
372
|
|
|
370
373
|
// src/lib/dialects/SqliteDialect.ts
|
|
@@ -412,6 +415,13 @@ var SqliteDialect = class extends DefaultSql {
|
|
|
412
415
|
return value.toString();
|
|
413
416
|
}
|
|
414
417
|
}
|
|
418
|
+
async getVersion(db) {
|
|
419
|
+
const output = await db.runGetStatement(`PRAGMA user_version;`);
|
|
420
|
+
return output[0].user_version;
|
|
421
|
+
}
|
|
422
|
+
async setVersion(db, newVersion) {
|
|
423
|
+
await db.runMultipleWriteStatements(`PRAGMA user_version = ${newVersion};`);
|
|
424
|
+
}
|
|
415
425
|
};
|
|
416
426
|
|
|
417
427
|
// src/lib/dialects/PostgresDialect.ts
|
|
@@ -550,6 +560,22 @@ var MySqlDialect = class extends DefaultSql {
|
|
|
550
560
|
}
|
|
551
561
|
};
|
|
552
562
|
|
|
563
|
+
// src/lib/getDialect.ts
|
|
564
|
+
function getDialect(dbInstructions) {
|
|
565
|
+
switch (dbInstructions.dialect) {
|
|
566
|
+
case "Sqlite":
|
|
567
|
+
return new SqliteDialect();
|
|
568
|
+
case "Postgres":
|
|
569
|
+
return new PostgresDialect();
|
|
570
|
+
case "MsSql":
|
|
571
|
+
return new MsSqlDialect();
|
|
572
|
+
case "MySql":
|
|
573
|
+
return new MySqlDialect();
|
|
574
|
+
default:
|
|
575
|
+
throw new Error(`Unknown dialect ${dbInstructions.dialect}`);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
553
579
|
// src/lib/MigrationManager.ts
|
|
554
580
|
var MigrationManager = class {
|
|
555
581
|
migrations = new Migrations();
|
|
@@ -560,22 +586,7 @@ var MigrationManager = class {
|
|
|
560
586
|
migrationHistoryManager;
|
|
561
587
|
dialect;
|
|
562
588
|
constructor(db, dbInstructions) {
|
|
563
|
-
|
|
564
|
-
case "Sqlite":
|
|
565
|
-
this.dialect = new SqliteDialect();
|
|
566
|
-
break;
|
|
567
|
-
case "Postgres":
|
|
568
|
-
this.dialect = new PostgresDialect();
|
|
569
|
-
break;
|
|
570
|
-
case "MsSql":
|
|
571
|
-
this.dialect = new MsSqlDialect();
|
|
572
|
-
break;
|
|
573
|
-
case "MySql":
|
|
574
|
-
this.dialect = new MySqlDialect();
|
|
575
|
-
break;
|
|
576
|
-
default:
|
|
577
|
-
throw new Error(`Unknown dialect ${dbInstructions.dialect}`);
|
|
578
|
-
}
|
|
589
|
+
this.dialect = getDialect(dbInstructions);
|
|
579
590
|
this.db = db;
|
|
580
591
|
this.dbInstructions = dbInstructions;
|
|
581
592
|
this.tableStructureGenerator = new TableStructureGenerator(dbInstructions, this.dialect);
|
|
@@ -595,7 +606,7 @@ var MigrationManager = class {
|
|
|
595
606
|
async getMigrateSql() {
|
|
596
607
|
if (this.dbInstructions.version <= 0)
|
|
597
608
|
throw new Error("Cannot migrate to version 0 or lower");
|
|
598
|
-
const fromVersion = this.
|
|
609
|
+
const fromVersion = await this.dialect.getVersion(this.db);
|
|
599
610
|
if (fromVersion == 0) {
|
|
600
611
|
Logger.log(`Creating initial migration to version ${this.dbInstructions.version}`);
|
|
601
612
|
return this.createAndDropTables();
|
|
@@ -671,7 +682,8 @@ ${foreignKeyOnQuery}`;
|
|
|
671
682
|
const changes = await this.getMigrateSql();
|
|
672
683
|
if (!changes)
|
|
673
684
|
return;
|
|
674
|
-
this.
|
|
685
|
+
const fromVersion = await this.dialect.getVersion(this.db);
|
|
686
|
+
this.migrationHistoryManager.createMigrationHistory(fromVersion, this.dbInstructions.version, changes, overwriteExisting);
|
|
675
687
|
}
|
|
676
688
|
/**
|
|
677
689
|
* Generates SQL change statements for creating and dropping tables based on the current table structure
|
|
@@ -975,7 +987,8 @@ async function prepareMigration(db, instructions, overwriteExisting) {
|
|
|
975
987
|
async function runPreparedMigrations(db, instructions) {
|
|
976
988
|
Logger.setMode(instructions.loggerMode);
|
|
977
989
|
const migrationHistoryManager = new MigrationHistoryManager(instructions.configPath);
|
|
978
|
-
const
|
|
990
|
+
const dialect = getDialect(instructions);
|
|
991
|
+
const fromVersion = await dialect.getVersion(db);
|
|
979
992
|
const toVersion = instructions.version;
|
|
980
993
|
if (fromVersion == toVersion)
|
|
981
994
|
return;
|
|
@@ -986,7 +999,7 @@ async function runPreparedMigrations(db, instructions) {
|
|
|
986
999
|
await db.runMultipleWriteStatements(upChanges);
|
|
987
1000
|
instructions.version = i;
|
|
988
1001
|
}
|
|
989
|
-
|
|
1002
|
+
await dialect.setVersion(db, toVersion);
|
|
990
1003
|
}
|
|
991
1004
|
async function prepareAndRunMigration(db, instructions, overwriteExisting) {
|
|
992
1005
|
Logger.setMode(instructions.loggerMode);
|
|
@@ -1003,7 +1016,8 @@ async function runMigrationWithoutHistory(db, instructions) {
|
|
|
1003
1016
|
async function rollback(db, instructions, toVersion) {
|
|
1004
1017
|
Logger.setMode(instructions.loggerMode);
|
|
1005
1018
|
const migrationHistoryManager = new MigrationHistoryManager(instructions.configPath);
|
|
1006
|
-
const
|
|
1019
|
+
const dialect = getDialect(instructions);
|
|
1020
|
+
const fromVersion = await dialect.getVersion(db);
|
|
1007
1021
|
Logger.log(`Rolling back from ${fromVersion} to ${toVersion}`);
|
|
1008
1022
|
for (let i = fromVersion - 1; i >= toVersion; --i) {
|
|
1009
1023
|
const upChanges = migrationHistoryManager.getDownMigration(i);
|
|
@@ -1011,7 +1025,7 @@ async function rollback(db, instructions, toVersion) {
|
|
|
1011
1025
|
await db.runMultipleWriteStatements(upChanges);
|
|
1012
1026
|
instructions.version = i;
|
|
1013
1027
|
}
|
|
1014
|
-
|
|
1028
|
+
await dialect.setVersion(db, toVersion);
|
|
1015
1029
|
}
|
|
1016
1030
|
export {
|
|
1017
1031
|
DbTable,
|
package/package.json
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "sqlmorpheus",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"author": "JodliDev",
|
|
5
|
-
"keywords": [],
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"description": "",
|
|
8
|
-
"repository": {
|
|
9
|
-
"type": "git",
|
|
10
|
-
"url": "git://github.com/JodliDev/SqlMorpheus.git"
|
|
11
|
-
},
|
|
12
|
-
"bugs": {
|
|
13
|
-
"url": "https://github.com/JodliDev/SqlMorpheus/issues"
|
|
14
|
-
},
|
|
15
|
-
"homepage": "https://github.com/JodliDev/SqlMorpheus#readme",
|
|
16
|
-
"main": "dist/index.js",
|
|
17
|
-
"types": "dist/index.d.ts",
|
|
18
|
-
"files": [
|
|
19
|
-
"/dist"
|
|
20
|
-
],
|
|
21
|
-
"scripts": {
|
|
22
|
-
"build": "tsup",
|
|
23
|
-
"dev": "tsup --watch",
|
|
24
|
-
"test": "vitest run",
|
|
25
|
-
"test:watch": "vitest",
|
|
26
|
-
"
|
|
27
|
-
},
|
|
28
|
-
"devDependencies": {
|
|
29
|
-
"@types/better-sqlite3": "^7.6.13",
|
|
30
|
-
"@types/node": "^24.0.13",
|
|
31
|
-
"better-sqlite3": "^12.2.0",
|
|
32
|
-
"tsup": "^8.5.0",
|
|
33
|
-
"typescript": "^5.8.3",
|
|
34
|
-
"vitest": "^3.2.4"
|
|
35
|
-
},
|
|
36
|
-
"dependencies": {
|
|
37
|
-
"polyfill-symbol-metadata": "^0.0.2"
|
|
38
|
-
}
|
|
39
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "sqlmorpheus",
|
|
3
|
+
"version": "0.1.7",
|
|
4
|
+
"author": "JodliDev",
|
|
5
|
+
"keywords": [],
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"description": "",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git://github.com/JodliDev/SqlMorpheus.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/JodliDev/SqlMorpheus/issues"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/JodliDev/SqlMorpheus#readme",
|
|
16
|
+
"main": "dist/index.js",
|
|
17
|
+
"types": "dist/index.d.ts",
|
|
18
|
+
"files": [
|
|
19
|
+
"/dist"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup",
|
|
23
|
+
"dev": "tsup --watch",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"test:watch": "vitest",
|
|
26
|
+
"run_publish": "npm run build && npm publish"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
30
|
+
"@types/node": "^24.0.13",
|
|
31
|
+
"better-sqlite3": "^12.2.0",
|
|
32
|
+
"tsup": "^8.5.0",
|
|
33
|
+
"typescript": "^5.8.3",
|
|
34
|
+
"vitest": "^3.2.4"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"polyfill-symbol-metadata": "^0.0.2"
|
|
38
|
+
}
|
|
39
|
+
}
|