Addresses #445, Keep multiple backups
- Properly handle missing custom data directory on Windows - Disable unresponsive script indicator during schema update - Back up the database before userdata schema upgrades (and delete all but last pre-upgrade backup on successful upgrade) - Delete tmp file in backupDatabase if corrupt - Remove backup file test on startup -- seems to be working
This commit is contained in:
parent
4408a01944
commit
6a96516391
|
@ -581,7 +581,7 @@ Zotero.DBConnection.prototype.checkException = function (e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Zotero.DBConnection.prototype.backupDatabase = function () {
|
Zotero.DBConnection.prototype.backupDatabase = function (suffix) {
|
||||||
if (this.transactionInProgress()) {
|
if (this.transactionInProgress()) {
|
||||||
this._debug("Transaction in progress--skipping backup of DB '" + this._dbName + "'", 2);
|
this._debug("Transaction in progress--skipping backup of DB '" + this._dbName + "'", 2);
|
||||||
return false;
|
return false;
|
||||||
|
@ -597,7 +597,8 @@ Zotero.DBConnection.prototype.backupDatabase = function () {
|
||||||
this._debug("Backing up database '" + this._dbName + "'");
|
this._debug("Backing up database '" + this._dbName + "'");
|
||||||
|
|
||||||
var file = Zotero.getZoteroDatabase(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
|
// Copy via a temporary file so we don't run into disk space issues
|
||||||
// after deleting the old backup file
|
// after deleting the old backup file
|
||||||
|
@ -626,6 +627,9 @@ Zotero.DBConnection.prototype.backupDatabase = function () {
|
||||||
}
|
}
|
||||||
catch (e){
|
catch (e){
|
||||||
this._debug("Database file '" + tmpFile.leafName + "' is corrupt--skipping backup");
|
this._debug("Database file '" + tmpFile.leafName + "' is corrupt--skipping backup");
|
||||||
|
if (tmpFile.exists()) {
|
||||||
|
tmpFile.remove(null);
|
||||||
|
}
|
||||||
return false;
|
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 {
|
catchBlock: try {
|
||||||
var corruptMarker = Zotero.getZoteroDatabase(this._dbName, 'is.corrupt');
|
var corruptMarker = Zotero.getZoteroDatabase(this._dbName, 'is.corrupt');
|
||||||
if (corruptMarker.exists()) {
|
if (corruptMarker.exists()) {
|
||||||
|
|
|
@ -46,6 +46,13 @@ Zotero.Schema = new function(){
|
||||||
|
|
||||||
var schemaVersion = _getSchemaSQLVersion('userdata');
|
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();
|
Zotero.DB.beginTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -65,9 +72,9 @@ Zotero.Schema = new function(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_migrateUserDataSchema(dbVersion);
|
var up1 = _migrateUserDataSchema(dbVersion);
|
||||||
var up1 = _updateSchema('system');
|
var up2 = _updateSchema('system');
|
||||||
var up2 = _updateSchema('scrapers');
|
var up3 = _updateSchema('scrapers');
|
||||||
|
|
||||||
// Rebuild fulltext cache if necessary
|
// Rebuild fulltext cache if necessary
|
||||||
if (Zotero.Fulltext.cacheIsOutdated()){
|
if (Zotero.Fulltext.cacheIsOutdated()){
|
||||||
|
@ -78,16 +85,36 @@ Zotero.Schema = new function(){
|
||||||
catch(e){
|
catch(e){
|
||||||
Zotero.debug(e);
|
Zotero.debug(e);
|
||||||
Zotero.DB.rollbackTransaction();
|
Zotero.DB.rollbackTransaction();
|
||||||
|
Zotero.UnresponsiveScriptIndicator.enable();
|
||||||
throw(e);
|
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
|
// Run a manual scraper update if upgraded and pref set
|
||||||
if (Zotero.Prefs.get('automaticScraperUpdates')){
|
if (Zotero.Prefs.get('automaticScraperUpdates')){
|
||||||
this.updateScrapersRemote(2);
|
this.updateScrapersRemote(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Zotero.UnresponsiveScriptIndicator.enable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -914,6 +941,8 @@ Zotero.Schema = new function(){
|
||||||
alert('Error migrating Zotero database');
|
alert('Error migrating Zotero database');
|
||||||
throw(e);
|
throw(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -235,6 +235,10 @@ var Zotero = new function(){
|
||||||
var file = Components.classes["@mozilla.org/file/local;1"].
|
var file = Components.classes["@mozilla.org/file/local;1"].
|
||||||
createInstance(Components.interfaces.nsILocalFile);
|
createInstance(Components.interfaces.nsILocalFile);
|
||||||
file.persistentDescriptor = Zotero.Prefs.get('dataDir');
|
file.persistentDescriptor = Zotero.Prefs.get('dataDir');
|
||||||
|
if (!file.exists()) {
|
||||||
|
var e = { name: "NS_ERROR_FILE_NOT_FOUND" };
|
||||||
|
throw (e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var file = Zotero.getProfileDirectory();
|
var file = Zotero.getProfileDirectory();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user