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