From 96e88bda1e14fc2b6cfefb39c84f6b541aab22b7 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Wed, 13 Aug 2008 06:38:47 +0000 Subject: [PATCH] - Change local key if remote item has different id but different key (which should mostly be with the Quick Start Guide) - Moved common singleton data logic (for now, just getByKey()) into Zotero.DataObjects, and use that as template for other data objects --- .../content/zotero/xpcom/data/collections.js | 3 ++ chrome/content/zotero/xpcom/data/creators.js | 3 ++ .../content/zotero/xpcom/data/dataObjects.js | 34 +++++++++++++ chrome/content/zotero/xpcom/data/item.js | 2 + chrome/content/zotero/xpcom/data/items.js | 20 ++------ chrome/content/zotero/xpcom/data/tags.js | 3 ++ chrome/content/zotero/xpcom/search.js | 3 ++ chrome/content/zotero/xpcom/sync.js | 21 +++++--- components/zotero-service.js | 50 ++++++++++++++++--- 9 files changed, 106 insertions(+), 33 deletions(-) create mode 100644 chrome/content/zotero/xpcom/data/dataObjects.js diff --git a/chrome/content/zotero/xpcom/data/collections.js b/chrome/content/zotero/xpcom/data/collections.js index 44f2441ca9..f366926a01 100644 --- a/chrome/content/zotero/xpcom/data/collections.js +++ b/chrome/content/zotero/xpcom/data/collections.js @@ -25,6 +25,9 @@ * Primary interface for accessing Zotero collection */ Zotero.Collections = new function() { + Zotero.DataObjects.apply(this, ['collection']); + this.constructor.prototype = new Zotero.DataObjects(); + var _collections = {}; var _collectionsLoaded = false; diff --git a/chrome/content/zotero/xpcom/data/creators.js b/chrome/content/zotero/xpcom/data/creators.js index 8acc69c7b6..ae3d320052 100644 --- a/chrome/content/zotero/xpcom/data/creators.js +++ b/chrome/content/zotero/xpcom/data/creators.js @@ -22,6 +22,9 @@ Zotero.Creators = new function() { + Zotero.DataObjects.apply(this, ['creator']); + this.constructor.prototype = new Zotero.DataObjects(); + var _creatorsByID = {}; // Zotero.Creator objects indexed by creatorID var _creatorDataHash = {}; // creatorDataIDs indexed by md5 hash of data diff --git a/chrome/content/zotero/xpcom/data/dataObjects.js b/chrome/content/zotero/xpcom/data/dataObjects.js new file mode 100644 index 0000000000..ac55d8a288 --- /dev/null +++ b/chrome/content/zotero/xpcom/data/dataObjects.js @@ -0,0 +1,34 @@ +Zotero.DataObjects = function (object, objectPlural) { + var self = this; + + if (!object) { + object = ''; + } + + // Override these variables in child objects + this._ZDO_object = object; + this._ZDO_objects = objectPlural ? objectPlural : object + 's'; + this._ZDO_Object = object.substr(0, 1).toUpperCase() + object.substr(1); + this._ZDO_Objects = this._ZDO_objects.substr(0, 1).toUpperCase() + + this._ZDO_objects.substr(1); + this._ZDO_id = object + 'ID'; + this._ZDO_table = this._ZDO_objects; + + + /** + * Retrieves an object by its secondary lookup key + * + * @param string key Secondary lookup key + * @return object Zotero data object, or FALSE if not found + */ + this.getByKey = function (key) { + var sql = "SELECT " + this._ZDO_id + " FROM " + this._ZDO_table + + " WHERE key=?"; + var id = Zotero.DB.valueQuery(sql, key); + if (!id) { + return false; + } + return Zotero[this._ZDO_Objects].get(id); + } +} + diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js index 3ef880db79..b8ee132dd0 100644 --- a/chrome/content/zotero/xpcom/data/item.js +++ b/chrome/content/zotero/xpcom/data/item.js @@ -96,10 +96,12 @@ Zotero.Item.prototype._init = function () { Zotero.Item.prototype.__defineGetter__('id', function () { return this._itemID; }); Zotero.Item.prototype.__defineGetter__('itemID', function () { return this._itemID; }); +Zotero.Item.prototype.__defineSetter__('itemID', function (val) { return this.setField('itemID', val); }); // used by sync.js Zotero.Item.prototype.__defineGetter__('itemTypeID', function () { return this.getField('itemTypeID'); }); Zotero.Item.prototype.__defineGetter__('dateAdded', function () { return this.getField('dateAdded'); }); Zotero.Item.prototype.__defineGetter__('dateModified', function () { return this.getField('dateModified'); }); Zotero.Item.prototype.__defineGetter__('key', function () { return this.getField('key'); }); +Zotero.Item.prototype.__defineSetter__('key', function (val) { return this.setField('key', val); }); // used by sync.js Zotero.Item.prototype.__defineGetter__('firstCreator', function () { return this.getField('firstCreator'); }); //Zotero.Item.prototype.__defineGetter__('numNotes', function () { return this._itemID; }); //Zotero.Item.prototype.__defineGetter__('numAttachments', function () { return this._itemID; }); diff --git a/chrome/content/zotero/xpcom/data/items.js b/chrome/content/zotero/xpcom/data/items.js index 4fed9aa39f..d4839da42e 100644 --- a/chrome/content/zotero/xpcom/data/items.js +++ b/chrome/content/zotero/xpcom/data/items.js @@ -25,9 +25,11 @@ * Primary interface for accessing Zotero items */ Zotero.Items = new function() { + Zotero.DataObjects.apply(this, ['item']); + this.constructor.prototype = new Zotero.DataObjects(); + // Privileged methods this.get = get; - this.getByKey = getByKey; this.exist = exist; this.getAll = getAll; this.getUpdated = getUpdated; @@ -102,22 +104,6 @@ Zotero.Items = new function() { } - /** - * Retrieves an item by its secondary lookup key - * - * @param string key Secondary lookup key - * @return object Zotero.Item object, or FALSE if not found - */ - function getByKey(key) { - var sql = "SELECT itemID FROM items WHERE key=?"; - var itemID = Zotero.DB.valueQuery(sql, key); - if (!itemID) { - return false; - } - return Zotero.Items.get(itemID); - } - - function exist(itemIDs) { var sql = "SELECT itemID FROM items WHERE itemID IN (" + itemIDs.map(function () '?').join() + ")"; diff --git a/chrome/content/zotero/xpcom/data/tags.js b/chrome/content/zotero/xpcom/data/tags.js index 217f1dc6bb..6c5bb19ed1 100644 --- a/chrome/content/zotero/xpcom/data/tags.js +++ b/chrome/content/zotero/xpcom/data/tags.js @@ -25,6 +25,9 @@ * Same structure as Zotero.Creators -- make changes in both places if possible */ Zotero.Tags = new function() { + Zotero.DataObjects.apply(this, ['tag']); + this.constructor.prototype = new Zotero.DataObjects(); + var _tags = []; // indexed by tag text var _tagsByID = []; // indexed by tagID diff --git a/chrome/content/zotero/xpcom/search.js b/chrome/content/zotero/xpcom/search.js index 5ec6633bf9..e16fac7bd5 100644 --- a/chrome/content/zotero/xpcom/search.js +++ b/chrome/content/zotero/xpcom/search.js @@ -1483,6 +1483,9 @@ Zotero.Search.prototype._generateKey = function () { Zotero.Searches = new function(){ + Zotero.DataObjects.apply(this, ['search', 'searches']); + this.constructor.prototype = new Zotero.DataObjects(); + this.get = get; this.getAll = getAll; this.getUpdated = getUpdated; diff --git a/chrome/content/zotero/xpcom/sync.js b/chrome/content/zotero/xpcom/sync.js index 2ac12b8d08..46d661c3fb 100644 --- a/chrome/content/zotero/xpcom/sync.js +++ b/chrome/content/zotero/xpcom/sync.js @@ -1423,14 +1423,7 @@ Zotero.Sync.Server.Data = new function() { Zotero.debug("Changing " + type + " " + oldID + " id to " + newID); // Save changed object now to update other linked objects - switch (type) { - case 'item': - obj.setField('itemID', newID); - break; - - default: - obj[type + 'ID'] = newID; - } + obj[type + 'ID'] = newID; obj.save(); // Update id in local updates array @@ -1489,6 +1482,18 @@ Zotero.Sync.Server.Data = new function() { localDelete = true; } + + // If key already exists on a different item, change local key + var oldKey = xmlNode.@key.toString(); + var keyObj = Zotero[Types].getByKey(oldKey); + if (keyObj) { + var newKey = Zotero.ID.getKey(); + Zotero.debug("Changing key of local " + type + " " + keyObj.id + + " from '" + oldKey + "' to '" + newKey + "'", 2); + keyObj.key = newKey; + keyObj.save(); + Zotero.Sync.addToUpdated(uploadIDs.updated[types], keyObj.id); + } } // Temporarily remove and store related items that don't yet exist diff --git a/components/zotero-service.js b/components/zotero-service.js index 2c6990fe6e..9a298cdca3 100644 --- a/components/zotero-service.js +++ b/components/zotero-service.js @@ -14,14 +14,48 @@ var ZoteroWrapped = this; * Include the core objects to be stored within XPCOM *********************************************************************/ -var xpcomFiles = ['zotero', - 'annotate', 'attachments', 'cite', 'collectionTreeView', - 'dataServer', 'data_access', 'data/item', 'data/items', 'data/collection', - 'data/collections', 'data/cachedTypes', 'data/creator', 'data/creators', - 'data/itemFields', 'data/notes', 'data/tag', 'data/tags', 'db', 'enstyle', - 'file', 'fulltext', 'id', 'ingester', 'integration', 'itemTreeView', 'mime', - 'notifier', 'progressWindow', 'proxy', 'quickCopy', 'report', 'schema', 'search', - 'sync', 'timeline', 'translate', 'utilities', 'zeroconf']; +var xpcomFiles = [ + 'zotero', + 'annotate', + 'attachments', + 'cite', + 'collectionTreeView', + 'dataServer', + 'data_access', + 'data/dataObjects', + 'data/cachedTypes', + 'data/item', + 'data/items', + 'data/collection', + 'data/collections', + 'data/creator', + 'data/creators', + 'data/itemFields', + 'data/notes', + 'data/tag', + 'data/tags', + 'db', + 'enstyle', + 'file', + 'fulltext', + 'id', + 'ingester', + 'integration', + 'itemTreeView', + 'mime', + 'notifier', + 'progressWindow', + 'proxy', + 'quickCopy', + 'report', + 'schema', + 'search', + 'sync', + 'timeline', + 'translate', + 'utilities', + 'zeroconf' +]; for (var i=0; i