Conditionally run post-attachment migrations
Introduce placeholder migrations for Backbone models so they never implicitly run migrations whenever they are `fetch`ed. We prefer to run our migrations explicitly upon app startup and then let Backbone models be (slightly) dumb(er) models, without inadvertently triggering migrations.
This commit is contained in:
parent
887bd83852
commit
805031ade8
6 changed files with 87 additions and 25 deletions
|
@ -83,23 +83,15 @@
|
||||||
const cancelInitializationMessage = Views.Initialization.setMessage();
|
const cancelInitializationMessage = Views.Initialization.setMessage();
|
||||||
console.log('Start IndexedDB migrations');
|
console.log('Start IndexedDB migrations');
|
||||||
|
|
||||||
console.log('Migrate database with attachments');
|
console.log('Run migrations on database with attachment data');
|
||||||
await Migrations0DatabaseWithAttachmentData.run({ Backbone });
|
await Migrations0DatabaseWithAttachmentData.run({ Backbone });
|
||||||
|
|
||||||
// console.log('Migrate attachments to disk');
|
const database = Whisper.Database;
|
||||||
// const database = Migrations0DatabaseWithAttachmentData.getDatabase();
|
const status = await Migrations1DatabaseWithoutAttachmentData.getStatus({ database });
|
||||||
// await MessageDataMigrator.processAll({
|
console.log('Run migrations on database without attachment data:', status);
|
||||||
// Backbone,
|
if (status.canRun) {
|
||||||
// databaseName: database.name,
|
await Migrations1DatabaseWithoutAttachmentData.run({ Backbone, database });
|
||||||
// minDatabaseVersion: database.version,
|
}
|
||||||
// upgradeMessageSchema,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// console.log('Migrate database without attachments');
|
|
||||||
// await Migrations1DatabaseWithoutAttachmentData.run({
|
|
||||||
// Backbone,
|
|
||||||
// database: Whisper.Database,
|
|
||||||
// });
|
|
||||||
|
|
||||||
console.log('Storage fetch');
|
console.log('Storage fetch');
|
||||||
storage.fetch();
|
storage.fetch();
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { Migrations0DatabaseWithAttachmentData } = window.Signal.Migrations;
|
const { getPlaceholderMigrations } = window.Signal.Migrations;
|
||||||
|
|
||||||
window.Whisper = window.Whisper || {};
|
window.Whisper = window.Whisper || {};
|
||||||
window.Whisper.Database = window.Whisper.Database || {};
|
window.Whisper.Database = window.Whisper.Database || {};
|
||||||
|
@ -123,5 +123,5 @@
|
||||||
request.onsuccess = resolve;
|
request.onsuccess = resolve;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Whisper.Database.migrations = Migrations0DatabaseWithAttachmentData.migrations;
|
Whisper.Database.migrations = getPlaceholderMigrations();
|
||||||
}());
|
}());
|
||||||
|
|
23
js/modules/migrations/get_placeholder_migrations.js
Normal file
23
js/modules/migrations/get_placeholder_migrations.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
const Migrations0DatabaseWithAttachmentData =
|
||||||
|
require('./migrations_0_database_with_attachment_data');
|
||||||
|
const Migrations1DatabaseWithoutAttachmentData =
|
||||||
|
require('./migrations_1_database_without_attachment_data');
|
||||||
|
|
||||||
|
|
||||||
|
exports.getPlaceholderMigrations = () => {
|
||||||
|
const last0MigrationVersion =
|
||||||
|
Migrations0DatabaseWithAttachmentData.getLatestVersion();
|
||||||
|
const last1MigrationVersion =
|
||||||
|
Migrations1DatabaseWithoutAttachmentData.getLatestVersion();
|
||||||
|
|
||||||
|
const lastMigrationVersion = last1MigrationVersion || last0MigrationVersion;
|
||||||
|
|
||||||
|
return [{
|
||||||
|
version: lastMigrationVersion,
|
||||||
|
migrate() {
|
||||||
|
throw new Error('Unexpected invocation of placeholder migration!' +
|
||||||
|
'\n\nMigrations must explicitly be run upon application startup instead' +
|
||||||
|
' of implicitly via Backbone IndexedDB adapter at any time.');
|
||||||
|
},
|
||||||
|
}];
|
||||||
|
};
|
|
@ -154,3 +154,12 @@ exports.getDatabase = () => ({
|
||||||
name: database.id,
|
name: database.id,
|
||||||
version: last(exports.migrations).version,
|
version: last(exports.migrations).version,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
exports.getLatestVersion = () => {
|
||||||
|
const lastMigration = last(migrations);
|
||||||
|
if (!lastMigration) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastMigration.version;
|
||||||
|
};
|
||||||
|
|
|
@ -1,15 +1,50 @@
|
||||||
|
const last = require('lodash/last');
|
||||||
|
|
||||||
|
const db = require('../database');
|
||||||
|
const settings = require('../settings');
|
||||||
const { runMigrations } = require('./run_migrations');
|
const { runMigrations } = require('./run_migrations');
|
||||||
|
|
||||||
|
|
||||||
exports.migrations = [
|
// NOTE: Add new migrations that need to traverse entire database, e.g. messages
|
||||||
|
// store, here. These will only run after attachment migration has completed in
|
||||||
|
// the background:
|
||||||
|
const migrations = [
|
||||||
// {
|
// {
|
||||||
// version: 18,
|
// version: 0,
|
||||||
// async migrate(transaction, next) {
|
// migrate(transaction, next) {
|
||||||
// console.log('Migration 18');
|
|
||||||
// console.log('Attachments stored on disk');
|
|
||||||
// next();
|
// next();
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
];
|
];
|
||||||
|
|
||||||
exports.run = runMigrations;
|
exports.run = async ({ Backbone, database } = {}) => {
|
||||||
|
const { canRun } = await exports.getStatus({ database });
|
||||||
|
if (!canRun) {
|
||||||
|
throw new Error('Cannot run migrations on database without attachment data');
|
||||||
|
}
|
||||||
|
|
||||||
|
await runMigrations({ Backbone, database });
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.getStatus = async ({ database } = {}) => {
|
||||||
|
const connection = await db.open(database.id, database.version);
|
||||||
|
const isAttachmentMigrationComplete =
|
||||||
|
await settings.isAttachmentMigrationComplete(connection);
|
||||||
|
const hasMigrations = migrations.length > 0;
|
||||||
|
|
||||||
|
const canRun = isAttachmentMigrationComplete && hasMigrations;
|
||||||
|
return {
|
||||||
|
isAttachmentMigrationComplete,
|
||||||
|
hasMigrations,
|
||||||
|
canRun,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.getLatestVersion = () => {
|
||||||
|
const lastMigration = last(migrations);
|
||||||
|
if (!lastMigration) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastMigration.version;
|
||||||
|
};
|
||||||
|
|
|
@ -119,6 +119,8 @@
|
||||||
const upgradeMessageSchema = message =>
|
const upgradeMessageSchema = message =>
|
||||||
Message.upgradeSchema(message, upgradeSchemaContext);
|
Message.upgradeSchema(message, upgradeSchemaContext);
|
||||||
|
|
||||||
|
const { getPlaceholderMigrations } =
|
||||||
|
require('./js/modules/migrations/get_placeholder_migrations');
|
||||||
const { IdleDetector} = require('./js/modules/idle_detector');
|
const { IdleDetector} = require('./js/modules/idle_detector');
|
||||||
|
|
||||||
window.Signal = {};
|
window.Signal = {};
|
||||||
|
@ -128,13 +130,14 @@
|
||||||
window.Signal.Debug = require('./js/modules/debug');
|
window.Signal.Debug = require('./js/modules/debug');
|
||||||
window.Signal.Logs = require('./js/modules/logs');
|
window.Signal.Logs = require('./js/modules/logs');
|
||||||
window.Signal.Migrations = {};
|
window.Signal.Migrations = {};
|
||||||
window.Signal.Migrations.loadAttachmentData = Attachment.loadData(readAttachmentData);
|
|
||||||
window.Signal.Migrations.deleteAttachmentData = Attachment.deleteData(deleteAttachmentData);
|
window.Signal.Migrations.deleteAttachmentData = Attachment.deleteData(deleteAttachmentData);
|
||||||
window.Signal.Migrations.upgradeMessageSchema = upgradeMessageSchema;
|
window.Signal.Migrations.getPlaceholderMigrations =getPlaceholderMigrations;
|
||||||
|
window.Signal.Migrations.loadAttachmentData = Attachment.loadData(readAttachmentData);
|
||||||
window.Signal.Migrations.Migrations0DatabaseWithAttachmentData =
|
window.Signal.Migrations.Migrations0DatabaseWithAttachmentData =
|
||||||
require('./js/modules/migrations/migrations_0_database_with_attachment_data');
|
require('./js/modules/migrations/migrations_0_database_with_attachment_data');
|
||||||
window.Signal.Migrations.Migrations1DatabaseWithoutAttachmentData =
|
window.Signal.Migrations.Migrations1DatabaseWithoutAttachmentData =
|
||||||
require('./js/modules/migrations/migrations_1_database_without_attachment_data');
|
require('./js/modules/migrations/migrations_1_database_without_attachment_data');
|
||||||
|
window.Signal.Migrations.upgradeMessageSchema = upgradeMessageSchema;
|
||||||
window.Signal.OS = require('./js/modules/os');
|
window.Signal.OS = require('./js/modules/os');
|
||||||
window.Signal.Settings = require('./js/modules/settings');
|
window.Signal.Settings = require('./js/modules/settings');
|
||||||
window.Signal.Types = {};
|
window.Signal.Types = {};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue