commit 67831bcb790c171411a4d9b267b07c2a662df6a1
parent d8bdb6c11d18922b35818790cb2490c3f72674b3
Author: Dan Stillman <dstillman@zotero.org>
Date: Mon, 12 Oct 2009 08:14:11 +0000
- Address "Delete reconciliation unimplemented for collections" message
- If collection items were added/removed on both sides, items from both sides were not always added
- Fix a couple other related glitches which may or may not have shown up before the above issues were fixed
Diffstat:
3 files changed, 37 insertions(+), 37 deletions(-)
diff --git a/chrome/content/zotero/xpcom/schema.js b/chrome/content/zotero/xpcom/schema.js
@@ -2472,6 +2472,13 @@ Zotero.Schema = new function(){
Zotero.DB.query("UPDATE version SET schema='storage_webdav' WHERE schema='storage'");
}
+ if (i==64) {
+ Zotero.DB.query("ALTER TABLE syncDeleteLog RENAME TO syncDeleteLogOld");
+ Zotero.DB.query("CREATE TABLE syncDeleteLog (\n syncObjectTypeID INT NOT NULL,\n libraryID INT NOT NULL,\n key TEXT NOT NULL,\n timestamp INT NOT NULL,\n UNIQUE (syncObjectTypeID, libraryID, key),\n FOREIGN KEY (syncObjectTypeID) REFERENCES syncObjectTypes(syncObjectTypeID)\n)");
+ Zotero.DB.query("INSERT INTO syncDeleteLog SELECT * FROM syncDeleteLogOld");
+ Zotero.DB.query("DROP TABLE syncDeleteLogOld");
+ }
+
Zotero.wait();
}
diff --git a/chrome/content/zotero/xpcom/sync.js b/chrome/content/zotero/xpcom/sync.js
@@ -374,7 +374,7 @@ Zotero.Sync.EventListener = new function () {
Zotero.DB.beginTransaction();
if (event == 'delete') {
- var sql = "INSERT INTO syncDeleteLog VALUES (?, ?, ?, ?)";
+ var sql = "REPLACE INTO syncDeleteLog VALUES (?, ?, ?, ?)";
var syncStatement = Zotero.DB.getStatement(sql);
if (isItem && Zotero.Sync.Storage.active) {
@@ -2337,6 +2337,7 @@ Zotero.Sync.Server.Data = new function() {
Zotero.debug("Processing remote " + type + " " + libraryID + "/" + key, 4);
var isNewObject;
var localDelete = false;
+ var skipCR = false;
// Get local object with same library and key
var obj = Zotero[Types].getByLibraryAndKey(libraryID, key);
@@ -2391,8 +2392,6 @@ Zotero.Sync.Server.Data = new function() {
}
// Mark other types for conflict resolution
else {
- var skipCR = false;
-
// Skip item if dateModified is the only modified
// field (and no linked creators changed)
switch (type) {
@@ -2455,8 +2454,7 @@ Zotero.Sync.Server.Data = new function() {
break;
case 'collection':
- // TODO: move childItemStore to syncSession
- var changed = _mergeCollection(obj, remoteObj, childItemStore, syncSession);
+ var changed = _mergeCollection(obj, remoteObj, syncSession);
if (!changed) {
syncSession.removeFromUpdated(obj);
continue;
@@ -2476,7 +2474,6 @@ Zotero.Sync.Server.Data = new function() {
// TODO: order reconcile by parent/child?
if (!skipCR) {
- Zotero.debug("ADDING " + type + " TO CR");
toReconcile.push([
obj,
remoteObj
@@ -2512,15 +2509,16 @@ Zotero.Sync.Server.Data = new function() {
localDelete = true;
break;
- // Auto-restore locally deleted tags that have
- // changed remotely
+ // Auto-restore locally deleted tags and collections that
+ // have changed remotely
case 'tag':
+ case 'collection':
syncSession.removeFromDeleted(fakeObj);
var msg = _generateAutoChangeMessage(
type, null, xmlNode.@name.toString()
);
alert(msg);
- continue;
+ break;
default:
alert('Delete reconciliation unimplemented for ' + types);
@@ -2539,7 +2537,11 @@ Zotero.Sync.Server.Data = new function() {
}
// Create or overwrite locally
- obj = Zotero.Sync.Server.Data['xmlTo' + Type](xmlNode, obj);
+ //
+ // If we skipped CR above, we already have an object to use
+ if (!skipCR) {
+ obj = Zotero.Sync.Server.Data['xmlTo' + Type](xmlNode, obj);
+ }
if (isNewObject && type == 'tag') {
// If a local tag matches the name of a different remote tag,
@@ -2653,6 +2655,7 @@ Zotero.Sync.Server.Data = new function() {
break;
case 'tag':
+ case 'collection':
var msg = _generateAutoChangeMessage(
type, obj.name, null
);
@@ -2961,7 +2964,7 @@ Zotero.Sync.Server.Data = new function() {
}
- function _mergeCollection(localObj, remoteObj, childItemStore, syncSession) {
+ function _mergeCollection(localObj, remoteObj, syncSession) {
var diff = localObj.diff(remoteObj, false, true);
if (!diff) {
return false;
@@ -2972,20 +2975,18 @@ Zotero.Sync.Server.Data = new function() {
// Local is newer
if (diff[0].primary.dateModified > diff[1].primary.dateModified) {
+ Zotero.debug("Local is newer");
var remoteIsTarget = false;
var targetObj = localObj;
- var targetDiff = diff[0];
- var otherDiff = diff[1];
}
// Remote is newer
else {
+ Zotero.debug("Remote is newer");
var remoteIsTarget = true;
var targetObj = remoteObj;
- var targetDiff = diff[1];
- var otherDiff = diff[0];
}
- if (targetDiff.fields.name) {
+ if (diff[0].fields.name) {
if (!syncSession.suppressWarnings) {
var msg = _generateAutoChangeMessage(
'collection', diff[0].fields.name, diff[1].fields.name, remoteIsTarget
@@ -2997,27 +2998,26 @@ Zotero.Sync.Server.Data = new function() {
// Check for child collections in the other object
// that aren't in the target one
- if (otherDiff.childCollections.length) {
+ if (diff[1].childCollections.length) {
// TODO: log
// TODO: add
throw ("Collection hierarchy conflict resolution is unimplemented");
}
- // Add items in other object to target one
- if (otherDiff.childItems.length) {
- var childItems = targetObj.getChildItems(true);
+ // Add items to local object, which is what's saved
+ if (diff[1].childItems.length) {
+ var childItems = localObj.getChildItems(true);
if (childItems) {
- targetObj.childItems = childItems.concat(otherDiff.childItems);
+ localObj.childItems = childItems.concat(diff[1].childItems);
}
else {
- targetObj.childItems = otherDiff.childItems;
+ localObj.childItems = diff[1].childItems;
}
if (!syncSession.suppressWarnings) {
var msg = _generateCollectionItemMergeMessage(
targetObj.name,
- otherDiff.childItems,
- remoteIsTarget
+ diff[0].childItems.concat(diff[1].childItems)
);
// TODO: log rather than alert
alert(msg);
@@ -3123,25 +3123,18 @@ Zotero.Sync.Server.Data = new function() {
/**
* @param {String} collectionName
* @param {Integer[]} addedItemIDs
- * @param {Boolean} remoteIsTarget
*/
- function _generateCollectionItemMergeMessage(collectionName, addedItemIDs, remoteIsTarget) {
+ function _generateCollectionItemMergeMessage(collectionName, addedItemIDs) {
// TODO: localize
var introMsg = "Items in the collection '" + collectionName + "' have been "
+ "added and/or removed in multiple locations."
- introMsg += " ";
- if (remoteIsTarget) {
- introMsg += "The following items have been added to the remote collection:";
- }
- else {
- introMsg += "The following items have been added to the local collection:";
- }
+ introMsg += " The following items have been added to the collection:";
var itemText = [];
for each(var id in addedItemIDs) {
var item = Zotero.Items.get(id);
var title = item.getField('title');
- var text = " - " + title;
+ var text = " \u2022 " + title;
var firstCreator = item.getField('firstCreator');
if (firstCreator) {
text += " (" + firstCreator + ")";
diff --git a/userdata.sql b/userdata.sql
@@ -1,4 +1,4 @@
--- 63
+-- 64
-- This file creates tables containing user-specific data for new users --
-- any changes made here must be mirrored in transition steps in schema.js::_migrateSchema()
@@ -258,10 +258,10 @@ CREATE INDEX fulltextItemWords_itemID ON fulltextItemWords(itemID);
CREATE TABLE syncDeleteLog (
syncObjectTypeID INT NOT NULL,
- libraryID INT,
+ libraryID INT NOT NULL,
key TEXT NOT NULL,
timestamp INT NOT NULL,
- UNIQUE (libraryID, key),
+ UNIQUE (syncObjectTypeID, libraryID, key),
FOREIGN KEY (syncObjectTypeID) REFERENCES syncObjectTypes(syncObjectTypeID)
);
CREATE INDEX syncDeleteLog_timestamp ON syncDeleteLog(timestamp);