diff --git a/chrome/content/zotero/xpcom/schema.js b/chrome/content/zotero/xpcom/schema.js index 10bd4913ce..82f8aba5b3 100644 --- a/chrome/content/zotero/xpcom/schema.js +++ b/chrome/content/zotero/xpcom/schema.js @@ -39,8 +39,8 @@ Zotero.Schema = new function () { const REPOSITORY_CHECK_INTERVAL = 86400; const REPOSITORY_RETRY_INTERVAL = 3600; - // If updating from this userdata version or later, don't show "Upgrading database…" and don't make - // DB backup first. This should be set to false when breaking compatibility or making major changes. + // If updating from this userdata version or later, don't show "Upgrading database…". This + // should be set to false when adding a slow or otherwise major upgrade step. const minorUpdateFrom = 112; var _dbVersions = []; @@ -155,12 +155,10 @@ Zotero.Schema = new function () { var userdataVersion = await _getSchemaSQLVersion('userdata'); options.minor = minorUpdateFrom && userdata >= minorUpdateFrom; - // If non-minor userdata upgrade, make backup of database first - if (userdata < userdataVersion && !options.minor) { - await Zotero.DB.backUpDatabase({ force: true, suffix: userdata }); - } - // Automatic backup - else if (integrityCheckRequired || bundledGlobalSchemaVersionCompare === 1) { + // Force a backup before a userdata upgrade, an integrity check, or a global schema update + if (userdata < userdataVersion + || integrityCheckRequired + || bundledGlobalSchemaVersionCompare === 1) { await Zotero.DB.backUpDatabase({ force: true }); } @@ -264,8 +262,8 @@ Zotero.Schema = new function () { } if (updated) { - // Upgrade seems to have been a success -- delete any previous backups - var maxPrevious = userdata - 1; + // Upgrade seems to have been a success -- delete any versioned backups + // (zotero.sqlite..bak) from upgrades in previous versions var file = Zotero.File.pathToFile(Zotero.DataDirectory.dir); var toDelete = []; try { @@ -276,11 +274,12 @@ Zotero.Schema = new function () { if (file.isDirectory()) { continue; } - var matches = file.leafName.match(/zotero\.sqlite\.([0-9]{2,})\.bak/); + var matches = file.leafName.match(/^zotero\.sqlite\.([0-9]{2,})\.bak$/); if (!matches) { continue; } - if (matches[1]>=28 && matches[1]<=maxPrevious) { + // Rotation backups (zotero.sqlite..bak) only go up to 24 + if (matches[1] >= 28) { toDelete.push(file); } } @@ -3679,7 +3678,8 @@ Zotero.Schema = new function () { await Zotero.DB.queryAsync("DROP TABLE savedSearchConditionsOld"); } - // If breaking compatibility or doing anything dangerous, clear minorUpdateFrom + // If adding a slow or otherwise major upgrade step, clear minorUpdateFrom so that + // "Upgrading database…" is shown } await _updateDBVersion('userdata', toVersion); diff --git a/test/content/support.js b/test/content/support.js index 043dd6cf9f..547d803dd4 100644 --- a/test/content/support.js +++ b/test/content/support.js @@ -721,10 +721,18 @@ var removeDir = async function (dir) { * * @param {Object} [options] - Initialization options, as passed to Zotero.init(), overriding * any that were set at startup + * @param {Object} [options.prefs] - Prefs to set for the reinitialization, overriding the + * test-runner defaults. Cleared by the global afterEach(). */ async function resetDB(options = {}) { resetPrefs(); + if (options.prefs) { + for (let key in options.prefs) { + Zotero.Prefs.set(key, options.prefs[key]); + } + } + if (options.thisArg) { options.thisArg.timeout(60000); } diff --git a/test/tests/schemaTest.js b/test/tests/schemaTest.js index 7d7a146df0..bf2fd41abb 100644 --- a/test/tests/schemaTest.js +++ b/test/tests/schemaTest.js @@ -488,11 +488,18 @@ describe("Zotero.Schema", function () { await resetDB({ thisArg: this, skipBundledFiles: true, - dbFile: OS.Path.join(getTestDataDirectory().path, 'zotero-4.0.sqlite.zip') + dbFile: OS.Path.join(getTestDataDirectory().path, 'zotero-4.0.sqlite.zip'), + // Backups are disabled in the test profile + prefs: { 'backup.numBackups': 2 } }); // Make sure we can open the Zotero pane without errors win = await loadZoteroPane(); win.close(); + + // A backup should have been made before the upgrade + assert.isTrue( + await IOUtils.exists(PathUtils.join(Zotero.DataDirectory.dir, 'zotero.sqlite.bak')) + ); }); }); })