commit c917d9e30e186718387850aa33d6d964c965ec6c
parent 985a5db0daf6fb7e3c30350c2bc11aebaf92b744
Author: Dan Stillman <dstillman@zotero.org>
Date: Tue, 9 Sep 2014 01:32:43 -0400
Use only keys for collections and saved searches in search conditions
Previously, 'collection' and 'savedSearch' conditions used
"[libraryID]_[key]" format. Now, the condition should contain only a
key, and the libraryID will be drawn from either the search itself or a
libraryID search condition. Old-style conditions are still parsed if
provided.
Diffstat:
4 files changed, 90 insertions(+), 78 deletions(-)
diff --git a/chrome/content/zotero/bindings/zoterosearch.xml b/chrome/content/zotero/bindings/zoterosearch.xml
@@ -451,7 +451,7 @@
}
indent += '- ';
}
- rows.push([indent + cols[i].name, 'C' + Zotero.Collections.getLibraryKeyHash(cols[i])]);
+ rows.push([indent + cols[i].name, 'C' + cols[i].key]);
}
this.createValueMenu(rows);
break;
@@ -462,7 +462,7 @@
var searches = Zotero.Searches.getAll(libraryID);
for (var i in searches) {
if (searches[i].id != this.parent.search.id) {
- rows.push([searches[i].name, 'S' + Zotero.Searches.getLibraryKeyHash(searches[i])]);
+ rows.push([searches[i].name, 'S' + searches[i].key]);
}
}
this.createValueMenu(rows);
diff --git a/chrome/content/zotero/xpcom/collectionTreeView.js b/chrome/content/zotero/xpcom/collectionTreeView.js
@@ -2216,9 +2216,9 @@ Zotero.CollectionTreeRow.prototype.getSearchObject = Zotero.Promise.coroutine(fu
}
else {
var s = new Zotero.Search();
+ yield s.addCondition('libraryID', 'is', this.ref.libraryID);
// Library root
if (this.isLibrary(true)) {
- yield s.addCondition('libraryID', 'is', this.ref.libraryID);
yield s.addCondition('noChildren', 'true');
includeScopeChildren = true;
}
@@ -2231,7 +2231,6 @@ Zotero.CollectionTreeRow.prototype.getSearchObject = Zotero.Promise.coroutine(fu
includeScopeChildren = true;
}
else if (this.isTrash()) {
- yield s.addCondition('libraryID', 'is', this.ref.libraryID);
yield s.addCondition('deleted', 'true');
}
else {
diff --git a/chrome/content/zotero/xpcom/data/items.js b/chrome/content/zotero/xpcom/data/items.js
@@ -197,7 +197,7 @@ Zotero.Items = new function() {
var s = new Zotero.Search;
yield s.addCondition('libraryID', 'is', params.libraryID);
if (params.scopeObject == 'collections') {
- yield s.addCondition('collection', 'is', params.libraryID + '/' + params.scopeObjectKey);
+ yield s.addCondition('collection', 'is', params.scopeObjectKey);
}
yield s.addCondition('title', 'contains', 'test');
var ids = yield s.search();
diff --git a/chrome/content/zotero/xpcom/search.js b/chrome/content/zotero/xpcom/search.js
@@ -389,9 +389,7 @@ Zotero.Search.prototype.addCondition = Zotero.Promise.coroutine(function* (condi
Components.utils.reportError(msg);
return;
}
- var lkh = Zotero.Collections.getLibraryKeyHash(c);
- // TEMP: Bluebird return yield
- return yield this.addCondition('collection', operator, lkh, required);
+ return this.addCondition('collection', operator, c.key, required);
}
// Shortcut to add a saved search
else if (condition == 'savedSearchID') {
@@ -402,9 +400,7 @@ Zotero.Search.prototype.addCondition = Zotero.Promise.coroutine(function* (condi
Components.utils.reportError(msg);
return;
}
- var lkh = Zotero.Searches.getLibraryKeyHash(s);
- // TEMP: Bluebird return yield
- return yield this.addCondition('savedSearch', operator, lkh, required);
+ return this.addCondition('savedSearch', operator, s.key, required);
}
var searchConditionID = ++this._maxSearchConditionID;
@@ -836,7 +832,7 @@ Zotero.Search.prototype.search = Zotero.Promise.coroutine(function* (asTempTable
}
finally {
if (tmpTable && !asTempTable) {
- yield Zotero.DB.queryAsync("DROP TABLE " + tmpTable);
+ yield Zotero.DB.queryAsync("DROP TABLE IF EXISTS " + tmpTable);
}
}
@@ -1185,87 +1181,104 @@ Zotero.Search.prototype._buildQuery = Zotero.Promise.coroutine(function* () {
break;
case 'collection':
- var col;
- if (condition.value) {
- var lkh = Zotero.Collections.parseLibraryKeyHash(condition.value);
- if (lkh) {
- col = yield Zotero.Collections.getByLibraryAndKeyAsync(lkh.libraryID, lkh.key);
- }
+ case 'savedSearch':
+ let obj;
+ let objLibraryID;
+ let objKey = condition.value;
+ let objectType = condition.name == 'collection' ? 'collection' : 'search';
+ let objectTypeClass = Zotero.DataObjectUtilities.getClassForObjectType(objectType);
+
+ // Old-style library-key hash
+ if (objKey.contains('_')) {
+ [objLibraryID, objKey] = objKey.split('_');
}
- if (!col) {
- var msg = "Collection " + condition.value + " specified in saved search doesn't exist";
- Zotero.debug(msg, 2);
- Zotero.log(msg, 'warning', 'chrome://zotero/content/xpcom/search.js');
- col = {
- id: 0
- };
+ // libraryID assigned on search
+ else if (this.libraryID !== null) {
+ objLibraryID = this.libraryID;
}
- var q = ['?'];
- var p = [col.id];
-
- // Search descendent collections if recursive search
- if (recursive){
- var descendents = col.getDescendents(false, 'collection');
- if (descendents){
- for (var k in descendents){
- q.push('?');
- p.push({int:descendents[k]['id']});
+ // If search doesn't have a libraryID, check all possible libraries
+ // for the collection/search
+ if (objLibraryID === undefined) {
+ let foundLibraryID = false;
+ for each (let c in this._conditions) {
+ if (c.condition == 'libraryID' && c.operator == 'is') {
+ foundLibraryID = true;
+ obj = yield objectTypeClass.getByLibraryAndKeyAsync(
+ c.value, objKey
+ );
+ if (obj) {
+ break;
+ }
}
}
- }
-
- condSQL += "collectionID IN (" + q.join() + ")";
- condSQLParams = condSQLParams.concat(p);
-
- skipOperators = true;
- break;
-
- case 'savedSearch':
- condSQL += "itemID ";
- if (condition['operator']=='isNot'){
- condSQL += "NOT ";
- }
- condSQL += "IN (";
-
- var search;
- if (condition.value) {
- var lkh = Zotero.Searches.parseLibraryKeyHash(condition.value);
- if (lkh) {
- search = Zotero.Searches.getByLibraryAndKey(lkh.libraryID, lkh.key);
+ if (!foundLibraryID) {
+ Zotero.debug("WARNING: libraryID condition not found for "
+ + objectType + " in search", 2);
}
}
- if (!search) {
- var msg = "Search " + condition.value + " specified in saved search doesn't exist";
+ else {
+ col = yield objectTypeClass.getByLibraryAndKeyAsync(
+ objLibraryID, objKey
+ );
+ }
+ if (!obj) {
+ var msg = objectType.charAt(0).toUpperCase() + objectType.substr(1)
+ + " " + objKey + " specified in search not found";
Zotero.debug(msg, 2);
Zotero.log(msg, 'warning', 'chrome://zotero/content/xpcom/search.js');
- continue;
+ if (objectType == 'search') {
+ continue;
+ }
+ obj = {
+ id: 0
+ };
}
- // Check if there are any post-search filters
- var hasFilter = search.hasPostSearchFilter();
-
- // This is an ugly and inefficient way of doing a
- // subsearch, but it's necessary if there are any
- // post-search filters (e.g. fulltext scanning) in the
- // subsearch
- //
- // DEBUG: it's possible there's a query length limit here
- // or that this slows things down with large libraries
- // -- should probably use a temporary table instead
- if (hasFilter){
- let subids = yield search.search();
- condSQL += subids.join();
+ if (objectType == 'collection') {
+ var q = ['?'];
+ var p = [obj.id];
+
+ // Search descendent collections if recursive search
+ if (recursive){
+ var descendents = col.getDescendents(false, 'collection');
+ if (descendents){
+ for (var k in descendents){
+ q.push('?');
+ p.push({int:descendents[k]['id']});
+ }
+ }
+ }
+
+ condSQL += "collectionID IN (" + q.join() + ")";
+ condSQLParams = condSQLParams.concat(p);
}
- // Otherwise just put the SQL in a subquery
else {
- condSQL += yield search.getSQL();
- let subpar = yield search.getSQLParams();
- for (let k in subpar){
- condSQLParams.push(subpar[k]);
+ // Check if there are any post-search filters
+ var hasFilter = search.hasPostSearchFilter();
+
+ // This is an ugly and inefficient way of doing a
+ // subsearch, but it's necessary if there are any
+ // post-search filters (e.g. fulltext scanning) in the
+ // subsearch
+ //
+ // DEBUG: it's possible there's a query length limit here
+ // or that this slows things down with large libraries
+ // -- should probably use a temporary table instead
+ if (hasFilter){
+ let subids = yield search.search();
+ condSQL += subids.join();
+ }
+ // Otherwise just put the SQL in a subquery
+ else {
+ condSQL += yield search.getSQL();
+ let subpar = yield search.getSQLParams();
+ for (let k in subpar){
+ condSQLParams.push(subpar[k]);
+ }
}
+ condSQL += ")";
}
- condSQL += ")";
skipOperators = true;
break;