Fix trash emptying, and do it in batches of 50

This commit is contained in:
Dan Stillman 2015-05-24 22:57:46 -04:00
parent 87fa51849f
commit 43762248a4
5 changed files with 71 additions and 36 deletions

View file

@ -102,9 +102,8 @@ Zotero.Items = function() {
/**
* Return items marked as deleted
*
* @param {Integer} libraryID
* @param {Boolean} asIDs Return itemIDs instead of
* Zotero.Item objects
* @param {Integer} libraryID - Library to search
* @param {Boolean} [asIDs] - Return itemIDs instead of Zotero.Item objects
* @return {Zotero.Item[]|Integer[]}
*/
this.getDeleted = Zotero.Promise.coroutine(function* (libraryID, asIDs, days) {
@ -113,7 +112,6 @@ Zotero.Items = function() {
if (days) {
sql += " AND dateDeleted<=DATE('NOW', '-" + parseInt(days) + " DAYS')";
}
var ids = yield Zotero.DB.columnQueryAsync(sql, [libraryID]);
if (!ids.length) {
return [];
@ -500,24 +498,27 @@ Zotero.Items = function() {
/**
* @param {Integer} days Only delete items deleted more than this many days ago
* @param {Integer} libraryID - Library to delete from
* @param {Integer} [days] - Only delete items deleted more than this many days ago
* @param {Integer} [limit]
*/
this.emptyTrash = Zotero.Promise.coroutine(function* (libraryID, days, limit) {
if (!libraryID) {
throw new Error("Library ID not provided");
}
var t = new Date();
var deletedIDs = [];
yield Zotero.DB.executeTransaction(function* () {
deletedIDs = yield this.getDeleted(libraryID, true, days);
if (deletedIDs.length) {
if (limit) {
deletedIDs = deletedIDs.slice(0, limit - 1)
}
yield this.erase(deletedIDs);
deletedIDs = yield this.getDeleted(libraryID, true, days);
if (deletedIDs.length) {
yield Zotero.Utilities.Internal.forEachChunkAsync(deletedIDs, 50, function* (chunk) {
yield this.erase(chunk);
Zotero.Notifier.trigger('refresh', 'trash', libraryID);
}
}.bind(this));
}.bind(this));
}
if (deletedIDs.length) {
Zotero.debug("Emptied " + deletedIDs.length + " item(s) from trash in " + (new Date() - t) + " ms");
}
@ -547,7 +548,7 @@ Zotero.Items = function() {
// TODO: increase number after dealing with slow
// tag.getLinkedItems() call during deletes
var num = 10;
this.emptyTrash(null, days, num)
this.emptyTrash(Zotero.Libraries.userLibraryID, days, num)
.then(deleted => {
if (!deleted) {
this._emptyTrashTimer = null;

View file

@ -603,15 +603,12 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
}
if (rows.length > 0) {
// Child items might have been added more than once
rows = Zotero.Utilities.arrayUnique(rows);
rows.sort(function(a,b) { return a-b });
for(var i=0, len=rows.length; i<len; i++)
{
var row = rows[i];
if(row != null)
{
this._removeRow(row-i);
}
for (let i = rows.length - 1; i >= 0; i--) {
this._removeRow(rows[i]);
}
madeChanges = true;

View file

@ -76,6 +76,11 @@ function waitForWindow(uri) {
return deferred.promise;
}
var selectLibrary = Zotero.Promise.coroutine(function* (win) {
yield win.ZoteroPane.collectionsView.selectLibrary(Zotero.Libraries.userLibraryID);
yield waitForItemsLoad(win);
});
var waitForItemsLoad = function (win, collectionRowToSelect) {
var resolve;
var promise = new Zotero.Promise(() => resolve = arguments[0]);
@ -151,7 +156,7 @@ function waitForCallback(cb, interval, timeout) {
function createUnsavedDataObject(objectType, params) {
params = params || {};
if (objectType == 'item') {
var param = 'book';
var param = params.itemType || 'book';
}
var obj = new Zotero[Zotero.Utilities.capitalize(objectType)](param);
switch (objectType) {

View file

@ -3,21 +3,14 @@
describe("Zotero.CollectionTreeView", function() {
var win, collectionsView;
// Select library
// TODO: Add a selectCollection() function and select a collection instead
var resetSelection = Zotero.Promise.coroutine(function* () {
yield collectionsView.selectLibrary(Zotero.Libraries.userLibraryID);
yield waitForItemsLoad(win);
assert.equal(collectionsView.getSelectedLibraryID(), Zotero.Libraries.userLibraryID);
});
// Load Zotero pane and select library
before(function* () {
win = yield loadZoteroPane();
collectionsView = win.ZoteroPane.collectionsView;
});
beforeEach(function () {
return resetSelection();
// TODO: Add a selectCollection() function and select a collection instead?
return selectLibrary(win);
})
after(function () {
win.close();
@ -108,7 +101,7 @@ describe("Zotero.CollectionTreeView", function() {
collection.name = "No select on modify";
var id = yield collection.saveTx();
yield resetSelection();
yield selectLibrary(win);
collection.name = "No select on modify 2";
yield collection.saveTx();

View file

@ -1,3 +1,42 @@
describe("Zotero.Items", function() {
describe("Zotero.Items", function () {
var win, collectionsView;
before(function* () {
win = yield loadZoteroPane();
collectionsView = win.ZoteroPane.collectionsView;
})
beforeEach(function () {
return selectLibrary(win);
})
after(function () {
win.close();
})
describe("#emptyTrash()", function () {
it("should delete items in the trash", function* () {
var item1 = createUnsavedDataObject('item');
item1.setField('title', 'a');
item1.deleted = true;
var id1 = yield item1.saveTx();
var item2 = createUnsavedDataObject('item');
item2.setField('title', 'b');
item2.deleted = true;
var id2 = yield item2.saveTx();
var item3 = createUnsavedDataObject('item', { itemType: 'attachment', parentID: id2 });
item3.attachmentLinkMode = Zotero.Attachments.LINK_MODE_IMPORTED_URL;
item3.deleted = true;
var id3 = yield item3.saveTx();
yield collectionsView.selectTrash(Zotero.Libraries.userLibraryID);
yield Zotero.Items.emptyTrash(Zotero.Libraries.userLibraryID);
assert.isFalse(yield Zotero.Items.getAsync(id1));
assert.isFalse(yield Zotero.Items.getAsync(id2));
assert.isFalse(yield Zotero.Items.getAsync(id3));
assert.equal(win.ZoteroPane.itemsView.rowCount, 0);
})
})
});