Group data layer fixes

This commit is contained in:
Dan Stillman 2015-05-22 13:38:50 -04:00
parent 32abbe7c25
commit 432d89af24
8 changed files with 77 additions and 93 deletions

View file

@ -550,9 +550,11 @@ Zotero.Collection.prototype.clone = function (includePrimary, newCollection) {
/** /**
* Deletes collection and all descendent collections (and optionally items) * 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(); Zotero.DB.requireTransaction();
var includeItems = env.options.deleteItems;
var collections = [this.id]; var collections = [this.id];
var descendents = yield this.getDescendents(false, null, true); 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); this.ObjectsClass.unload(collections);
//return Zotero.Collections.reloadAll(); //return Zotero.Collections.reloadAll();
Zotero.Notifier.trigger('delete', 'collection', collections, notifierData); if (!env.skipNotifier) {
Zotero.Notifier.trigger('delete', 'collection', collections, notifierData);
}
}); });

View file

@ -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) { if (!this.id) {
throw ("ID not set in Zotero.Group.save()"); throw ("ID not set in Zotero.Group.save()");
} }
@ -233,14 +233,12 @@ Zotero.Group.prototype.save = function () {
return false; return false;
} }
Zotero.DB.beginTransaction(); yield Zotero.DB.executeTransaction(function* () {
var isNew = !this.exists();
var isNew = !this.exists();
try {
Zotero.debug("Saving group " + this.id); Zotero.debug("Saving group " + this.id);
var columns = [ var sqlColumns = [
'groupID', 'groupID',
'libraryID', 'libraryID',
'name', 'name',
@ -249,7 +247,6 @@ Zotero.Group.prototype.save = function () {
'filesEditable', 'filesEditable',
'version' 'version'
]; ];
var placeholders = columns.map(function () '?').join();
var sqlValues = [ var sqlValues = [
this.id, this.id,
this.libraryID, this.libraryID,
@ -265,80 +262,57 @@ Zotero.Group.prototype.save = function () {
Zotero.Libraries.add(this.libraryID, 'group'); Zotero.Libraries.add(this.libraryID, 'group');
} }
var sql = "INSERT INTO groups (" + columns.join(', ') + ") " var sql = "INSERT INTO groups (" + sqlColumns.join(', ') + ") "
+ "VALUES (" + placeholders.join(', ') + ")"; + "VALUES (" + sqlColumns.map(() => '?').join(', ') + ")";
Zotero.DB.query(sql, sqlValues); yield Zotero.DB.queryAsync(sql, sqlValues);
} }
else { else {
columns.shift(); sqlColumns.shift();
sqlValues.shift(); sqlValues.shift();
var sql = "UPDATE groups SET " var sql = "UPDATE groups SET "
+ columns.map(function (val) val + '=?').join(', ') + sqlColumns.map(function (val) val + '=?').join(', ')
+ " WHERE groupID=?"; + " WHERE groupID=?";
sqlValues.push(this.id); sqlValues.push(this.id);
Zotero.DB.query(sql, sqlValues); yield Zotero.DB.queryAsync(sql, sqlValues);
} }
}.bind(this));
Zotero.DB.commitTransaction();
}
catch (e) {
Zotero.DB.rollbackTransaction();
throw (e);
}
Zotero.Groups.register(this); Zotero.Groups.register(this);
Zotero.Notifier.trigger('add', 'group', this.id); Zotero.Notifier.trigger('add', 'group', this.id);
} });
/** /**
* Deletes group and all descendant objects * Deletes group and all descendant objects
**/ **/
Zotero.Group.prototype.erase = Zotero.Promise.coroutine(function* () { 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* () { yield Zotero.DB.executeTransaction(function* () {
var notifierData = {};
notifierData[this.id] = this.serialize(); // TODO: Replace with JSON
var sql, ids, obj; var sql, ids, obj;
// Delete items // Delete items
sql = "SELECT itemID FROM items WHERE libraryID=?"; var types = ['item', 'collection', 'search'];
ids = yield Zotero.DB.columnQueryAsync(sql, this.libraryID); for (let type of types) {
yield Zotero.Items.erase(ids); let objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(type);
let sql = "SELECT " + objectsClass.idColumn + " FROM " + objectsClass.table
// Delete collections + " WHERE libraryID=?";
sql = "SELECT collectionID FROM collections WHERE libraryID=?"; ids = yield Zotero.DB.columnQueryAsync(sql, this.libraryID);
ids = yield Zotero.DB.columnQueryAsync(sql, this.libraryID); for (let i = 0; i < ids.length; i++) {
for each(var id in ids) { let id = ids[i];
obj = yield Zotero.Collections.getAsync(id); let obj = yield Zotero.Items.getAsync(id, { noCache: true });
// Subcollections might've already been deleted yield obj.erase({
if (obj) { skipNotifier: true
yield obj.erase(); });
} }
} }
// Delete creators /*// Delete tags
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
sql = "SELECT tagID FROM tags WHERE libraryID=?"; sql = "SELECT tagID FROM tags WHERE libraryID=?";
ids = yield Zotero.DB.columnQueryAsync(sql, this.libraryID); ids = yield Zotero.DB.columnQueryAsync(sql, this.libraryID);
yield Zotero.Tags.erase(ids); yield Zotero.Tags.erase(ids);*/
// Delete delete log entries // Delete delete log entries
sql = "DELETE FROM syncDeleteLog WHERE libraryID=?"; sql = "DELETE FROM syncDeleteLog WHERE libraryID=?";
@ -361,16 +335,9 @@ Zotero.Group.prototype.erase = Zotero.Promise.coroutine(function* () {
yield Zotero.purgeDataObjects(); yield Zotero.purgeDataObjects();
var notifierData = {}; Zotero.Groups.unregister(this.id);
notifierData[this.id] = this.serialize(); Zotero.Notifier.trigger('delete', 'group', this.id, notifierData);
}.bind(this)); }.bind(this));
if (notifierDisabled) {
Zotero.Notifier.enable();
}
Zotero.Groups.unregister(this.id);
Zotero.Notifier.trigger('delete', 'group', this.id, notifierData);
}); });

