diff --git a/chrome/content/zotero/xpcom/db.js b/chrome/content/zotero/xpcom/db.js index a37ee98a1..4b85fc2ae 100644 --- a/chrome/content/zotero/xpcom/db.js +++ b/chrome/content/zotero/xpcom/db.js @@ -581,7 +581,7 @@ Zotero.DBConnection.prototype.checkException = function (e) { } -Zotero.DBConnection.prototype.backupDatabase = function () { +Zotero.DBConnection.prototype.backupDatabase = function (suffix) { if (this.transactionInProgress()) { this._debug("Transaction in progress--skipping backup of DB '" + this._dbName + "'", 2); return false; @@ -597,7 +597,8 @@ Zotero.DBConnection.prototype.backupDatabase = function () { this._debug("Backing up database '" + this._dbName + "'"); var file = Zotero.getZoteroDatabase(this._dbName); - var backupFile = Zotero.getZoteroDatabase(this._dbName, 'bak'); + var backupFile = Zotero.getZoteroDatabase(this._dbName, + (suffix ? suffix + '.' : '') + 'bak'); // Copy via a temporary file so we don't run into disk space issues // after deleting the old backup file @@ -626,6 +627,9 @@ Zotero.DBConnection.prototype.backupDatabase = function () { } catch (e){ this._debug("Database file '" + tmpFile.leafName + "' is corrupt--skipping backup"); + if (tmpFile.exists()) { + tmpFile.remove(null); + } return false; } } @@ -681,18 +685,6 @@ Zotero.DBConnection.prototype._getDBConnection = function () { } } - // DEBUG: Temporary check - // Test the backup file (to make sure the backup mechanism is working) - if (backupFile.exists()) { - try { - this._connection = store.openDatabase(backupFile); - } - catch (e) { - this._debug("Backup file '" + backupFile.leafName + "' was corrupt!", 1); - } - this._connection = undefined; - } - catchBlock: try { var corruptMarker = Zotero.getZoteroDatabase(this._dbName, 'is.corrupt'); if (corruptMarker.exists()) { diff --git a/chrome/content/zotero/xpcom/schema.js b/chrome/content/zotero/xpcom/schema.js index 611c6a34c..a2833e666 100644 --- a/chrome/content/zotero/xpcom/schema.js +++ b/chrome/content/zotero/xpcom/schema.js @@ -46,6 +46,13 @@ Zotero.Schema = new function(){ var schemaVersion = _getSchemaSQLVersion('userdata'); + Zotero.UnresponsiveScriptIndicator.disable(); + + // If upgrading userdata, make backup of database first + if (dbVersion < schemaVersion){ + Zotero.DB.backupDatabase(dbVersion); + } + Zotero.DB.beginTransaction(); try { @@ -65,9 +72,9 @@ Zotero.Schema = new function(){ } } - _migrateUserDataSchema(dbVersion); - var up1 = _updateSchema('system'); - var up2 = _updateSchema('scrapers'); + var up1 = _migrateUserDataSchema(dbVersion); + var up2 = _updateSchema('system'); + var up3 = _updateSchema('scrapers'); // Rebuild fulltext cache if necessary if (Zotero.Fulltext.cacheIsOutdated()){ @@ -78,16 +85,36 @@ Zotero.Schema = new function(){ catch(e){ Zotero.debug(e); Zotero.DB.rollbackTransaction(); + Zotero.UnresponsiveScriptIndicator.enable(); throw(e); } - if (up1 || up2) { + if (up1) { + // Upgrade seems to have been a success -- delete any previous backups + var maxPrevious = dbVersion - 1; + var file = Zotero.getZoteroDirectory(); + // directoryEntries.hasMoreElements() throws an error (possibly + // because of the temporary SQLite journal file?), so we just look + // for all versions + for (var i=maxPrevious; i>=29; i--) { + var fileName = 'zotero.sqlite.' + i + '.bak'; + file.append(fileName); + if (file.exists()) { + Zotero.debug('Removing previous backup file ' + fileName); + file.remove(null); + } + file = file.parent; + } + } + + if (up2 || up3) { // Run a manual scraper update if upgraded and pref set if (Zotero.Prefs.get('automaticScraperUpdates')){ this.updateScrapersRemote(2); } } + Zotero.UnresponsiveScriptIndicator.enable(); return; } @@ -914,6 +941,8 @@ Zotero.Schema = new function(){ alert('Error migrating Zotero database'); throw(e); } + + return true; } diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index 4575db66e..efd434950 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -235,6 +235,10 @@ var Zotero = new function(){ var file = Components.classes["@mozilla.org/file/local;1"]. createInstance(Components.interfaces.nsILocalFile); file.persistentDescriptor = Zotero.Prefs.get('dataDir'); + if (!file.exists()) { + var e = { name: "NS_ERROR_FILE_NOT_FOUND" }; + throw (e); + } } else { var file = Zotero.getProfileDirectory();