Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Silbe <sascha@silbe.org>2009-07-19 11:22:54 (GMT)
committer Sascha Silbe <sascha@silbe.org>2009-07-19 11:22:54 (GMT)
commitdfda7fe0ddce178b8a7da1c7414a721fad445f3c (patch)
tree476375d98c00d811631aaf7a6c075802436b8051
parenta5f12b6805c7554871e566b702a1b995340f664b (diff)
add support for list- and range-queries
-rw-r--r--src/carquinyol/indexstore.py77
1 files changed, 54 insertions, 23 deletions
diff --git a/src/carquinyol/indexstore.py b/src/carquinyol/indexstore.py
index 2aa90c3..a612950 100644
--- a/src/carquinyol/indexstore.py
+++ b/src/carquinyol/indexstore.py
@@ -21,11 +21,13 @@ import gobject
import xapian
from xapian import WritableDatabase, Document, Enquire, Query, QueryParser
+import sugar.datastore
+
from carquinyol import layoutmanager
from carquinyol.layoutmanager import MAX_QUERY_LIMIT
_VALUE_TID = 0
-_VALUE_TIMESTAMP = 1
+_VALUE_CTIME = 1
_VALUE_VID = 2
_PREFIX_TID = 'Q'
@@ -41,7 +43,7 @@ _FLUSH_THRESHOLD = 20
# Force a flush after _n_ seconds since the last change to the db
_FLUSH_TIMEOUT = 60
-_PROPERTIES_NOT_TO_INDEX = ['timestamp', 'activity_id', 'keep', 'preview']
+_PROPERTIES_NOT_TO_INDEX = ['ctime', 'activity_id', 'keep', 'preview']
_MAX_RESULTS = int(2 ** 31 - 1)
@@ -89,7 +91,7 @@ class IndexStore(object):
document.add_value(_VALUE_TID, tree_id)
document.add_value(_VALUE_VID, version_id)
- document.add_value(_VALUE_TIMESTAMP, str(properties['timestamp']))
+ document.add_value(_VALUE_CTIME, str(properties['ctime']))
term_generator = xapian.TermGenerator()
@@ -139,7 +141,7 @@ class IndexStore(object):
# This will assure that the results count is exact.
check_at_least = offset + limit + 1
- enquire.set_sort_by_value(_VALUE_TIMESTAMP, True)
+ enquire.set_sort_by_value(_VALUE_CTIME, True)
if not all_versions :
# only select newest entry (sort order) for each tree_id
@@ -161,6 +163,43 @@ class IndexStore(object):
'activity_id': _PREFIX_ACTIVITY_ID,
'keep': _PREFIX_KEEP,
}
+ _queryValueMap = {
+ 'ctime': _VALUE_CTIME,
+ }
+ def _parse_query_term(self, m_name, prefix, m_value) :
+ if isinstance(m_value, list) :
+ # list -> multiple terms joined by OR
+ return Query(Query.OP_OR,
+ [self._parse_query_term(m_name, prefix, word) for word in m_value])
+
+ else :
+ # simple query on regular term
+ return Query(prefix+str(m_value))
+
+ def _parse_query_value(self, m_name, value_no, m_value) :
+ if isinstance(m_value, list) :
+ # list -> multiple values joined by OR
+ return Query(Query.OP_OR,
+ [self._parse_query_value(m_name, value_no, word) for word in m_value])
+
+ elif isinstance(m_value, tuple) :
+ # 2-tuple -> range query
+ if m_name not in self._valueQueryMap :
+ raise NotImplementedError("range queries for %r currently not supported")
+
+ if len(m_value) != 2 :
+ raise sugar.datastore.InvalidArgumentError("Only tuples of size 2 have a defined meaning. Did you mean to pass a list instead?")
+
+ start, end = m_value
+ return Query(Query.OP_VALUE_RANGE,
+ self._queryValueMap[m_name], str(start), str(end))
+
+ else :
+ # simple query on value-stored metadata
+ return Query(Query.OP_VALUE_RANGE,
+ self._queryValueMap[m_name], str(m_value), str(m_value))
+
+
def _parse_query(self, query_dict, query_str):
logging.debug('_parse_query %r' % query_dict)
queries = []
@@ -184,32 +223,24 @@ class IndexStore(object):
queries.append(query)
- # metadata -> term for simple datatypes (string, bool)
- for (m_name, term_prefix) in self._queryTermMap.items() :
- m_value = query_dict.pop(m_name, None)
- if m_value is not None:
- queries.append(Query(term_prefix+str(m_value)))
-
- timestamp = query_dict.pop('timestamp', None)
- if timestamp is not None:
- start = str(timestamp.pop('start', 0))
- end = str(timestamp.pop('end', _MAX_RESULTS))
- query = Query(Query.OP_VALUE_RANGE, _VALUE_TIMESTAMP, start, end)
- queries.append(query)
+ # construct queries for term-stored metadata
+ queries += [
+ self._parse_query_term(m_name, prefix, query_dict.pop(m_name))
+ for (m_name, prefix) in self._queryTermMap.items()
+ if m_name in query_dict]
- mime_type = query_dict.pop('mime_type', None)
- if mime_type is not None:
- mime_queries = []
- for mime_type in mime_type:
- mime_queries.append(Query(_PREFIX_MIME_TYPE + mime_type))
- queries.append(Query(Query.OP_OR, mime_queries))
+ # construct queries for value-stored metadata
+ queries += [
+ self._parse_query_value(m_name, value_no, query_dict.pop(m_name))
+ for (m_name, value_no) in self._queryValueMap.items()
+ if m_name in query_dict]
if not queries:
queries.append(Query(''))
if query_dict:
logging.warning('Unknown term(s): %r' % query_dict)
-
+
return Query(Query.OP_AND, queries)
def delete(self, tree_id, version_id):