Fix trash emptying, and do it in batches of 50
This commit is contained in:
parent
87fa51849f
commit
43762248a4
5 changed files with 71 additions and 36 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
})
|
||||
})
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue