DB isolation changes and item selection tweaks
- Add an 'exclusive' option to transactions that causes them to block other transactions and wait for other transactions to finish before starting, instead of nesting - Resolve Zotero.DB.waitForTransaction() promise before returning from executeTransaction() - A side effect of the above: wait for a newly created item to be selected in the middle pane and rendered in the right-hand pane before returning from executeTransaction() - Don't save items multiple times when adding/removing a non-final creator in the Info pane - Use a simpler, non-recursive method for focusing the next field in the Info pane; this prevents "too much recursion" errors if something causes the right-hand pane not to be rendered when expected
This commit is contained in:
parent
4a0018ec63
commit
bdd44e9a44
7 changed files with 182 additions and 146 deletions
|
@ -1,7 +1,15 @@
|
|||
describe("Zotero.DB", function() {
|
||||
var tmpTable = "tmpDBTest";
|
||||
|
||||
beforeEach(function* () {
|
||||
Zotero.DB.queryAsync("DROP TABLE IF EXISTS " + tmpTable);
|
||||
});
|
||||
after(function* () {
|
||||
Zotero.DB.queryAsync("DROP TABLE IF EXISTS " + tmpTable);
|
||||
});
|
||||
|
||||
describe("#executeTransaction()", function () {
|
||||
it("should nest concurrent transactions", Zotero.Promise.coroutine(function* () {
|
||||
var tmpTable = "tmpWaitForTransactions";
|
||||
yield Zotero.DB.queryAsync("CREATE TABLE " + tmpTable + " (foo INT)");
|
||||
|
||||
var resolve1, resolve2, reject1, reject2;
|
||||
|
@ -18,8 +26,7 @@ describe("Zotero.DB", function() {
|
|||
yield Zotero.Promise.delay(100);
|
||||
assert.equal(Zotero.DB._asyncTransactionNestingLevel, 0);
|
||||
yield Zotero.DB.queryAsync("INSERT INTO " + tmpTable + " VALUES (2)");
|
||||
// Make sure we're still in a transaction
|
||||
Zotero.DB.transactionDate;
|
||||
Zotero.DB.transactionDate; // Make sure we're still in a transaction
|
||||
})
|
||||
.then(resolve1)
|
||||
.catch(reject1);
|
||||
|
@ -27,8 +34,7 @@ describe("Zotero.DB", function() {
|
|||
Zotero.DB.executeTransaction(function* () {
|
||||
assert.equal(Zotero.DB._asyncTransactionNestingLevel, 1);
|
||||
yield Zotero.DB.queryAsync("INSERT INTO " + tmpTable + " VALUES (1)");
|
||||
// Make sure we're still in a transaction
|
||||
Zotero.DB.transactionDate;
|
||||
Zotero.DB.transactionDate; // Make sure we're still in a transaction
|
||||
})
|
||||
.then(resolve2)
|
||||
.catch(reject2);
|
||||
|
@ -36,8 +42,77 @@ describe("Zotero.DB", function() {
|
|||
yield Zotero.Promise.all([promise1, promise2]);
|
||||
}));
|
||||
|
||||
it("shouldn't nest transactions if an exclusive transaction is open", Zotero.Promise.coroutine(function* () {
|
||||
yield Zotero.DB.queryAsync("CREATE TABLE " + tmpTable + " (foo INT)");
|
||||
|
||||
var resolve1, resolve2, reject1, reject2;
|
||||
var promise1 = new Promise(function (resolve, reject) {
|
||||
resolve1 = resolve;
|
||||
reject1 = reject;
|
||||
});
|
||||
var promise2 = new Promise(function (resolve, reject) {
|
||||
resolve2 = resolve;
|
||||
reject2 = reject;
|
||||
});
|
||||
|
||||
Zotero.DB.executeTransaction(function* () {
|
||||
yield Zotero.Promise.delay(100);
|
||||
assert.equal(Zotero.DB._asyncTransactionNestingLevel, 0);
|
||||
yield Zotero.DB.queryAsync("INSERT INTO " + tmpTable + " VALUES (1)");
|
||||
Zotero.DB.transactionDate; // Make sure we're still in a transaction
|
||||
}, { exclusive: true })
|
||||
.then(resolve1)
|
||||
.catch(reject1);
|
||||
|
||||
Zotero.DB.executeTransaction(function* () {
|
||||
assert.equal(Zotero.DB._asyncTransactionNestingLevel, 0);
|
||||
var num = yield Zotero.DB.valueQueryAsync("SELECT COUNT(*) FROM " + tmpTable);
|
||||
assert.equal(num, 1);
|
||||
yield Zotero.DB.queryAsync("INSERT INTO " + tmpTable + " VALUES (2)");
|
||||
Zotero.DB.transactionDate; // Make sure we're still in a transaction
|
||||
})
|
||||
.then(resolve2)
|
||||
.catch(reject2);
|
||||
|
||||
yield Zotero.Promise.all([promise1, promise2]);
|
||||
}));
|
||||
|
||||
it("shouldn't nest an exclusive transaction if another transaction is open", Zotero.Promise.coroutine(function* () {
|
||||
yield Zotero.DB.queryAsync("CREATE TABLE " + tmpTable + " (foo INT)");
|
||||
|
||||
var resolve1, resolve2, reject1, reject2;
|
||||
var promise1 = new Promise(function (resolve, reject) {
|
||||
resolve1 = resolve;
|
||||
reject1 = reject;
|
||||
});
|
||||
var promise2 = new Promise(function (resolve, reject) {
|
||||
resolve2 = resolve;
|
||||
reject2 = reject;
|
||||
});
|
||||
|
||||
Zotero.DB.executeTransaction(function* () {
|
||||
yield Zotero.Promise.delay(100);
|
||||
assert.equal(Zotero.DB._asyncTransactionNestingLevel, 0);
|
||||
yield Zotero.DB.queryAsync("INSERT INTO " + tmpTable + " VALUES (1)");
|
||||
Zotero.DB.transactionDate; // Make sure we're still in a transaction
|
||||
})
|
||||
.then(resolve1)
|
||||
.catch(reject1);
|
||||
|
||||
Zotero.DB.executeTransaction(function* () {
|
||||
assert.equal(Zotero.DB._asyncTransactionNestingLevel, 0);
|
||||
var num = yield Zotero.DB.valueQueryAsync("SELECT COUNT(*) FROM " + tmpTable);
|
||||
assert.equal(num, 1);
|
||||
yield Zotero.DB.queryAsync("INSERT INTO " + tmpTable + " VALUES (2)");
|
||||
Zotero.DB.transactionDate; // Make sure we're still in a transaction
|
||||
}, { exclusive: true })
|
||||
.then(resolve2)
|
||||
.catch(reject2);
|
||||
|
||||
yield Zotero.Promise.all([promise1, promise2]);
|
||||
}));
|
||||
|
||||
it("should roll back on error", function* () {
|
||||
var tmpTable = "tmpRollbackOnError";
|
||||
yield Zotero.DB.queryAsync("CREATE TABLE " + tmpTable + " (foo INT)");
|
||||
yield Zotero.DB.queryAsync("INSERT INTO " + tmpTable + " VALUES (1)");
|
||||
try {
|
||||
|
@ -59,7 +134,6 @@ describe("Zotero.DB", function() {
|
|||
});
|
||||
|
||||
it("should run onRollback callbacks", function* () {
|
||||
var tmpTable = "tmpOnRollback";
|
||||
var callbackRan = false;
|
||||
yield Zotero.DB.queryAsync("CREATE TABLE " + tmpTable + " (foo INT)");
|
||||
try {
|
||||
|
@ -84,7 +158,6 @@ describe("Zotero.DB", function() {
|
|||
});
|
||||
|
||||
it("should run onRollback callbacks for nested transactions", function* () {
|
||||
var tmpTable = "tmpOnNestedRollback";
|
||||
var callback1Ran = false;
|
||||
var callback2Ran = false;
|
||||
yield Zotero.DB.queryAsync("CREATE TABLE " + tmpTable + " (foo INT)");
|
||||
|
@ -120,7 +193,6 @@ describe("Zotero.DB", function() {
|
|||
});
|
||||
|
||||
it("should not commit nested transactions", function* () {
|
||||
var tmpTable = "tmpNoCommitNested";
|
||||
yield Zotero.DB.queryAsync("CREATE TABLE " + tmpTable + " (foo INT)");
|
||||
try {
|
||||
yield Zotero.DB.executeTransaction(function* () {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue