commit a1c96f1db13e4a064d631c8e3f8d0bd53fc4f09c
parent b1b9dcf233df241985cd34904c68b36e6ae4a322
Author: Dan Stillman <dstillman@zotero.org>
Date: Wed, 20 Dec 2017 20:37:19 -0500
Fix deletion of tags across libraries
https://forums.zotero.org/discussion/comment/296384/#Comment_296384
Diffstat:
2 files changed, 38 insertions(+), 22 deletions(-)
diff --git a/chrome/content/zotero/xpcom/data/tags.js b/chrome/content/zotero/xpcom/data/tags.js
@@ -431,9 +431,11 @@ Zotero.Tags = new function() {
Zotero.DB.requireTransaction();
+ var sql;
+
// Use given tags, as long as they're orphaned
if (tagIDs) {
- let sql = "CREATE TEMPORARY TABLE tagDelete (tagID INT PRIMARY KEY)";
+ sql = "CREATE TEMPORARY TABLE tagDelete (tagID INT PRIMARY KEY)";
yield Zotero.DB.queryAsync(sql);
yield Zotero.Utilities.Internal.forEachChunkAsync(
tagIDs,
@@ -446,13 +448,17 @@ Zotero.Tags = new function() {
);
}
);
- sql = "SELECT tagID AS id, name FROM tagDelete JOIN tags USING (tagID) "
- + "WHERE tagID NOT IN (SELECT tagID FROM itemTags)";
+
+ // Skip tags that are still linked to items
+ sql = "DELETE FROM tagDelete WHERE tagID IN (SELECT tagID FROM itemTags)";
+ yield Zotero.DB.queryAsync(sql);
+
+ sql = "SELECT tagID AS id, name FROM tagDelete JOIN tags USING (tagID)";
var toDelete = yield Zotero.DB.queryAsync(sql);
}
// Look for orphaned tags
else {
- var sql = "CREATE TEMPORARY TABLE tagDelete AS "
+ sql = "CREATE TEMPORARY TABLE tagDelete AS "
+ "SELECT tagID FROM tags WHERE tagID NOT IN (SELECT tagID FROM itemTags)";
yield Zotero.DB.queryAsync(sql);
@@ -461,11 +467,10 @@ Zotero.Tags = new function() {
sql = "SELECT tagID AS id, name FROM tagDelete JOIN tags USING (tagID)";
var toDelete = yield Zotero.DB.queryAsync(sql);
-
- if (!toDelete.length) {
- sql = "DROP TABLE tagDelete";
- return Zotero.DB.queryAsync(sql);
- }
+ }
+
+ if (!toDelete.length) {
+ return Zotero.DB.queryAsync("DROP TABLE tagDelete");
}
var ids = [];
diff --git a/test/tests/tagsTest.js b/test/tests/tagsTest.js
@@ -39,35 +39,46 @@ describe("Zotero.Tags", function () {
});
describe("#removeFromLibrary()", function () {
- it("should remove tags in given library", function* () {
+ it("should remove tags in given library", async function () {
var libraryID = Zotero.Libraries.userLibraryID;
- var groupLibraryID = (yield getGroup()).libraryID;
+ var groupLibraryID = (await getGroup()).libraryID;
var tags = [];
var items = [];
- yield Zotero.DB.executeTransaction(function* () {
+ await Zotero.DB.executeTransaction(async function () {
for (let i = 0; i < 10; i++) {
let tagName = Zotero.Utilities.randomString();
tags.push(tagName);
- let item = createUnsavedDataObject('item');
- item.addTag(tagName);
- yield item.save();
+ let item = createUnsavedDataObject('item', { tags: [tagName] });
+ await item.save();
items.push(item);
}
});
- var groupTagName = Zotero.Utilities.randomString();
- var groupItem = createUnsavedDataObject('item', { libraryID: groupLibraryID });
- groupItem.addTag(groupTagName);
- yield groupItem.saveTx();
+ var groupTagName = tags[0];
+ var groupItem = await createDataObject(
+ 'item',
+ {
+ libraryID: groupLibraryID,
+ tags: [groupTagName]
+ }
+ );
var tagIDs = tags.map(tag => Zotero.Tags.getID(tag));
- yield Zotero.Tags.removeFromLibrary(libraryID, tagIDs);
+ await Zotero.Tags.removeFromLibrary(libraryID, tagIDs);
items.forEach(item => assert.lengthOf(item.getTags(), 0));
// Group item should still have the tag
- assert.lengthOf(groupItem.getTags(), 1);
- })
+ assert.sameDeepMembers(groupItem.getTags(), [{ tag: groupTagName }]);
+ assert.equal(
+ await Zotero.DB.valueQueryAsync(
+ "SELECT COUNT(*) FROM itemTags WHERE itemID=?",
+ groupItem.id
+ ),
+ 1
+ );
+ });
+
it("should reload tags of associated items", function* () {
var libraryID = Zotero.Libraries.userLibraryID;