Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@sugarlabs.org>2012-03-13 18:06:16 (GMT)
committer Aleksey Lim <alsroot@sugarlabs.org>2012-03-13 18:06:16 (GMT)
commit6156ff9dab937fcbba1a22e9579e93c785d10738 (patch)
tree9596efbc8af2fec5f049d4d17d071390dea53f7a
parentd05e1afd30a511778238789ff79605c671210f2f (diff)
Reproduce index behaviour in cache for searching by composite properties
-rw-r--r--active_document/index_proxy.py59
-rwxr-xr-xtests/units/index.py19
-rwxr-xr-xtests/units/index_proxy.py43
3 files changed, 107 insertions, 14 deletions
diff --git a/active_document/index_proxy.py b/active_document/index_proxy.py
index 40e98e4..cd99f2d 100644
--- a/active_document/index_proxy.py
+++ b/active_document/index_proxy.py
@@ -131,8 +131,17 @@ class IndexProxy(IndexReader):
terms = set()
for prop_name, value in request.items():
- if _is_term(self.metadata[prop_name]):
- terms.add((prop_name, value))
+ prop = self.metadata[prop_name]
+ if not _is_term(prop):
+ continue
+ try:
+ value = prop.convert(value)
+ except ValueError, error:
+ _logger.debug('Wrong request property value %r for "%s" ' \
+ 'property, thus the whole request is empty: %s',
+ value, prop_name, error)
+ return None, None, None
+ terms.add(_TermValue(prop, value))
for cache in self._cache.values():
if cache.new:
@@ -192,15 +201,17 @@ class _CachedDocument(object):
self.new = new
self.terms = set()
self.orig_terms = set()
- self._term_names = []
+ self._term_props = []
if not new:
record = Storage(metadata).get(guid)
for prop_name, prop in metadata.items():
- if _is_term(prop):
- self._term_names.append(prop_name)
- if not new:
- self.orig_terms.add((prop_name, record.get(prop_name)))
+ if not _is_term(prop):
+ continue
+ self._term_props.append(prop)
+ if not new:
+ self.orig_terms.add(_TermValue(prop, record.get(prop_name)))
+
self._update_terms()
def __sort__(self, other):
@@ -212,10 +223,36 @@ class _CachedDocument(object):
def _update_terms(self):
self.terms.clear()
- orig_terms = dict(self.orig_terms)
- for prop_name in self._term_names:
- term = self.properties.get(prop_name, orig_terms.get(prop_name))
- self.terms.add((prop_name, term))
+ orig_terms = {}
+ for i in self.orig_terms:
+ orig_terms[i.prop] = i.value
+ for prop in self._term_props:
+ term = self.properties.get(prop.name, orig_terms.get(prop))
+ self.terms.add(_TermValue(prop, term))
+
+
+class _TermValue:
+
+ def __init__(self, prop, value):
+ self.prop = prop
+ self.value = value
+
+ def __cmp__(self, other):
+ result = cmp(self.prop.name, other.prop.name)
+ if result:
+ return result
+ if not self.prop.composite:
+ return cmp(self.value, other.value)
+ self_value = set(self.value)
+ other_value = set(other.value)
+ if self_value.issubset(other_value) or \
+ other_value.issubset(self_value):
+ return 0
+ else:
+ return cmp(self.value, other.value)
+
+ def __hash__(self):
+ return hash(self.prop.name)
def _is_term(prop):
diff --git a/tests/units/index.py b/tests/units/index.py
index 0749b41..6d14701 100755
--- a/tests/units/index.py
+++ b/tests/units/index.py
@@ -508,6 +508,25 @@ class IndexTest(tests.Test):
([{'guid': '1'}], 1),
db._find(query='%s:=test' % term, reply=['guid']))
+ def test_find_WithListProps(self):
+ db = Index({'prop': ActiveProperty('prop', None, 'A', full_text=True, typecast=[])})
+
+ db.store('1', {'prop': ('a', )}, True)
+ db.store('2', {'prop': ('a', 'aa')}, True)
+ db.store('3', {'prop': ('aa', 'aaa')}, True)
+
+ self.assertEqual(
+ ([{'guid': '1'}, {'guid': '2'}], 2),
+ db._find(request={'prop': 'a'}, reply=['prop']))
+
+ self.assertEqual(
+ ([{'guid': '2'}, {'guid': '3'}], 2),
+ db._find(request={'prop': 'aa'}))
+
+ self.assertEqual(
+ ([{'guid': '3'}], 1),
+ db._find(request={'prop': 'aaa'}))
+
class Index(index.IndexWriter):
diff --git a/tests/units/index_proxy.py b/tests/units/index_proxy.py
index cc1ed03..17175cc 100755
--- a/tests/units/index_proxy.py
+++ b/tests/units/index_proxy.py
@@ -21,6 +21,9 @@ class IndexProxyTest(tests.Test):
def setUp(self):
tests.Test.setUp(self)
+ self.Document = None
+
+ def setup_document(self):
class Document(document.Document):
@@ -69,12 +72,14 @@ class IndexProxyTest(tests.Test):
self.wait_job = gevent.spawn(waiter)
def tearDown(self):
- assert not self.committed
- self.wait_job.kill()
+ if self.Document is not None:
+ assert not self.committed
+ self.wait_job.kill()
+ self.Document.close()
tests.Test.tearDown(self)
- self.Document.close()
def test_Create(self):
+ self.setup_document()
proxy = IndexProxy(self.metadata)
self.assertEqual(
@@ -138,6 +143,7 @@ class IndexProxyTest(tests.Test):
proxy._find()[0])
def test_Update(self):
+ self.setup_document()
proxy = IndexProxy(self.metadata)
proxy._store(self.doc_1, {'term': '1_term_2'})
@@ -151,6 +157,7 @@ class IndexProxyTest(tests.Test):
proxy._find()[0])
def test_Update_Adds(self):
+ self.setup_document()
proxy = IndexProxy(self.metadata)
self.assertEqual(
@@ -181,6 +188,7 @@ class IndexProxyTest(tests.Test):
proxy._find()[0])
def test_Update_Deletes(self):
+ self.setup_document()
proxy = IndexProxy(self.metadata)
self.assertEqual(
@@ -204,6 +212,7 @@ class IndexProxyTest(tests.Test):
proxy._find(request={'common': 'common'}))
def test_Get(self):
+ self.setup_document()
doc = self.Document(term='3', not_term='3', common='3')
doc.post()
@@ -213,6 +222,7 @@ class IndexProxyTest(tests.Test):
self.assertEqual('3', doc_2.common)
def test_Document_merge(self):
+ self.setup_document()
ts = int(time.time())
self.Document.merge(self.doc_1.guid, {
@@ -263,6 +273,33 @@ class IndexProxyTest(tests.Test):
del self.committed[:]
+ def test_FindByListProps(self):
+
+ class Document2(document.Document):
+
+ @active_property(prefix='A', typecast=[])
+ def prop(self, value):
+ return value
+
+ index_queue.close()
+ Document2.init(IndexProxy)
+ index_queue.init([Document2])
+ proxy = IndexProxy(Document2.metadata)
+
+ proxy.store('1', {'ctime': 0, 'mtime': 0, 'seqno': 0, 'prop': ('a',)}, True)
+ proxy.store('2', {'ctime': 0, 'mtime': 0, 'seqno': 0, 'prop': ('a', 'aa')}, True)
+ proxy.store('3', {'ctime': 0, 'mtime': 0, 'seqno': 0, 'prop': ('aa', 'aaa')}, True)
+
+ self.assertEqual(
+ ['1', '2'],
+ [i['guid'] for i in proxy._find(request={'prop': 'a'})[0]])
+ self.assertEqual(
+ ['2', '3'],
+ [i['guid'] for i in proxy._find(request={'prop': 'aa'})[0]])
+ self.assertEqual(
+ ['3'],
+ [i['guid'] for i in proxy._find(request={'prop': 'aaa'})[0]])
+
class IndexProxy(index_proxy.IndexProxy):