Fix deletion of tags across libraries

https://forums.zotero.org/discussion/comment/296384/#Comment_296384
This commit is contained in:
Dan Stillman 2017-12-20 20:37:19 -05:00
parent b1b9dcf233
commit a1c96f1db1
2 changed files with 38 additions and 22 deletions

View File

@ -431,9 +431,11 @@ Zotero.Tags = new function() {
Zotero.DB.requireTransaction(); Zotero.DB.requireTransaction();
var sql;
// Use given tags, as long as they're orphaned // Use given tags, as long as they're orphaned
if (tagIDs) { 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.DB.queryAsync(sql);
yield Zotero.Utilities.Internal.forEachChunkAsync( yield Zotero.Utilities.Internal.forEachChunkAsync(
tagIDs, 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); var toDelete = yield Zotero.DB.queryAsync(sql);
} }
// Look for orphaned tags // Look for orphaned tags
else { 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)"; + "SELECT tagID FROM tags WHERE tagID NOT IN (SELECT tagID FROM itemTags)";
yield Zotero.DB.queryAsync(sql); 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)"; sql = "SELECT tagID AS id, name FROM tagDelete JOIN tags USING (tagID)";
var toDelete = yield Zotero.DB.queryAsync(sql); var toDelete = yield Zotero.DB.queryAsync(sql);
}
if (!toDelete.length) {
sql = "DROP TABLE tagDelete"; if (!toDelete.length) {
return Zotero.DB.queryAsync(sql); return Zotero.DB.queryAsync("DROP TABLE tagDelete");
}
} }
var ids = []; var ids = [];

View File

@ -39,35 +39,46 @@ describe("Zotero.Tags", function () {
}); });
describe("#removeFromLibrary()", 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 libraryID = Zotero.Libraries.userLibraryID;
var groupLibraryID = (yield getGroup()).libraryID; var groupLibraryID = (await getGroup()).libraryID;
var tags = []; var tags = [];
var items = []; var items = [];
yield Zotero.DB.executeTransaction(function* () { await Zotero.DB.executeTransaction(async function () {
for (let i = 0; i < 10; i++) { for (let i = 0; i < 10; i++) {
let tagName = Zotero.Utilities.randomString(); let tagName = Zotero.Utilities.randomString();
tags.push(tagName); tags.push(tagName);
let item = createUnsavedDataObject('item'); let item = createUnsavedDataObject('item', { tags: [tagName] });
item.addTag(tagName); await item.save();
yield item.save();
items.push(item); items.push(item);
} }
}); });
var groupTagName = Zotero.Utilities.randomString(); var groupTagName = tags[0];
var groupItem = createUnsavedDataObject('item', { libraryID: groupLibraryID }); var groupItem = await createDataObject(
groupItem.addTag(groupTagName); 'item',
yield groupItem.saveTx(); {
libraryID: groupLibraryID,
tags: [groupTagName]
}
);
var tagIDs = tags.map(tag => Zotero.Tags.getID(tag)); 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)); items.forEach(item => assert.lengthOf(item.getTags(), 0));
// Group item should still have the tag // 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* () { it("should reload tags of associated items", function* () {
var libraryID = Zotero.Libraries.userLibraryID; var libraryID = Zotero.Libraries.userLibraryID;