-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(migrate) Allows for currentVersion to be async function
- Loading branch information
1 parent
b58e0b3
commit 56bbaca
Showing
4 changed files
with
92 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,4 @@ | ||
import { runSequence } from "@klw/node-sequential-promises"; | ||
import { Migration, MigrationOptions, MigrationResult, MigrationVersion } from "./types"; | ||
import { migrate } from "./migrate"; | ||
import { Migration, MigrationOptions, MigrationResult, MigrationVersion, MigrationError } from "./types"; | ||
|
||
/** | ||
* Runs your database migrations up and down. | ||
* | ||
* @param migrations - Array of all Migrations. See docs/types for details. | ||
* @param currentVersion - The current version (or null) if the database is not set up yet. | ||
* @param options - Set the target version with {targetVersion: string} | ||
* | ||
* Will fallback to latest version, if target version is not specified. | ||
*/ | ||
export const migrate = async ( | ||
migrations: Migration[], | ||
currentVersion: MigrationVersion | null, | ||
options?: MigrationOptions, | ||
): Promise<MigrationResult | undefined> => { | ||
const latestVersion = migrations[migrations.length - 1].version; | ||
const targetVersion = options?.targetVersion || "latest"; | ||
const newVersion = targetVersion === "latest" ? latestVersion : targetVersion || latestVersion; | ||
const curVersionIndex = migrations.findIndex((x) => x.version === currentVersion); | ||
const newVersionIndex = migrations.findIndex((x) => x.version === newVersion); | ||
|
||
// Don't know what to do with not-matching version | ||
if (currentVersion && curVersionIndex === -1) { | ||
return Promise.reject(`No matching currentVersion (${currentVersion}) found.`); | ||
} | ||
|
||
// Define actual migrations to run | ||
const migrateUp = newVersionIndex >= curVersionIndex; | ||
const steps = migrateUp | ||
? migrations.slice(curVersionIndex + 1, newVersionIndex + 1) | ||
: migrations.slice(newVersionIndex + 1, curVersionIndex + 1).reverse(); | ||
|
||
// Target version number | ||
const returnTargetVersion = migrations[newVersionIndex].version; | ||
|
||
// No migrations to run | ||
if (steps.length === 0) { | ||
return Promise.resolve({ | ||
success: true, | ||
started: [], | ||
fulfilled: [], | ||
direction: "UP", | ||
targetVersion: returnTargetVersion, | ||
}); | ||
} | ||
|
||
// Actually run migrations | ||
const result = await runSequence(steps.map((step) => (migrateUp ? step.up : step.down))); | ||
|
||
const started = result.started.map((index) => steps[index].version); | ||
const fulfilled = result.fulfilled.map((index) => steps[index].version); | ||
return { | ||
targetVersion: returnTargetVersion, | ||
direction: migrateUp ? "UP" : "DOWN", | ||
success: result.success, | ||
started, | ||
fulfilled, | ||
errorMessage: result.error, | ||
}; | ||
}; | ||
export { migrate, Migration, MigrationOptions, MigrationResult, MigrationVersion, MigrationError }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { runSequence } from "@klw/node-sequential-promises"; | ||
import { Migration, MigrationOptions, MigrationResult, MigrationVersion } from "./types"; | ||
|
||
/** | ||
* Runs your database migrations up and down. | ||
* | ||
* @param migrations - Array of all Migrations. See docs/types for details. | ||
* @param currentVersion - The current version (or null) if the database is not set up yet. | ||
* @param options - Set the target version with {targetVersion: string} | ||
* | ||
* Will fallback to latest version, if target version is not specified. | ||
*/ | ||
export const migrate = async ( | ||
migrations: Migration[], | ||
currentVersion: MigrationVersion | null | (() => Promise<MigrationVersion | null>), | ||
options?: MigrationOptions, | ||
): Promise<MigrationResult | undefined> => { | ||
const curVersion = currentVersion instanceof Function ? await currentVersion() : currentVersion; | ||
const latestVersion = migrations[migrations.length - 1].version; | ||
const targetVersion = options?.targetVersion || "latest"; | ||
const newVersion = targetVersion === "latest" ? latestVersion : targetVersion || latestVersion; | ||
const curVersionIndex = migrations.findIndex((x) => x.version === curVersion); | ||
const newVersionIndex = migrations.findIndex((x) => x.version === newVersion); | ||
|
||
// Don't know what to do with not-matching version | ||
if (curVersion && curVersionIndex === -1) { | ||
return Promise.reject(`No matching currentVersion (${curVersion}) found.`); | ||
} | ||
|
||
// Define actual migrations to run | ||
const migrateUp = newVersionIndex >= curVersionIndex; | ||
const steps = migrateUp | ||
? migrations.slice(curVersionIndex + 1, newVersionIndex + 1) | ||
: migrations.slice(newVersionIndex + 1, curVersionIndex + 1).reverse(); | ||
|
||
// Target version number | ||
const returnTargetVersion = migrations[newVersionIndex].version; | ||
|
||
// No migrations to run | ||
if (steps.length === 0) { | ||
return Promise.resolve({ | ||
success: true, | ||
started: [], | ||
fulfilled: [], | ||
direction: "UP", | ||
targetVersion: returnTargetVersion, | ||
}); | ||
} | ||
|
||
// Actually run migrations | ||
const result = await runSequence(steps.map((step) => (migrateUp ? step.up : step.down))); | ||
|
||
const started = result.started.map((index) => steps[index].version); | ||
const fulfilled = result.fulfilled.map((index) => steps[index].version); | ||
return { | ||
targetVersion: returnTargetVersion, | ||
direction: migrateUp ? "UP" : "DOWN", | ||
success: result.success, | ||
started, | ||
fulfilled, | ||
errorMessage: result.error, | ||
}; | ||
}; |