Fx60: Update DB query onRow() behavior

onRow() handlers now get passed a cancellation function as a second
argument
This commit is contained in:
Dan Stillman 2019-08-27 05:58:49 -04:00
parent 564e72196f
commit b08bd6849e
3 changed files with 12 additions and 18 deletions

View file

@ -586,22 +586,14 @@ Zotero.DBConnection.prototype.queryAsync = Zotero.Promise.coroutine(function* (s
} }
var failed = false; var failed = false;
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 the 'cancel' function is called
onRow = function (row) { onRow = function (row, cancel) {
try { try {
options.onRow(row); options.onRow(row, cancel);
} }
catch (e) { catch (e) {
// If the onRow throws a StopIteration, stop gracefully
if (e instanceof StopIteration) {
Zotero.debug("Query cancelled", 3);
}
// Otherwise, mark the promise as rejected, which Sqlite.jsm doesn't do
// on a StopIteration by default
else {
failed = e; failed = e;
} cancel();
throw StopIteration;
} }
} }
} }

View file

@ -214,10 +214,11 @@ ZoteroAutoComplete.prototype.startSearch = Zotero.Promise.coroutine(function* (s
var onRow = null; var onRow = null;
// If there's a result callback (e.g., for sorting), don't use a row handler // If there's a result callback (e.g., for sorting), don't use a row handler
if (!resultsCallback) { if (!resultsCallback) {
onRow = function (row) { onRow = function (row, cancel) {
if (this._cancelled) { if (this._cancelled) {
Zotero.debug("Cancelling query"); Zotero.debug("Cancelling query");
throw StopIteration; cancel();
return;
} }
var result = row.getResultByIndex(0); var result = row.getResultByIndex(0);
var comment = row.getResultByIndex(1); var comment = row.getResultByIndex(1);

View file

@ -151,16 +151,17 @@ describe("Zotero.DB", function() {
assert.equal(e.message, "Failed"); assert.equal(e.message, "Failed");
}); });
it("should stop gracefully if onRow throws a StopIteration", function* () { it("should stop gracefully if onRow calls cancel()", function* () {
var i = 0; var i = 0;
var rows = []; var rows = [];
yield Zotero.DB.queryAsync( yield Zotero.DB.queryAsync(
"SELECT * FROM " + tmpTable, "SELECT * FROM " + tmpTable,
false, false,
{ {
onRow: function (row) { onRow: function (row, cancel) {
if (i > 0) { if (i > 0) {
throw StopIteration; cancel();
return;
} }
rows.push(row.getResultByIndex(0)); rows.push(row.getResultByIndex(0));
i++; i++;