Speed up DB methods slightly by avoiding unnecessary yields

And tidy some things up
This commit is contained in:
Dan Stillman 2016-01-17 00:49:26 -05:00
parent c4d67c5b5e
commit 5ef89b1d0f
2 changed files with 59 additions and 76 deletions

View File

@ -72,13 +72,12 @@ Zotero.DBConnection = function(dbName) {
// Private members // Private members
this._dbName = dbName; this._dbName = dbName;
this._shutdown = false; this._shutdown = false;
this._connectionAsync = null; this._connection = null;
this._transactionID = null; this._transactionID = null;
this._transactionDate = null; this._transactionDate = null;
this._lastTransactionDate = null; this._lastTransactionDate = null;
this._transactionRollback = false; this._transactionRollback = false;
this._transactionNestingLevel = 0; this._transactionNestingLevel = 0;
this._asyncTransactionNestingLevel = 0;
this._callbacks = { this._callbacks = {
begin: [], begin: [],
commit: [], commit: [],
@ -89,7 +88,6 @@ Zotero.DBConnection = function(dbName) {
} }
}; };
this._dbIsCorrupt = null this._dbIsCorrupt = null
this._self = this;
this._transactionPromise = null; this._transactionPromise = null;
} }
@ -610,16 +608,13 @@ Zotero.DBConnection.prototype.requireTransaction = function () {
* rows are Proxy objects that return values from the * rows are Proxy objects that return values from the
* underlying mozIStorageRows based on column names. * underlying mozIStorageRows based on column names.
*/ */
Zotero.DBConnection.prototype.queryAsync = function (sql, params, options) { Zotero.DBConnection.prototype.queryAsync = Zotero.Promise.coroutine(function* (sql, params, options) {
let conn; try {
let self = this; let onRow = null;
let onRow = null; let conn = this._getConnection(options) || (yield this._getConnectionAsync(options));
return this._getConnectionAsync(options) [sql, params] = this.parseQueryAndParams(sql, params);
.then(function (c) {
conn = c;
[sql, params] = self.parseQueryAndParams(sql, params);
if (Zotero.Debug.enabled) { if (Zotero.Debug.enabled) {
self.logQuery(sql, params, options); this.logQuery(sql, params, options);
} }
if (options && options.onRow) { if (options && options.onRow) {
// Errors in onRow don't stop the query unless StopIteration is thrown // Errors in onRow don't stop the query unless StopIteration is thrown
@ -638,11 +633,9 @@ Zotero.DBConnection.prototype.queryAsync = function (sql, params, options) {
} }
} }
} }
return conn.executeCached(sql, params, onRow); let rows = yield conn.executeCached(sql, params, onRow);
})
.then(function (rows) {
// Parse out the SQL command being used // Parse out the SQL command being used
var op = sql.match(/^[^a-z]*[^ ]+/i); let op = sql.match(/^[^a-z]*[^ ]+/i);
if (op) { if (op) {
op = op.toString().toLowerCase(); op = op.toString().toLowerCase();
} }
@ -681,8 +674,8 @@ Zotero.DBConnection.prototype.queryAsync = function (sql, params, options) {
// returning it for SELECT and REPLACE queries // returning it for SELECT and REPLACE queries
return; return;
} }
}) }
.catch(function (e) { catch (e) {
if (e.errors && e.errors[0]) { if (e.errors && e.errors[0]) {
var eStr = e + ""; var eStr = e + "";
eStr = eStr.indexOf("Error: ") == 0 ? eStr.substr(7): e; eStr = eStr.indexOf("Error: ") == 0 ? eStr.substr(7): e;
@ -693,8 +686,8 @@ Zotero.DBConnection.prototype.queryAsync = function (sql, params, options) {
else { else {
throw e; throw e;
} }
}); }
}; });
Zotero.DBConnection.prototype.queryTx = function (sql, params, options) { Zotero.DBConnection.prototype.queryTx = function (sql, params, options) {
@ -711,20 +704,17 @@ Zotero.DBConnection.prototype.queryTx = function (sql, params, options) {
* @param {Array|String|Integer} [params] SQL parameters to bind * @param {Array|String|Integer} [params] SQL parameters to bind
* @return {Promise<Array|Boolean>} A promise for either the value or FALSE if no result * @return {Promise<Array|Boolean>} A promise for either the value or FALSE if no result
*/ */
Zotero.DBConnection.prototype.valueQueryAsync = function (sql, params) { Zotero.DBConnection.prototype.valueQueryAsync = Zotero.Promise.coroutine(function* (sql, params, options = {}) {
let self = this; try {
return this._getConnectionAsync() let conn = this._getConnection(options) || (yield this._getConnectionAsync(options));
.then(function (conn) { [sql, params] = this.parseQueryAndParams(sql, params);
[sql, params] = self.parseQueryAndParams(sql, params);
if (Zotero.Debug.enabled) { if (Zotero.Debug.enabled) {
self.logQuery(sql, params); this.logQuery(sql, params);
} }
return conn.executeCached(sql, params); let rows = yield conn.executeCached(sql, params);
})
.then(function (rows) {
return rows.length ? rows[0].getResultByIndex(0) : false; return rows.length ? rows[0].getResultByIndex(0) : false;
}) }
.catch(function (e) { catch (e) {
if (e.errors && e.errors[0]) { if (e.errors && e.errors[0]) {
var eStr = e + ""; var eStr = e + "";
eStr = eStr.indexOf("Error: ") == 0 ? eStr.substr(7): e; eStr = eStr.indexOf("Error: ") == 0 ? eStr.substr(7): e;
@ -735,8 +725,8 @@ Zotero.DBConnection.prototype.valueQueryAsync = function (sql, params) {
else { else {
throw e; throw e;
} }
}); }
}; });
/** /**
@ -757,26 +747,21 @@ Zotero.DBConnection.prototype.rowQueryAsync = function (sql, params) {
* @param {Array|String|Integer} [params] SQL parameters to bind * @param {Array|String|Integer} [params] SQL parameters to bind
* @return {Promise<Array>} A promise for an array of values in the column * @return {Promise<Array>} A promise for an array of values in the column
*/ */
Zotero.DBConnection.prototype.columnQueryAsync = function (sql, params) { Zotero.DBConnection.prototype.columnQueryAsync = Zotero.Promise.coroutine(function* (sql, params, options = {}) {
let conn; try {
let self = this; let conn = this._getConnection(options) || (yield this._getConnectionAsync(options));
return this._getConnectionAsync(). [sql, params] = this.parseQueryAndParams(sql, params);
then(function (c) {
conn = c;
[sql, params] = self.parseQueryAndParams(sql, params);
if (Zotero.Debug.enabled) { if (Zotero.Debug.enabled) {
self.logQuery(sql, params); this.logQuery(sql, params);
} }
return conn.executeCached(sql, params); let rows = yield conn.executeCached(sql, params);
})
.then(function (rows) {
var column = []; var column = [];
for (let i=0, len=rows.length; i<len; i++) { for (let i=0, len=rows.length; i<len; i++) {
column.push(rows[i].getResultByIndex(0)); column.push(rows[i].getResultByIndex(0));
} }
return column; return column;
}) }
.catch(function (e) { catch (e) {
if (e.errors && e.errors[0]) { if (e.errors && e.errors[0]) {
var eStr = e + ""; var eStr = e + "";
eStr = eStr.indexOf("Error: ") == 0 ? eStr.substr(7): e; eStr = eStr.indexOf("Error: ") == 0 ? eStr.substr(7): e;
@ -787,8 +772,8 @@ Zotero.DBConnection.prototype.columnQueryAsync = function (sql, params) {
else { else {
throw e; throw e;
} }
}); }
}; });
Zotero.DBConnection.prototype.logQuery = function (sql, params, options) { Zotero.DBConnection.prototype.logQuery = function (sql, params, options) {
@ -916,11 +901,11 @@ Zotero.DBConnection.prototype.checkException = function (e) {
* allowing code to re-open the database again * allowing code to re-open the database again
*/ */
Zotero.DBConnection.prototype.closeDatabase = Zotero.Promise.coroutine(function* (permanent) { Zotero.DBConnection.prototype.closeDatabase = Zotero.Promise.coroutine(function* (permanent) {
if (this._connectionAsync) { if (this._connection) {
Zotero.debug("Closing database"); Zotero.debug("Closing database");
yield this._connectionAsync.close(); yield this._connection.close();
this._connectionAsync = undefined; this._connection = undefined;
this._connectionAsync = permanent ? false : null; this._connection = permanent ? false : null;
Zotero.debug("Database closed"); Zotero.debug("Database closed");
} }
}); });
@ -1135,10 +1120,10 @@ Zotero.DBConnection.prototype._getConnection = function (options) {
if (this._backupPromise && this._backupPromise.isPending() && (!options || !options.inBackup)) { if (this._backupPromise && this._backupPromise.isPending() && (!options || !options.inBackup)) {
return false; return false;
} }
if (this._connectionAsync === false) { if (this._connection === false) {
throw new Error("Database permanently closed; not re-opening"); throw new Error("Database permanently closed; not re-opening");
} }
return this._connectionAsync || false; return this._connection || false;
} }
/* /*
@ -1151,10 +1136,10 @@ Zotero.DBConnection.prototype._getConnectionAsync = Zotero.Promise.coroutine(fun
yield this._backupPromise; yield this._backupPromise;
} }
if (this._connectionAsync) { if (this._connection) {
return this._connectionAsync; return this._connection;
} }
else if (this._connectionAsync === false) { else if (this._connection === false) {
throw new Error("Database permanently closed; not re-opening"); throw new Error("Database permanently closed; not re-opening");
} }
@ -1176,7 +1161,7 @@ Zotero.DBConnection.prototype._getConnectionAsync = Zotero.Promise.coroutine(fun
name: 'NS_ERROR_FILE_CORRUPTED' name: 'NS_ERROR_FILE_CORRUPTED'
}; };
} }
this._connectionAsync = yield Zotero.Promise.resolve(this.Sqlite.openConnection({ this._connection = yield Zotero.Promise.resolve(this.Sqlite.openConnection({
path: file.path path: file.path
})); }));
} }
@ -1195,7 +1180,7 @@ Zotero.DBConnection.prototype._getConnectionAsync = Zotero.Promise.coroutine(fun
// Create new main database // Create new main database
var file = Zotero.getZoteroDatabase(this._dbName); var file = Zotero.getZoteroDatabase(this._dbName);
this._connectionAsync = store.openDatabase(file); this._connection = store.openDatabase(file);
if (corruptMarker.exists()) { if (corruptMarker.exists()) {
corruptMarker.remove(null); corruptMarker.remove(null);
@ -1213,7 +1198,7 @@ Zotero.DBConnection.prototype._getConnectionAsync = Zotero.Promise.coroutine(fun
// Test the backup file // Test the backup file
try { try {
Zotero.debug("Asynchronously opening DB connection"); Zotero.debug("Asynchronously opening DB connection");
this._connectionAsync = yield Zotero.Promise.resolve(this.Sqlite.openConnection({ this._connection = yield Zotero.Promise.resolve(this.Sqlite.openConnection({
path: backupFile.path path: backupFile.path
})); }));
} }
@ -1221,7 +1206,7 @@ Zotero.DBConnection.prototype._getConnectionAsync = Zotero.Promise.coroutine(fun
catch (e) { catch (e) {
// Create new main database // Create new main database
var file = Zotero.getZoteroDatabase(this._dbName); var file = Zotero.getZoteroDatabase(this._dbName);
this._connectionAsync = yield Zotero.Promise.resolve(this.Sqlite.openConnection({ this._connection = yield Zotero.Promise.resolve(this.Sqlite.openConnection({
path: file.path path: file.path
})); }));
@ -1234,7 +1219,7 @@ Zotero.DBConnection.prototype._getConnectionAsync = Zotero.Promise.coroutine(fun
break catchBlock; break catchBlock;
} }
this._connectionAsync = undefined; this._connection = undefined;
// Copy backup file to main DB file // Copy backup file to main DB file
this._debug("Restoring database '" + this._dbName + "' from backup file", 1); this._debug("Restoring database '" + this._dbName + "' from backup file", 1);
@ -1249,7 +1234,7 @@ Zotero.DBConnection.prototype._getConnectionAsync = Zotero.Promise.coroutine(fun
// Open restored database // Open restored database
var file = Zotero.getZoteroDirectory(); var file = Zotero.getZoteroDirectory();
file.append(fileName); file.append(fileName);
this._connectionAsync = yield Zotero.Promise.resolve(this.Sqlite.openConnection({ this._connection = yield Zotero.Promise.resolve(this.Sqlite.openConnection({
path: file.path path: file.path
})); }));
this._debug('Database restored', 1); this._debug('Database restored', 1);
@ -1292,7 +1277,7 @@ Zotero.DBConnection.prototype._getConnectionAsync = Zotero.Promise.coroutine(fun
idleService.addIdleObserver(this, 60); idleService.addIdleObserver(this, 60);
idleService = null; idleService = null;
return this._connectionAsync; return this._connection;
}); });

View File

@ -833,7 +833,7 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
} }
} }
this.shutdown = function() { this.shutdown = Zotero.Promise.coroutine(function* () {
Zotero.debug("Shutting down Zotero"); Zotero.debug("Shutting down Zotero");
try { try {
@ -841,7 +841,7 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
Zotero.closing = true; Zotero.closing = true;
// run shutdown listener // run shutdown listener
for each(var listener in _shutdownListeners) { for (let listener of _shutdownListeners) {
try { try {
listener(); listener();
} catch(e) { } catch(e) {
@ -852,20 +852,18 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
// remove temp directory // remove temp directory
Zotero.removeTempDirectory(); Zotero.removeTempDirectory();
if (Zotero.DB && Zotero.DB._connectionAsync) { if (Zotero.DB) {
// close DB // close DB
return Zotero.DB.closeDatabase(true).then(function() { yield Zotero.DB.closeDatabase(true)
// broadcast that DB lock has been released
Zotero.IPC.broadcast("lockReleased"); // broadcast that DB lock has been released
}); Zotero.IPC.broadcast("lockReleased");
} }
return Zotero.Promise.resolve();
} catch(e) { } catch(e) {
Zotero.debug(e); Zotero.logError(e);
return Zotero.Promise.reject(e); throw e;
} }
} });
function getProfileDirectory(){ function getProfileDirectory(){