diff --git a/chrome/content/zotero/overlay.js b/chrome/content/zotero/overlay.js index a344531fad..aba4a48fb4 100644 --- a/chrome/content/zotero/overlay.js +++ b/chrome/content/zotero/overlay.js @@ -338,6 +338,11 @@ var ZoteroPane = new function() // Focus the quicksearch on pane open setTimeout("document.getElementById('zotero-tb-search').inputField.select();", 1); + var d = new Date(); + Zotero.purgeDataObjects(true); + var d2 = new Date(); + Zotero.debug("Purged data tables in " + (d2 - d) + "ms"); + if (Zotero.Prefs.get('sync.autoSync') && Zotero.Sync.Server.enabled) { setTimeout(function () { Zotero.Sync.Runner.sync(); diff --git a/chrome/content/zotero/xpcom/data/creator.js b/chrome/content/zotero/xpcom/data/creator.js index a7db6eeb86..d61a65566b 100644 --- a/chrome/content/zotero/xpcom/data/creator.js +++ b/chrome/content/zotero/xpcom/data/creator.js @@ -409,6 +409,8 @@ Zotero.Creator.prototype.erase = function () { } Zotero.DB.commitTransaction(); + + Zotero.Prefs.set('purge.creators', true); } diff --git a/chrome/content/zotero/xpcom/data/creators.js b/chrome/content/zotero/xpcom/data/creators.js index 0ac0f24f0d..79c5989566 100644 --- a/chrome/content/zotero/xpcom/data/creators.js +++ b/chrome/content/zotero/xpcom/data/creators.js @@ -197,6 +197,10 @@ Zotero.Creators = new function() { * and clear internal array entries */ function purge() { + if (!Zotero.Prefs.get('purge.creators')) { + return; + } + Zotero.debug("Purging creator tables"); // Purge unused creators @@ -230,6 +234,8 @@ Zotero.Creators = new function() { + "(SELECT creatorDataID FROM creators)"; Zotero.DB.query(sql); } + + Zotero.Prefs.set('purge.creators', false); } diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js index de023edec2..723de4bbf5 100644 --- a/chrome/content/zotero/xpcom/data/item.js +++ b/chrome/content/zotero/xpcom/data/item.js @@ -3358,7 +3358,12 @@ Zotero.Item.prototype.erase = function(deleteChildren) { Zotero.DB.query('DELETE FROM annotations WHERE itemID=?', this.id); Zotero.DB.query('DELETE FROM highlights WHERE itemID=?', this.id); Zotero.DB.query('DELETE FROM deletedItems WHERE itemID=?', this.id); - Zotero.DB.query('DELETE FROM itemCreators WHERE itemID=?', this.id); + var hasCreators = Zotero.DB.valueQuery( + "SELECT rowid FROM itemCreators WHERE itemID=? LIMIT 1", this.id + ); + if (hasCreators) { + Zotero.DB.query('DELETE FROM itemCreators WHERE itemID=?', this.id); + } Zotero.DB.query('DELETE FROM itemNotes WHERE itemID=?', this.id); Zotero.DB.query('DELETE FROM itemAttachments WHERE itemID=?', this.id); Zotero.DB.query('DELETE FROM itemSeeAlso WHERE itemID=?', this.id); @@ -3392,6 +3397,11 @@ Zotero.Item.prototype.erase = function(deleteChildren) { } Zotero.Notifier.trigger('delete', 'item', this.id, deletedItemNotifierData); + + Zotero.Prefs.set('purge.items', true); + if (hasCreators) { + Zotero.Prefs.set('purge.creators', true); + } } diff --git a/chrome/content/zotero/xpcom/data/items.js b/chrome/content/zotero/xpcom/data/items.js index 0c86af0226..03469db1d5 100644 --- a/chrome/content/zotero/xpcom/data/items.js +++ b/chrome/content/zotero/xpcom/data/items.js @@ -35,7 +35,6 @@ Zotero.Items = new function() { this.add = add; this.cacheFields = cacheFields; this.erase = erase; - this.purge = purge; this.getFirstCreatorSQL = getFirstCreatorSQL; this.getSortTitle = getSortTitle; @@ -386,7 +385,7 @@ Zotero.Items = new function() { function erase(ids, eraseChildren) { ids = Zotero.flattenArguments(ids); - Zotero.UnresponsiveScriptIndicator.disable(); + var usiDisabled = Zotero.UnresponsiveScriptIndicator.disable(); try { Zotero.DB.beginTransaction(); for each(var id in ids) { @@ -399,7 +398,6 @@ Zotero.Items = new function() { item.erase(eraseChildren); // calls unload() item = undefined; } - this.purge(); Zotero.DB.commitTransaction(); } catch (e) { @@ -407,31 +405,26 @@ Zotero.Items = new function() { throw (e); } finally { - Zotero.UnresponsiveScriptIndicator.enable(); + if (usiDisabled) { + Zotero.UnresponsiveScriptIndicator.enable(); + } } } - /* - * Clear entries from various tables that no longer exist - * - * This is called automatically by Items.erase() but must be called - * manually after Item.erase() + /** + * Purge unused data values */ - function purge() { - Zotero.Creators.purge(); - Zotero.Tags.purge(); - Zotero.Fulltext.purgeUnusedWords(); + this.purge = function () { + if (!Zotero.Prefs.get('purge.items')) { + return; + } - // Purge unused values var sql = "DELETE FROM itemDataValues WHERE valueID NOT IN " - + "(SELECT valueID FROM itemData)"; + + "(SELECT valueID FROM itemData)"; Zotero.DB.query(sql); - var ZU = new Zotero.Utilities; - if (Zotero.Sync.Storage.active && ZU.probability(10)) { - Zotero.Sync.Storage.purgeDeletedStorageFiles(); - } + Zotero.Prefs.set('purge.items', false) } diff --git a/chrome/content/zotero/xpcom/data/tag.js b/chrome/content/zotero/xpcom/data/tag.js index fc63d0e1c3..ba415d1e17 100644 --- a/chrome/content/zotero/xpcom/data/tag.js +++ b/chrome/content/zotero/xpcom/data/tag.js @@ -531,6 +531,8 @@ Zotero.Tag.prototype.erase = function () { Zotero.Notifier.trigger('delete', 'tag', this.id, deletedTagNotifierData); Zotero.DB.commitTransaction(); + + Zotero.Prefs.set('purge.tags', true); return; } diff --git a/chrome/content/zotero/xpcom/data/tags.js b/chrome/content/zotero/xpcom/data/tags.js index 3a3476ff68..04d25ec75a 100644 --- a/chrome/content/zotero/xpcom/data/tags.js +++ b/chrome/content/zotero/xpcom/data/tags.js @@ -342,13 +342,17 @@ Zotero.Tags = new function() { * Returns removed tagIDs on success */ function purge() { + if (!Zotero.Prefs.get('purge.tags')) { + return; + } + Zotero.UnresponsiveScriptIndicator.disable(); try { Zotero.DB.beginTransaction(); var sql = "CREATE TEMPORARY TABLE tagDelete AS " + "SELECT tagID FROM tags WHERE tagID " - + "NOT IN (SELECT tagID FROM itemTags);"; + + "NOT IN (SELECT tagID FROM itemTags)"; Zotero.DB.query(sql); sql = "CREATE INDEX tagDelete_tagID ON tagDelete(tagID)"; @@ -361,6 +365,7 @@ Zotero.Tags = new function() { sql = "DROP TABLE tagDelete"; Zotero.DB.query(sql); Zotero.DB.commitTransaction(); + Zotero.Prefs.set('purge.tags', false); return; } @@ -393,6 +398,8 @@ Zotero.Tags = new function() { finally { Zotero.UnresponsiveScriptIndicator.enable(); } + + Zotero.Prefs.set('purge.tags', false); } diff --git a/chrome/content/zotero/xpcom/fulltext.js b/chrome/content/zotero/xpcom/fulltext.js index 4825a07611..a01a8b62d3 100644 --- a/chrome/content/zotero/xpcom/fulltext.js +++ b/chrome/content/zotero/xpcom/fulltext.js @@ -634,10 +634,18 @@ Zotero.Fulltext = new function(){ function clearItemWords(itemID){ Zotero.DB.beginTransaction(); - Zotero.DB.query("DELETE FROM fulltextItems WHERE itemID=" + itemID); - Zotero.DB.query("DELETE FROM fulltextItemWords WHERE itemID=" + itemID); + var sql = "SELECT rowid FROM fulltextItems WHERE itemID=? LIMIT 1"; + var indexed = Zotero.DB.valueQuery(sql, itemID); + if (indexed) { + Zotero.DB.query("DELETE FROM fulltextItems WHERE itemID=?", itemID); + Zotero.DB.query("DELETE FROM fulltextItemWords WHERE itemID=?", itemID); + } Zotero.DB.commitTransaction(); + if (indexed) { + Zotero.Prefs.set('purge.fulltext', true); + } + // Delete fulltext cache file if there is one this.clearCacheFile(itemID); } @@ -933,10 +941,16 @@ Zotero.Fulltext = new function(){ */ - function purgeUnusedWords(){ + function purgeUnusedWords() { + if (!Zotero.Prefs.get('purge.fulltext')) { + return; + } + var sql = "DELETE FROM fulltextWords WHERE wordID NOT IN " - + "(SELECT wordID FROM fulltextItemWords)"; + + "(SELECT wordID FROM fulltextItemWords)"; Zotero.DB.query(sql); + + Zotero.Prefs.set('purge.fulltext', false) } diff --git a/chrome/content/zotero/xpcom/itemTreeView.js b/chrome/content/zotero/xpcom/itemTreeView.js index 651029a6dc..a9690dc8f7 100644 --- a/chrome/content/zotero/xpcom/itemTreeView.js +++ b/chrome/content/zotero/xpcom/itemTreeView.js @@ -155,6 +155,9 @@ Zotero.ItemTreeView.prototype.setTree = function(treebox) Zotero.ItemTreeView.prototype.refresh = function() { Zotero.debug('Refreshing items list'); + + var usiDisabled = Zotero.UnresponsiveScriptIndicator.disable(); + this._searchMode = this._itemGroup.isSearchMode(); var oldRows = this.rowCount; @@ -228,6 +231,10 @@ Zotero.ItemTreeView.prototype.refresh = function() if (diff != 0) { this._treebox.rowCountChanged(0, diff); } + + if (usiDisabled) { + Zotero.UnresponsiveScriptIndicator.enable(); + } } diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index 934e851c23..a3b6b256fa 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -970,6 +970,22 @@ var Zotero = new function(){ } + /* + * Clear entries that no longer exist from various tables + */ + this.purgeDataObjects = function () { + Zotero.Creators.purge(); + Zotero.Tags.purge(); + Zotero.Fulltext.purgeUnusedWords(); + Zotero.Items.purge(); + + var ZU = new Zotero.Utilities; + if (Zotero.Sync.Storage.active && ZU.probability(10)) { + Zotero.Sync.Storage.purgeDeletedStorageFiles(); + } + } + + function reloadDataObjects() { Zotero.Tags.reloadAll(); Zotero.Collections.reloadAll(); @@ -2103,7 +2119,9 @@ Zotero.UnresponsiveScriptIndicator = new function() { **/ function disable() { // don't do anything if already disabled - if(_isDisabled) return; + if (_isDisabled) { + return false; + } var prefService = Components.classes["@mozilla.org/preferences-service;1"]. getService(Components.interfaces.nsIPrefBranch); @@ -2111,6 +2129,7 @@ Zotero.UnresponsiveScriptIndicator = new function() { prefService.setIntPref("dom.max_chrome_script_run_time", 0); _isDisabled = true; + return true; } /** diff --git a/defaults/preferences/zotero.js b/defaults/preferences/zotero.js index 94ae193588..93e8869a84 100644 --- a/defaults/preferences/zotero.js +++ b/defaults/preferences/zotero.js @@ -102,4 +102,10 @@ pref("extensions.zotero.sync.storage.deleteDelayDays", 30); // Proxy pref("extensions.zotero.proxies.autoRecognize", true); -pref("extensions.zotero.proxies.transparent", true); \ No newline at end of file +pref("extensions.zotero.proxies.transparent", true); + +// Data layer purging +pref("extensions.zotero.purge.creators", false); +pref("extensions.zotero.purge.fulltext", false); +pref("extensions.zotero.purge.items", false); +pref("extensions.zotero.purge.tags", false); \ No newline at end of file