signal-desktop/js/modules/migrations/run_migrations.js

80 lines
2.2 KiB
JavaScript
Raw Normal View History

/* eslint-env browser */
2018-04-27 21:25:04 +00:00
const { head, isFunction, isObject, isString, last } = require('lodash');
2018-03-26 19:17:19 +00:00
const db = require('../database');
const { deferredToPromise } = require('../deferred_to_promise');
2018-03-26 19:17:19 +00:00
const closeDatabaseConnection = ({ Backbone } = {}) =>
deferredToPromise(Backbone.sync('closeall'));
exports.runMigrations = async ({ Backbone, database, logger } = {}) => {
2018-04-27 21:25:04 +00:00
if (
!isObject(Backbone) ||
!isObject(Backbone.Collection) ||
!isFunction(Backbone.Collection.extend)
) {
throw new TypeError('runMigrations: Backbone is required');
2018-03-26 19:17:19 +00:00
}
2018-04-27 21:25:04 +00:00
if (
!isObject(database) ||
!isString(database.id) ||
!Array.isArray(database.migrations)
) {
throw new TypeError('runMigrations: database is required');
}
if (!isObject(logger)) {
throw new TypeError('runMigrations: logger is required');
2018-03-26 19:17:19 +00:00
}
const {
firstVersion: firstMigrationVersion,
lastVersion: lastMigrationVersion,
} = getMigrationVersions(database);
const databaseVersion = await db.getVersion(database.id);
const isAlreadyUpgraded = databaseVersion >= lastMigrationVersion;
logger.info('Database status', {
firstMigrationVersion,
lastMigrationVersion,
databaseVersion,
isAlreadyUpgraded,
});
if (isAlreadyUpgraded) {
return;
}
2018-03-26 19:17:19 +00:00
const migrationCollection = new (Backbone.Collection.extend({
database,
storeName: 'items',
}))();
2018-10-18 01:01:21 +00:00
// Note: this legacy migration technique is required to bring old clients with
// data in IndexedDB forward into the new world of SQLCipher only.
await deferredToPromise(migrationCollection.fetch({ limit: 1 }));
2018-10-18 01:01:21 +00:00
logger.info('Close database connection');
await closeDatabaseConnection({ Backbone });
2018-03-26 19:17:19 +00:00
};
2018-03-28 17:05:49 +00:00
2018-04-27 21:25:04 +00:00
const getMigrationVersions = database => {
2018-03-28 17:05:49 +00:00
if (!isObject(database) || !Array.isArray(database.migrations)) {
2018-04-11 19:44:52 +00:00
throw new TypeError("'database' is required");
2018-03-28 17:05:49 +00:00
}
const firstMigration = head(database.migrations);
const lastMigration = last(database.migrations);
2018-04-27 21:25:04 +00:00
const firstVersion = firstMigration
? parseInt(firstMigration.version, 10)
: null;
const lastVersion = lastMigration
? parseInt(lastMigration.version, 10)
: null;
2018-03-28 17:05:49 +00:00
return { firstVersion, lastVersion };
};