Add Sync.Storage.Local.updateSyncStates()

This speeds up updating of sync states, particularly after resetting
file sync history.
This commit is contained in:
Dan Stillman 2017-07-01 06:26:22 -04:00
parent b72f1c2a08
commit 88088c68db
2 changed files with 65 additions and 4 deletions

View file

@ -258,16 +258,26 @@ Zotero.Sync.Storage.Local = {
//Zotero.debug("Memory usage: " + memmgr.resident);
var changed = false;
for (let i = 0; i < items.length; i++) {
let item = items[i];
var statesToSet = {};
for (let item of items) {
// TODO: Catch error?
let state = yield this._checkForUpdatedFile(item, attachmentData[item.id]);
if (state !== false) {
item.attachmentSyncState = state;
yield item.saveTx({ skipAll: true });
if (!statesToSet[state]) {
statesToSet[state] = [];
}
statesToSet[state].push(item);
changed = true;
}
}
// Update sync states in bulk
if (changed) {
yield Zotero.DB.executeTransaction(function* () {
for (let state in statesToSet) {
yield this.updateSyncStates(statesToSet[state], parseInt(state));
}
}.bind(this));
}
if (!items.length) {
Zotero.debug("No synced files have changed locally");
@ -499,6 +509,35 @@ Zotero.Sync.Storage.Local = {
},
/**
* @param {Zotero.Item[]} items
* @param {String|Integer} syncState
* @return {Promise}
*/
updateSyncStates: function (items, syncState) {
if (syncState === undefined) {
throw new Error("Sync state not specified");
}
if (typeof syncState == 'string') {
syncState = this["SYNC_STATE_" + syncState.toUpperCase()];
}
return Zotero.Utilities.Internal.forEachChunkAsync(
items,
1000,
async function (chunk) {
chunk.forEach((item) => {
item._attachmentSyncState = syncState;
});
return Zotero.DB.queryAsync(
"UPDATE itemAttachments SET syncState=? WHERE itemID IN "
+ "(" + chunk.map(item => item.id).join(', ') + ")",
syncState
);
}
);
},
/**
* Mark all stored files for upload checking
*

View file

@ -93,6 +93,28 @@ describe("Zotero.Sync.Storage.Local", function () {
})
})
describe("#updateSyncStates()", function () {
it("should update attachment sync states to 'to_upload'", function* () {
var attachment1 = yield importFileAttachment('test.png');
attachment1.attachmentSyncState = 'in_sync';
yield attachment1.saveTx();
var attachment2 = yield importFileAttachment('test.png');
attachment2.attachmentSyncState = 'in_sync';
yield attachment2.saveTx();
var local = Zotero.Sync.Storage.Local;
yield local.updateSyncStates([attachment1, attachment2], 'to_upload');
for (let attachment of [attachment1, attachment2]) {
assert.strictEqual(attachment.attachmentSyncState, local.SYNC_STATE_TO_UPLOAD);
let state = yield Zotero.DB.valueQueryAsync(
"SELECT syncState FROM itemAttachments WHERE itemID=?", attachment.id
);
assert.strictEqual(state, local.SYNC_STATE_TO_UPLOAD);
}
});
});
describe("#resetAllSyncStates()", function () {
it("should reset attachment sync states to 'to_upload'", function* () {
var attachment = yield importFileAttachment('test.png');