View file

@ -97,11 +97,11 @@ Zotero.Groups = new function () {
} }
this.unregister = function (id) { this.unregister = function (groupID) {
var libraryID = _libraryIDsByGroupID[groupID]; var libraryID = _libraryIDsByGroupID[groupID];
delete _groupIDsByLibraryID[libraryID]; delete _groupIDsByLibraryID[libraryID];
delete _libraryIDsByGroupID[groupID]; delete _libraryIDsByGroupID[groupID];
delete _cache[id]; delete _cache[groupID];
} }

View file

@ -3970,7 +3970,9 @@ Zotero.Item.prototype._erasePreCommit = Zotero.Promise.coroutine(function* (env)
this.ObjectsClass.unload(this.id); 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.items', true);
Zotero.Prefs.set('purge.creators', true); Zotero.Prefs.set('purge.creators', true);

View file

@ -608,6 +608,8 @@ Zotero.Items = function() {
* Purge unused data values * Purge unused data values
*/ */
this.purge = Zotero.Promise.coroutine(function* () { this.purge = Zotero.Promise.coroutine(function* () {
Zotero.DB.requireTransaction();
if (!Zotero.Prefs.get('purge.items')) { if (!Zotero.Prefs.get('purge.items')) {
return; return;
} }

View file

@ -183,7 +183,7 @@ Zotero.Relations = function () {
var ids = yield Zotero.DB.columnQueryAsync(sql, params); var ids = yield Zotero.DB.columnQueryAsync(sql, params);
for (let i=0; i<ids.length; i++) { 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.load();
yield relation.erase(); yield relation.erase();
} }
@ -206,7 +206,7 @@ Zotero.Relations = function () {
var ids = yield Zotero.DB.columnQueryAsync(sql, params); var ids = yield Zotero.DB.columnQueryAsync(sql, params);
for (let i=0; i<ids.length; i++) { 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.load();
yield relation.erase(); yield relation.erase();
} }
@ -214,6 +214,8 @@ Zotero.Relations = function () {
this.purge = Zotero.Promise.coroutine(function* () { this.purge = Zotero.Promise.coroutine(function* () {
Zotero.DB.requireTransaction();
Zotero.debug("Purging relations"); Zotero.debug("Purging relations");
var t = new Date; var t = new Date;
var sql = "SELECT subject FROM relations WHERE predicate != ? " 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]); var uris = yield Zotero.DB.columnQueryAsync(sql, [this.deletedItemPredicate, this.deletedItemPredicate]);
if (uris) { if (uris) {
var prefix = Zotero.URI.defaultPrefix; var prefix = Zotero.URI.defaultPrefix;
yield Zotero.DB.executeTransaction(function* () { for each(var uri in uris) {
for each(var uri in uris) { // Skip URIs that don't begin with the default prefix,
// Skip URIs that don't begin with the default prefix, // since they don't correspond to local items
// since they don't correspond to local items if (uri.indexOf(prefix) == -1) {
if (uri.indexOf(prefix) == -1) { continue;
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);
}
} }
}.bind(this)); 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);
}
}
Zotero.debug("Purged relations in " + ((new Date) - t) + "ms"); Zotero.debug("Purged relations in " + ((new Date) - t) + "ms");
} }
}); });

View file

@ -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(); Zotero.DB.requireTransaction();
var notifierData = {}; var notifierData = {};
@ -228,7 +228,9 @@ Zotero.Search.prototype._eraseData = Zotero.Promise.coroutine(function* () {
var sql = "DELETE FROM savedSearches WHERE savedSearchID=?"; var sql = "DELETE FROM savedSearches WHERE savedSearchID=?";
yield Zotero.DB.queryAsync(sql, this.id); 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);
}
}); });

View file

@ -2052,14 +2052,21 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
* Clear entries that no longer exist from various tables * Clear entries that no longer exist from various tables
*/ */
this.purgeDataObjects = Zotero.Promise.coroutine(function* (skipStoragePurge) { this.purgeDataObjects = Zotero.Promise.coroutine(function* (skipStoragePurge) {
yield Zotero.Creators.purge(); yield Zotero.DB.executeTransaction(function* () {
yield Zotero.Tags.purge(); return Zotero.Creators.purge();
});
yield Zotero.DB.executeTransaction(function* () {
return Zotero.Tags.purge();
});
// TEMP: Disabled until we have async DB (and maybe SQLite FTS) // TEMP: Disabled until we have async DB (and maybe SQLite FTS)
//Zotero.Fulltext.purgeUnusedWords(); //Zotero.Fulltext.purgeUnusedWords();
yield Zotero.Items.purge(); yield Zotero.DB.executeTransaction(function* () {
yield Zotero.Items.purge();
});
// DEBUG: this might not need to be permanent // DEBUG: this might not need to be permanent
yield Zotero.Relations.purge(); yield Zotero.DB.executeTransaction(function* () {
yield Zotero.CharacterSets.purge(); yield Zotero.Relations.purge();
});
}); });