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();
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 = [];

View file

@ -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;