Restore tag rename and delete

Tag comparisons are now case-insensitive, and old tags with case differences are migrated to the most-used tag or the tag linked to the oldest item
This commit is contained in:
Dan Stillman 2008-06-16 20:07:17 +00:00
parent 8214d7ac60
commit 413670b09d
3 changed files with 80 additions and 12 deletions

View File

@ -555,9 +555,7 @@
}
}
for each(var tagID in tagIDs) {
Zotero.Tags.remove(tagID);
}
Zotero.Tags.erase(tagIDs);
Zotero.DB.commitTransaction()
}

View File

@ -75,6 +75,7 @@ Zotero.Tags = new function() {
return _tagsByID[tagID].name;
}
// Populate cache
var tag = this.get(tagID);
return _tagsByID[tagID] ? _tagsByID[tagID].name : false;
@ -85,6 +86,8 @@ Zotero.Tags = new function() {
* Returns the tagID matching given tag and type
*/
function getID(name, type) {
name = name.toLowerCase();
if (_tags[type] && _tags[type]['_' + name]) {
return _tags[type]['_' + name];
}
@ -252,17 +255,26 @@ Zotero.Tags = new function() {
var oldName = tagObj.name;
var oldType = tagObj.type;
var notifierData = {};
notifierData[tagID] = { old: tag.serialize() };
notifierData[tagID] = { old: tagObj.serialize() };
if (oldName == name) {
Zotero.DB.commitTransaction();
return;
}
// Check if the new tag already exists
var sql = "SELECT tagID FROM tags WHERE name=? AND type=0";
var existingTagID = Zotero.DB.valueQuery(sql, name);
if (existingTagID) {
// New tag already exists as manual tag
if (existingTagID
// Tag check is case-insensitive, so make sure we have a
// different tag
&& existingTagID != tagID) {
// Change case of existing manual tag before switching automatic
if (oldName.toLowerCase() == name.toLowerCase()) {
var sql = "UPDATE tags SET name=? WHERE tagID=?";
Zotero.DB.query(sql, [name, existingTagID]);
}
var itemIDs = this.getTagItems(tagID);
var existingItemIDs = this.getTagItems(existingTagID);

View File

@ -1449,14 +1449,72 @@ Zotero.Schema = new function(){
statement.reset();
// Tags
var tags = Zotero.DB.query("SELECT * FROM tags");
var tags = Zotero.DB.query("SELECT tagID, tag AS tag, tagType FROM tags");
var newTags = [];
var cases = {};
if (tags) {
// Find tags with multiple case forms
for each(var row in tags) {
var l = row.tag.toLowerCase();
if (!cases[l]) {
cases[l] = [];
}
if (cases[l].indexOf(row.tag) == -1) {
cases[l].push(row.tag);
}
}
var done = {};
for each(var row in tags) {
var l = row.tag.toLowerCase();
if (done[l]) {
continue;
}
done[l] = true;
// Only one tag -- use
if (cases[l].length == 1) {
newTags.push(row);
continue;
}
// Use most frequent
var counts = Zotero.DB.query("SELECT tag, COUNT(*) AS numItems FROM tags NATURAL JOIN itemTags WHERE tag LIKE ? GROUP BY tag ORDER BY numItems DESC", l);
if (counts[0].numItems != counts[1].numItems) {
var newTag = counts[0].tag;
}
// Use earliest
else {
var newTag = Zotero.DB.valueQuery("SELECT tag FROM tags NATURAL JOIN itemTags WHERE tag IN (SELECT tag FROM tags NATURAL JOIN itemTags NATURAL JOIN items WHERE tag LIKE ? ORDER BY dateAdded LIMIT 1) GROUP BY tag", l);
}
// Point old to new
var types = Zotero.DB.columnQuery("SELECT DISTINCT tagType FROM tags WHERE tag LIKE ?", l);
for each(var type in types) {
var newTagID = Zotero.DB.valueQuery("SELECT tagID FROM tags WHERE tag=? AND tagType=?", [newTag, type]);
var oldIDs = Zotero.DB.columnQuery("SELECT tagID FROM tags WHERE tag LIKE ? AND tag != ? AND tagType=?", [l, l, type]);
if (!newTagID) {
if (oldIDs) {
newTagID = oldIDs[0];
}
else {
newTagID = Zotero.DB.valueQuery("SELECT MAX(tagID)+1 FROM tags");
Zotero.DB.query("INSERT INTO tags VALUES (?,?,?)", [newTagID, newTag, type]);
}
}
Zotero.DB.query("UPDATE OR REPLACE itemTags SET tagID=? WHERE tagID IN (" + oldIDs.map(function () '?').join() + ")", [newTagID].concat(oldIDs));
newTags.push({ tagID: newTagID, tag: newTag, tagType: type });
}
}
}
Zotero.DB.query("DROP TABLE tags");
Zotero.DB.query("CREATE TABLE tags (\n tagID INTEGER PRIMARY KEY,\n name TEXT,\n type INT,\n dateModified DEFAULT CURRENT_TIMESTAMP NOT NULL,\n key TEXT NOT NULL UNIQUE,\n UNIQUE (name, type)\n)");
Zotero.DB.query("CREATE TABLE tags (\n tagID INTEGER PRIMARY KEY,\n name TEXT COLLATE NOCASE,\n type INT,\n dateModified DEFAULT CURRENT_TIMESTAMP NOT NULL,\n key TEXT NOT NULL UNIQUE,\n UNIQUE (name, type)\n)");
var statement = Zotero.DB.getStatement("INSERT INTO tags (tagID, name, type, key) VALUES (?,?,?,?)");
for (var j=0, len=tags.length; j<len; j++) {
statement.bindInt32Parameter(0, tags[j].tagID);
statement.bindUTF8StringParameter(1, tags[j].tag);
statement.bindInt32Parameter(2, tags[j].tagType);
for (var j=0, len=newTags.length; j<len; j++) {
statement.bindInt32Parameter(0, newTags[j].tagID);
statement.bindUTF8StringParameter(1, newTags[j].tag);
statement.bindInt32Parameter(2, newTags[j].tagType);
var key = Zotero.ID.getKey();
statement.bindStringParameter(3, key);