www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

commit 432d89af249110367969c2ed118f264428d859d6
parent 32abbe7c2550162e42a9398fe96c3021cac74302
Author: Dan Stillman <dstillman@zotero.org>
Date:   Fri, 22 May 2015 13:38:50 -0400

Group data layer fixes

Diffstat:
Mchrome/content/zotero/xpcom/data/collection.js | 8++++++--
Mchrome/content/zotero/xpcom/data/group.js | 97++++++++++++++++++++++++++-----------------------------------------------------
Mchrome/content/zotero/xpcom/data/groups.js | 4++--
Mchrome/content/zotero/xpcom/data/item.js | 4+++-
Mchrome/content/zotero/xpcom/data/items.js | 2++
Mchrome/content/zotero/xpcom/data/relations.js | 32++++++++++++++++----------------
Mchrome/content/zotero/xpcom/search.js | 6++++--
Mchrome/content/zotero/xpcom/zotero.js | 17++++++++++++-----
8 files changed, 77 insertions(+), 93 deletions(-)

diff --git a/chrome/content/zotero/xpcom/data/collection.js b/chrome/content/zotero/xpcom/data/collection.js @@ -550,9 +550,11 @@ Zotero.Collection.prototype.clone = function (includePrimary, newCollection) { /** * Deletes collection and all descendent collections (and optionally items) **/ -Zotero.Collection.prototype._eraseData = Zotero.Promise.coroutine(function* (deleteItems) { +Zotero.Collection.prototype._eraseData = Zotero.Promise.coroutine(function* (env) { Zotero.DB.requireTransaction(); + var includeItems = env.options.deleteItems; + var collections = [this.id]; var descendents = yield this.getDescendents(false, null, true); @@ -612,7 +614,9 @@ Zotero.Collection.prototype._eraseData = Zotero.Promise.coroutine(function* (del this.ObjectsClass.unload(collections); //return Zotero.Collections.reloadAll(); - Zotero.Notifier.trigger('delete', 'collection', collections, notifierData); + if (!env.skipNotifier) { + Zotero.Notifier.trigger('delete', 'collection', collections, notifierData); + } }); diff --git a/chrome/content/zotero/xpcom/data/group.js b/chrome/content/zotero/xpcom/data/group.js @@ -219,7 +219,7 @@ Zotero.Group.prototype.hasItem = function (item) { } -Zotero.Group.prototype.save = function () { +Zotero.Group.prototype.save = Zotero.Promise.coroutine(function* () { if (!this.id) { throw ("ID not set in Zotero.Group.save()"); } @@ -233,14 +233,12 @@ Zotero.Group.prototype.save = function () { return false; } - Zotero.DB.beginTransaction(); - - var isNew = !this.exists(); - - try { + yield Zotero.DB.executeTransaction(function* () { + var isNew = !this.exists(); + Zotero.debug("Saving group " + this.id); - var columns = [ + var sqlColumns = [ 'groupID', 'libraryID', 'name', @@ -249,7 +247,6 @@ Zotero.Group.prototype.save = function () { 'filesEditable', 'version' ]; - var placeholders = columns.map(function () '?').join(); var sqlValues = [ this.id, this.libraryID, @@ -265,80 +262,57 @@ Zotero.Group.prototype.save = function () { Zotero.Libraries.add(this.libraryID, 'group'); } - var sql = "INSERT INTO groups (" + columns.join(', ') + ") " - + "VALUES (" + placeholders.join(', ') + ")"; - Zotero.DB.query(sql, sqlValues); + var sql = "INSERT INTO groups (" + sqlColumns.join(', ') + ") " + + "VALUES (" + sqlColumns.map(() => '?').join(', ') + ")"; + yield Zotero.DB.queryAsync(sql, sqlValues); } else { - columns.shift(); + sqlColumns.shift(); sqlValues.shift(); var sql = "UPDATE groups SET " - + columns.map(function (val) val + '=?').join(', ') + + sqlColumns.map(function (val) val + '=?').join(', ') + " WHERE groupID=?"; sqlValues.push(this.id); - Zotero.DB.query(sql, sqlValues); + yield Zotero.DB.queryAsync(sql, sqlValues); } - - Zotero.DB.commitTransaction(); - } - catch (e) { - Zotero.DB.rollbackTransaction(); - throw (e); - } + }.bind(this)); Zotero.Groups.register(this); - Zotero.Notifier.trigger('add', 'group', this.id); -} +}); /** * Deletes group and all descendant objects **/ Zotero.Group.prototype.erase = Zotero.Promise.coroutine(function* () { - // Don't send notifications for items and other groups objects that are deleted, - // since we're really only removing the group from the client - var notifierDisabled = Zotero.Notifier.disable(); - yield Zotero.DB.executeTransaction(function* () { + var notifierData = {}; + notifierData[this.id] = this.serialize(); // TODO: Replace with JSON + var sql, ids, obj; // Delete items - sql = "SELECT itemID FROM items WHERE libraryID=?"; - ids = yield Zotero.DB.columnQueryAsync(sql, this.libraryID); - yield Zotero.Items.erase(ids); - - // Delete collections - sql = "SELECT collectionID FROM collections WHERE libraryID=?"; - ids = yield Zotero.DB.columnQueryAsync(sql, this.libraryID); - for each(var id in ids) { - obj = yield Zotero.Collections.getAsync(id); - // Subcollections might've already been deleted - if (obj) { - yield obj.erase(); + var types = ['item', 'collection', 'search']; + for (let type of types) { + let objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(type); + let sql = "SELECT " + objectsClass.idColumn + " FROM " + objectsClass.table + + " WHERE libraryID=?"; + ids = yield Zotero.DB.columnQueryAsync(sql, this.libraryID); + for (let i = 0; i < ids.length; i++) { + let id = ids[i]; + let obj = yield Zotero.Items.getAsync(id, { noCache: true }); + yield obj.erase({ + skipNotifier: true + }); } } - // Delete creators - sql = "SELECT creatorID FROM creators WHERE libraryID=?"; - ids = yield Zotero.DB.columnQueryAsync(sql, this.libraryID); - for (let i=0; i<ids.length; i++) { - obj = yield Zotero.Creators.getAsync(ids[i]); - yield obj.erase(); - } - - // Delete saved searches - sql = "SELECT savedSearchID FROM savedSearches WHERE libraryID=?"; - ids = yield Zotero.DB.columnQueryAsync(sql, this.libraryID); - if (ids) { - yield Zotero.Searches.erase(ids); - } - - // Delete tags + /*// Delete tags sql = "SELECT tagID FROM tags WHERE libraryID=?"; ids = yield Zotero.DB.columnQueryAsync(sql, this.libraryID); - yield Zotero.Tags.erase(ids); + yield Zotero.Tags.erase(ids);*/ // Delete delete log entries sql = "DELETE FROM syncDeleteLog WHERE libraryID=?"; @@ -361,16 +335,9 @@ Zotero.Group.prototype.erase = Zotero.Promise.coroutine(function* () { yield Zotero.purgeDataObjects(); - var notifierData = {}; - notifierData[this.id] = this.serialize(); + Zotero.Groups.unregister(this.id); + Zotero.Notifier.trigger('delete', 'group', this.id, notifierData); }.bind(this)); - - if (notifierDisabled) { - Zotero.Notifier.enable(); - } - - Zotero.Groups.unregister(this.id); - Zotero.Notifier.trigger('delete', 'group', this.id, notifierData); }); diff --git a/chrome/content/zotero/xpcom/data/groups.js b/chrome/content/zotero/xpcom/data/groups.js @@ -97,11 +97,11 @@ Zotero.Groups = new function () { } - this.unregister = function (id) { + this.unregister = function (groupID) { var libraryID = _libraryIDsByGroupID[groupID]; delete _groupIDsByLibraryID[libraryID]; delete _libraryIDsByGroupID[groupID]; - delete _cache[id]; + delete _cache[groupID]; } diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js @@ -3970,7 +3970,9 @@ Zotero.Item.prototype._erasePreCommit = Zotero.Promise.coroutine(function* (env) this.ObjectsClass.unload(this.id); - Zotero.Notifier.trigger('delete', 'item', this.id, env.deletedItemNotifierData); + if (!env.skipNotifier) { + Zotero.Notifier.trigger('delete', 'item', this.id, env.deletedItemNotifierData); + } Zotero.Prefs.set('purge.items', true); Zotero.Prefs.set('purge.creators', true); diff --git a/chrome/content/zotero/xpcom/data/items.js b/chrome/content/zotero/xpcom/data/items.js @@ -608,6 +608,8 @@ Zotero.Items = function() { * Purge unused data values */ this.purge = Zotero.Promise.coroutine(function* () { + Zotero.DB.requireTransaction(); + if (!Zotero.Prefs.get('purge.items')) { return; } diff --git a/chrome/content/zotero/xpcom/data/relations.js b/chrome/content/zotero/xpcom/data/relations.js @@ -183,7 +183,7 @@ Zotero.Relations = function () { var ids = yield Zotero.DB.columnQueryAsync(sql, params); for (let i=0; i<ids.length; i++) { - let relation = this.get(ids[i]); + let relation = yield this.getAsync(ids[i]); yield relation.load(); yield relation.erase(); } @@ -206,7 +206,7 @@ Zotero.Relations = function () { var ids = yield Zotero.DB.columnQueryAsync(sql, params); for (let i=0; i<ids.length; i++) { - let relation = this.get(ids[i]); + let relation = yield this.getAsync(ids[i]); yield relation.load(); yield relation.erase(); } @@ -214,6 +214,8 @@ Zotero.Relations = function () { this.purge = Zotero.Promise.coroutine(function* () { + Zotero.DB.requireTransaction(); + Zotero.debug("Purging relations"); var t = new Date; var sql = "SELECT subject FROM relations WHERE predicate != ? " @@ -221,21 +223,19 @@ Zotero.Relations = function () { var uris = yield Zotero.DB.columnQueryAsync(sql, [this.deletedItemPredicate, this.deletedItemPredicate]); if (uris) { var prefix = Zotero.URI.defaultPrefix; - yield Zotero.DB.executeTransaction(function* () { - for each(var uri in uris) { - // Skip URIs that don't begin with the default prefix, - // since they don't correspond to local items - if (uri.indexOf(prefix) == -1) { - continue; - } - if (uri.indexOf("/items/") != -1 && !Zotero.URI.getURIItemID(uri)) { - yield this.eraseByURI(uri); - } - if (uri.indexOf("/collections/") != -1 && !Zotero.URI.getURICollectionID(uri)) { - yield this.eraseByURI(uri); - } + for each(var uri in uris) { + // Skip URIs that don't begin with the default prefix, + // since they don't correspond to local items + if (uri.indexOf(prefix) == -1) { + continue; + } + if (uri.indexOf("/items/") != -1 && !Zotero.URI.getURIItemID(uri)) { + yield this.eraseByURI(uri); } - }.bind(this)); + if (uri.indexOf("/collections/") != -1 && !Zotero.URI.getURICollectionID(uri)) { + yield this.eraseByURI(uri); + } + } Zotero.debug("Purged relations in " + ((new Date) - t) + "ms"); } }); diff --git a/chrome/content/zotero/xpcom/search.js b/chrome/content/zotero/xpcom/search.js @@ -213,7 +213,7 @@ Zotero.Search.prototype.clone = function (libraryID) { }; -Zotero.Search.prototype._eraseData = Zotero.Promise.coroutine(function* () { +Zotero.Search.prototype._eraseData = Zotero.Promise.coroutine(function* (env) { Zotero.DB.requireTransaction(); var notifierData = {}; @@ -228,7 +228,9 @@ Zotero.Search.prototype._eraseData = Zotero.Promise.coroutine(function* () { var sql = "DELETE FROM savedSearches WHERE savedSearchID=?"; yield Zotero.DB.queryAsync(sql, this.id); - Zotero.Notifier.trigger('delete', 'search', this.id, notifierData); + if (!env.skipNotifier) { + Zotero.Notifier.trigger('delete', 'search', this.id, notifierData); + } }); diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js @@ -2052,14 +2052,21 @@ Components.utils.import("resource://gre/modules/osfile.jsm"); * Clear entries that no longer exist from various tables */ this.purgeDataObjects = Zotero.Promise.coroutine(function* (skipStoragePurge) { - yield Zotero.Creators.purge(); - yield Zotero.Tags.purge(); + yield Zotero.DB.executeTransaction(function* () { + return Zotero.Creators.purge(); + }); + yield Zotero.DB.executeTransaction(function* () { + return Zotero.Tags.purge(); + }); // TEMP: Disabled until we have async DB (and maybe SQLite FTS) //Zotero.Fulltext.purgeUnusedWords(); - yield Zotero.Items.purge(); + yield Zotero.DB.executeTransaction(function* () { + yield Zotero.Items.purge(); + }); // DEBUG: this might not need to be permanent - yield Zotero.Relations.purge(); - yield Zotero.CharacterSets.purge(); + yield Zotero.DB.executeTransaction(function* () { + yield Zotero.Relations.purge(); + }); });