From aa2e0a8582bc606784ae87265edff0dbbb60e61d Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Thu, 4 Jun 2015 19:25:45 -0400 Subject: [PATCH] Update Zotero.Relations.updateUser() for new relations schema Also adds Zotero.DataObjects::getLoaded(), which returns an array of all loaded objects of the given type. This is useful for selective reloading, for example with item.reload(['relations'], true). --- .../content/zotero/xpcom/data/dataObjects.js | 10 +++++ chrome/content/zotero/xpcom/data/relations.js | 40 ++++++++--------- test/tests/relationsTest.js | 43 +++++++++++++++++++ 3 files changed, 70 insertions(+), 23 deletions(-) diff --git a/chrome/content/zotero/xpcom/data/dataObjects.js b/chrome/content/zotero/xpcom/data/dataObjects.js index edbfb5dc9b..adeaa0f35a 100644 --- a/chrome/content/zotero/xpcom/data/dataObjects.js +++ b/chrome/content/zotero/xpcom/data/dataObjects.js @@ -190,6 +190,16 @@ Zotero.DataObjects.prototype.getAsync = Zotero.Promise.coroutine(function* (ids, }); +/** + * Get all loaded objects + * + * @return {Zotero.DataObject[]} + */ +Zotero.DataObjects.prototype.getLoaded = function () { + return Object.keys(this._objectCache).map(id => this._objectCache[id]); +} + + /** * @deprecated - use .libraryKey */ diff --git a/chrome/content/zotero/xpcom/data/relations.js b/chrome/content/zotero/xpcom/data/relations.js index d8bb060fa2..005b1fc15d 100644 --- a/chrome/content/zotero/xpcom/data/relations.js +++ b/chrome/content/zotero/xpcom/data/relations.js @@ -83,32 +83,27 @@ Zotero.Relations = new function () { }); - this.updateUser = Zotero.Promise.coroutine(function* (fromUserID, fromLibraryID, toUserID, toLibraryID) { + this.updateUser = Zotero.Promise.coroutine(function* (toUserID) { + var fromUserID = Zotero.Users.getCurrentUserID(); if (!fromUserID) { - throw ("Invalid source userID " + fromUserID + " in Zotero.Relations.updateUserID"); - } - if (!fromLibraryID) { - throw ("Invalid source libraryID " + fromLibraryID + " in Zotero.Relations.updateUserID"); + fromUserID = "local/" + Zotero.Users.getLocalUserKey(); } if (!toUserID) { - throw ("Invalid target userID " + toUserID + " in Zotero.Relations.updateUserID"); + throw new Error("Invalid target userID " + toUserID); } - if (!toLibraryID) { - throw ("Invalid target libraryID " + toLibraryID + " in Zotero.Relations.updateUserID"); - } - - yield Zotero.DB.executeTransaction(function* () { - var sql = "UPDATE relations SET libraryID=? WHERE libraryID=?"; - yield Zotero.DB.queryAsync(sql, [toLibraryID, fromLibraryID]); + Zotero.DB.requireTransaction(); + for (let type of _types) { + var sql = "UPDATE " + type + "Relations SET " + + "object=REPLACE(object, 'zotero.org/users/" + fromUserID + "', " + + "'zotero.org/users/" + toUserID + "')"; + yield Zotero.DB.queryAsync(sql); - sql = "UPDATE relations SET " - + "subject=REPLACE(subject, 'zotero.org/users/" + fromUserID + "', " - + "'zotero.org/users/" + toUserID + "'), " - + "object=REPLACE(object, 'zotero.org/users/" + fromUserID + "', " - + "'zotero.org/users/" + toUserID + "') " - + "WHERE predicate IN (?, ?)"; - yield Zotero.DB.queryAsync(sql, [this.linkedObjectPredicate, this.replacedItemPredicate]); - }.bind(this)); + var objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(type); + var objects = objectsClass.getLoaded(); + for (let object of objects) { + yield object.reload(['relations'], true); + } + } }); @@ -118,8 +113,7 @@ Zotero.Relations = new function () { Zotero.DB.requireTransaction(); var t = new Date; let prefix = Zotero.URI.defaultPrefix; - var types = ['collection', 'item']; - for (let type of types) { + for (let type of _types) { let objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(type); let getFunc = "getURI" + Zotero.Utilities.capitalize(type); let objects = {}; diff --git a/test/tests/relationsTest.js b/test/tests/relationsTest.js index 21720f9a5b..d5e7898aa1 100644 --- a/test/tests/relationsTest.js +++ b/test/tests/relationsTest.js @@ -21,4 +21,47 @@ describe("Zotero.Relations", function () { assert.equal(objects[0], item); }) }) + + describe("#updateUser", function () { + beforeEach(function* () { + yield Zotero.DB.queryAsync("DELETE FROM settings WHERE setting='account'"); + yield Zotero.Users.init(); + }) + + it("should update relations using local user key to use userID", function* () { + var item1 = yield createDataObject('item'); + var item2 = createUnsavedDataObject('item'); + item2.addRelatedItem(item1); + yield item2.save(); + + var rels = item2.getRelationsByPredicate(Zotero.Relations.relatedItemPredicate); + assert.include(rels[0], "/users/local"); + + yield Zotero.DB.executeTransaction(function* () { + yield Zotero.Relations.updateUser(1); + }) + + var rels = item2.getRelationsByPredicate(Zotero.Relations.relatedItemPredicate); + assert.include(rels[0], "/users/1"); + }) + + it("should update relations from one userID to another", function* () { + yield Zotero.Users.setCurrentUserID(1); + + var item1 = yield createDataObject('item'); + var item2 = createUnsavedDataObject('item'); + item2.addRelatedItem(item1); + yield item2.save(); + + var rels = item2.getRelationsByPredicate(Zotero.Relations.relatedItemPredicate); + assert.include(rels[0], "/users/1"); + + yield Zotero.DB.executeTransaction(function* () { + yield Zotero.Relations.updateUser(2); + }); + + var rels = item2.getRelationsByPredicate(Zotero.Relations.relatedItemPredicate); + assert.include(rels[0], "/users/2"); + }) + }) })