Add an API interface for performing DB migrations as required
This commit is contained in:
parent
2567f5fb62
commit
1e007af52a
6 changed files with 83 additions and 0 deletions
|
|
@ -45,6 +45,7 @@ export default [
|
||||||
},
|
},
|
||||||
languageOptions: {
|
languageOptions: {
|
||||||
globals: {
|
globals: {
|
||||||
|
__TITLE__: `readonly`,
|
||||||
__ID__: `readonly`,
|
__ID__: `readonly`,
|
||||||
__VERSION__: `readonly`,
|
__VERSION__: `readonly`,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,38 @@ Hooks.on(`ready`, () => {
|
||||||
CONFIG.stats.db = NilDatabase;
|
CONFIG.stats.db = NilDatabase;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Perform any required data migration if any is required for the version
|
||||||
|
jump that the user may have caused. This only migrates the data iff the
|
||||||
|
currently authenticated user is able to perform the full migration of
|
||||||
|
data.
|
||||||
|
*/
|
||||||
|
const db = CONFIG.stats.db;
|
||||||
|
const lastVersion = game.settings.get(__ID__, `lastVersion`);
|
||||||
|
const canDoMigration = db.canPerformMigration();
|
||||||
|
const requiresMigration = db.requiresMigrationFrom(lastVersion);
|
||||||
|
if (requiresMigration) {
|
||||||
|
if (canDoMigration) {
|
||||||
|
const notif = ui.notifications.info(
|
||||||
|
`${__TITLE__} | Performing data migration, please do not close the window`,
|
||||||
|
{ progress: true, permanent: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fire and forget
|
||||||
|
CONFIG.stats.db.migrateData(notif)
|
||||||
|
.then(() => {
|
||||||
|
game.settings.set(__ID__, __VERSION__);
|
||||||
|
setTimeout(() => ui.notifications.remove(notif), 500);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ui.notifications.error(
|
||||||
|
`The stat-tracker database is out of date, temporarily disabling the stat-tracker module's functionality until the migration can be performed by a GM user logging into the world.`,
|
||||||
|
{ console: false, permanent: true },
|
||||||
|
);
|
||||||
|
CONFIG.stats.db = NilDatabase;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Prevent any run-time modifications to the CONFIG API so that users can't wreck
|
Prevent any run-time modifications to the CONFIG API so that users can't wreck
|
||||||
themselves nor their data by fooling around with the values.
|
themselves nor their data by fooling around with the values.
|
||||||
|
|
|
||||||
|
|
@ -23,4 +23,11 @@ export function registerMetaSettings() {
|
||||||
config: false,
|
config: false,
|
||||||
requiresReload: false,
|
requiresReload: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
game.settings.register(__ID__, `lastVersion`, {
|
||||||
|
scope: `world`,
|
||||||
|
type: String,
|
||||||
|
config: false,
|
||||||
|
requiresReload: false,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,43 @@ export class Database {
|
||||||
static async triggerListeners() {};
|
static async triggerListeners() {};
|
||||||
|
|
||||||
static async unregisterListeners() {};
|
static async unregisterListeners() {};
|
||||||
|
|
||||||
|
// MARK: Migrations
|
||||||
|
/**
|
||||||
|
* Determines if the currently authenticated user is capable of running
|
||||||
|
* the full migration on their own.
|
||||||
|
*
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
static async canPerformMigration() {
|
||||||
|
// TODO: this *must* account for isActiveGM, because otherwise the
|
||||||
|
// world setting cannot be updated after the migration finishes.
|
||||||
|
return game.user.isActiveGM;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the previous version of the plugin that was active
|
||||||
|
* needs to be migrated in order to work with the new version.
|
||||||
|
*
|
||||||
|
* @param {string} lastVersion The version that was last active
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
static async requiresMigrationFrom(lastVersion) {
|
||||||
|
return foundry.utils.isNewerVersion(__VERSION__, lastVersion);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method migrates ALL of the database data from one version of
|
||||||
|
* the module to the currently installed module. This is not guaranteed
|
||||||
|
* to run only on one client, so it should be made to be either
|
||||||
|
* idempotent, or have an operation locking mechanism that can prevent
|
||||||
|
* other clients from executing it if there's a migration in-progress.
|
||||||
|
*
|
||||||
|
* @param {string} lastVersion The last version that the user had active
|
||||||
|
* @param {Notification} notif The progress bar notification used for
|
||||||
|
* user feedback while performing migrations.
|
||||||
|
*/
|
||||||
|
static async migrateData(lastVersion, notif) {};
|
||||||
};
|
};
|
||||||
|
|
||||||
/* eslint-enable no-unused-vars */
|
/* eslint-enable no-unused-vars */
|
||||||
|
|
|
||||||
|
|
@ -31,4 +31,9 @@ export class NilDatabase extends Database {
|
||||||
static async registerListeners() {};
|
static async registerListeners() {};
|
||||||
static async triggerListeners() {};
|
static async triggerListeners() {};
|
||||||
static async unregisterListeners() {};
|
static async unregisterListeners() {};
|
||||||
|
|
||||||
|
// MARK: Migrations
|
||||||
|
static async canPerformMigration() { return true };
|
||||||
|
static async requiresMigrationFrom() { return false };
|
||||||
|
static async migrateData() {};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ export default defineConfig(({ mode }) => {
|
||||||
return {
|
return {
|
||||||
plugins,
|
plugins,
|
||||||
define: {
|
define: {
|
||||||
|
__TITLE__: JSON.stringify(manifest.title),
|
||||||
__ID__: JSON.stringify(manifest.id),
|
__ID__: JSON.stringify(manifest.id),
|
||||||
__VERSION__: JSON.stringify(manifest.version),
|
__VERSION__: JSON.stringify(manifest.version),
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue