Fixes that should hopefully protect against database corruption

- When opening the DB, always tell other Zotero instances to close it,
  regardless of whether they are holding the lock.
- Don't let database re-open after it has been closed. This also fixes
  some issues with connector switching.
This commit is contained in:
Simon Kornblith 2013-12-13 17:19:56 -05:00
parent 207c34b1a4
commit d84bffb1c2
3 changed files with 21 additions and 6 deletions

View file

@ -791,12 +791,17 @@ Zotero.DBConnection.prototype.checkException = function (e) {
}
Zotero.DBConnection.prototype.closeDatabase = function () {
/**
* Close the database
* @param {Boolean} [permanent] If true, throw an error instead of
* allowing code to re-open the database again
*/
Zotero.DBConnection.prototype.closeDatabase = function (permanent) {
if(this._connection) {
this.stopDummyStatement();
var deferred = Q.defer();
this._connection.asyncClose(deferred.resolve);
this._connection = undefined;
this._connection = permanent ? false : null;
return deferred.promise;
} else {
return Q();
@ -1073,6 +1078,8 @@ Zotero.DBConnection.prototype.getSQLDataType = function(value) {
Zotero.DBConnection.prototype._getDBConnection = function () {
if (this._connection) {
return this._connection;
} else if (this._connection === false) {
throw new Error("Database permanently closed; not re-opening");
}
this._debug("Opening database '" + this._dbName + "'");

View file

@ -62,10 +62,13 @@ Zotero.IPC = new function() {
* has been received if it is already initialized, SA sends an initComplete message
* to Z4Fx.
*/
if(msg === "releaseLock" && !Zotero.isConnector) {
if(msg.substr(0, 11) === "releaseLock") {
// Standalone sends this to the Firefox extension to tell the Firefox extension to
// release its lock on the Zotero database
switchConnectorMode(true);
if(!Zotero.isConnector && (msg.length === 11 ||
msg.substr(12) === Zotero.getZoteroDirectory().persistentDescriptor)) {
switchConnectorMode(true);
}
} else if(msg === "lockReleased") {
// The Firefox extension sends this to Standalone to let Standalone know that it has
// released its lock

View file

@ -759,6 +759,11 @@ Components.utils.import("resource://gre/modules/Services.jsm");
Zotero.DB.test();
var dbfile = Zotero.getZoteroDatabase();
// Tell any other Zotero instances to release their lock,
// in case we lost the lock on the database (how?) and it's
// now open in two places at once
Zotero.IPC.broadcast("releaseLock "+dbfile.persistentDescriptor);
// Test write access on Zotero data directory
if (!dbfile.parent.isWritable()) {
@ -886,8 +891,8 @@ Components.utils.import("resource://gre/modules/Services.jsm");
// Zotero.DBConnection.getStatement() explicitly
Components.utils.forceGC();
// unlock DB
return Zotero.DB.closeDatabase().then(function() {
// close DB
return Zotero.DB.closeDatabase(true).then(function() {
// broadcast that DB lock has been released
Zotero.IPC.broadcast("lockReleased");
});