From 71b0cfeef0c0edc6ce54a876fc356b4d3403735d Mon Sep 17 00:00:00 2001 From: Benjamin Saller Date: Fri, 20 Jul 2007 21:41:11 +0000 Subject: limited support for dateranges, this will have to expand to include all the types --- diff --git a/src/olpc/datastore/utils.py b/src/olpc/datastore/utils.py index 711007e..0505463 100644 --- a/src/olpc/datastore/utils.py +++ b/src/olpc/datastore/utils.py @@ -110,7 +110,8 @@ def sanitize_dbus(method): return method(self, *n, **kw) return decorator -def timeparse(t, format): +DATEFORMAT = "%Y-%m-%dT%H:%M:%S" +def timeparse(t, format=DATEFORMAT): """Parse a time string that might contain fractions of a second. Fractional seconds are supported using a fragile, miserable hack. @@ -151,3 +152,11 @@ def timeparse(t, format): raise +def parse_timestamp_or_float(value): + result = None + try: + result = timeparse(value) + result = str(time.mktime(result.timetuple())) + except: + result = str(float(value)) + return result diff --git a/src/olpc/datastore/xapianindex.py b/src/olpc/datastore/xapianindex.py index 0be462d..a6f8994 100644 --- a/src/olpc/datastore/xapianindex.py +++ b/src/olpc/datastore/xapianindex.py @@ -25,7 +25,7 @@ import secore from olpc.datastore import model from olpc.datastore.converter import converter -from olpc.datastore.utils import create_uid +from olpc.datastore.utils import create_uid, parse_timestamp_or_float # Setup Logger @@ -349,7 +349,20 @@ class IndexManager(object): else: # each term becomes part of the query join for k, v in query.iteritems(): - queries.append(ri.query_field(k, v)) + if isinstance(v, dict): + # it might be a range scan + # this needs to be factored out + # and/or we need client side lib that helps + # issue queries because there are type + # conversion issues here + start = v.pop('start', 0) + end = v.pop('end', sys.maxint) + start = parse_timestamp_or_float(start) + end = parse_timestamp_or_float(end) + queries.append(ri.query_range(k, start, end)) + else: + queries.append(ri.query_field(k, v)) + q = ri.query_composite(ri.OP_AND, queries) else: q = self.parse_query(query) diff --git a/tests/dateranges.txt b/tests/dateranges.txt new file mode 100644 index 0000000..886e7d2 --- /dev/null +++ b/tests/dateranges.txt @@ -0,0 +1,42 @@ +Test that date +First clean up from any other tests. +>>> import os, datetime +>>> assert os.system('rm -rf /tmp/test_ds/') == 0 + +>>> from olpc.datastore import DataStore +>>> from olpc.datastore import backingstore, model +>>> ds = DataStore() +>>> ds.registerBackend(backingstore.FileBackingStore) + +>>> assert ds.mount("/tmp/test_ds") + +>>> t1 = datetime.datetime(1995, 1, 1) +>>> t2 = datetime.datetime(2000, 1, 1) +>>> t3 = datetime.datetime(2005, 1, 1) + +>>> a = ds.create(dict(title="Content A", author="Bob", ctime=t1.isoformat()), '') +>>> b = ds.create(dict(title="Content B", author="Alice", ctime=t2.isoformat()), '') +>>> c = ds.create(dict(title="Content V", author="Clare", ctime=t3.isoformat()), '') + +>>> ds.complete_indexing() + + +Scan for ranges + +>>> result, count = ds.find({'ctime' : {'start' : t1.isoformat(), 'end' : t3.isoformat() }}) +>>> assert count == 3 + + +>>> result, count = ds.find({'ctime' : {'start' : t1.isoformat(), 'end' : t2.isoformat() }}) +>>> assert count == 2 + +>>> result, count = ds.find({'ctime' : {'start' : t2.isoformat(), 'end' : t3.isoformat() }}) +>>> assert count == 2 + +>>> result, count = ds.find({'ctime' : {'start' : t1.isoformat(), 'end' : t1.isoformat() }}) +>>> assert count == 1 + + +>>> ds.stop() +>>> del ds +>>> assert os.system('rm -rf /tmp/test_ds/') == 0 diff --git a/tests/runalltests.py b/tests/runalltests.py index 896972f..52ec486 100644 --- a/tests/runalltests.py +++ b/tests/runalltests.py @@ -27,6 +27,7 @@ doctests = [ resource_filename(__name__, "milestone_2.txt"), resource_filename(__name__, "mountpoints.txt"), resource_filename(__name__, "properties.txt"), + resource_filename(__name__, "dateranges.txt"), ] -- cgit v0.9.1