Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@sugarlabs.org>2013-08-01 18:42:36 (GMT)
committer Aleksey Lim <alsroot@sugarlabs.org>2013-08-01 18:42:36 (GMT)
commitc5fb6a110e1fdf99b192e7029f29d73157c21d22 (patch)
treed153001a6f98e32548a74211142746c07db97519
parentedbccdb9861c291f6b26574ff3d54aec2733be79 (diff)
Get rid of redundant "public" lauer
All objects without "deleted" layers are public.
-rw-r--r--sugar_network/db/directory.py68
-rw-r--r--sugar_network/db/index.py116
-rw-r--r--sugar_network/db/resource.py2
-rw-r--r--sugar_network/node/routes.py21
-rw-r--r--sugar_network/node/slave.py7
-rw-r--r--sugar_network/toolkit/router.py11
-rwxr-xr-xtests/units/db/index.py60
-rwxr-xr-xtests/units/db/resource.py58
-rwxr-xr-xtests/units/db/routes.py28
-rwxr-xr-xtests/units/node/node.py16
-rwxr-xr-xtests/units/node/sync_offline.py6
-rwxr-xr-xtests/units/node/sync_online.py16
-rwxr-xr-xtests/units/node/volume.py22
13 files changed, 182 insertions, 249 deletions
diff --git a/sugar_network/db/directory.py b/sugar_network/db/directory.py
index 08f1c35..b8d9176 100644
--- a/sugar_network/db/directory.py
+++ b/sugar_network/db/directory.py
@@ -152,42 +152,8 @@ class Directory(object):
guid, self.metadata.name)
return self.document_class(guid, record, cached_props)
- def find(self, *args, **kwargs):
- """Search documents.
-
- The result will be an array of dictionaries with found documents'
- properties.
-
- :param offset:
- the resulting list should start with this offset;
- 0 by default
- :param limit:
- the resulting list will be at least `limit` size;
- the `--find-limit` will be used by default
- :param query:
- a string in Xapian serach format, empty to avoid text search
- :param reply:
- an array of property names to use only in the resulting list;
- only GUID property will be used by default
- :param order_by:
- property name to sort resulting list; might be prefixed with ``+``
- (or without any prefixes) for ascending order, and ``-`` for
- descending order
- :param group_by:
- property name to group resulting list by; no groupping by default
- :param kwargs:
- a dictionary with property values to restrict the search
- :returns:
- a tuple of (`documents`, `total_count`); where the `total_count` is
- the total number of documents conforming the search parameters,
- i.e., not only documents that are included to the resulting list
-
- """
- # XXX Hardcode SN layers switch; Remove in 0.9
- if kwargs.get('layer') in ('peruvian-pilot', ['peruvian-pilot']):
- kwargs['layer'] = 'pilot'
-
- mset = self._index.find(_Query(*args, **kwargs))
+ def find(self, **kwargs):
+ mset = self._index.find(**kwargs)
def iterate():
for hit in mset:
@@ -403,33 +369,3 @@ class _SessionSeqno(object):
def commit(self):
pass
-
-
-class _Query(object):
-
- def __init__(self, offset=None, limit=None, query='', reply=None,
- order_by=None, no_cache=False, group_by=None, **kwargs):
- self.query = query
- self.no_cache = no_cache
- self.group_by = group_by
-
- if offset is None:
- offset = 0
- self.offset = offset
-
- self.limit = limit or 16
-
- if reply is None:
- reply = ['guid']
- self.reply = reply
-
- if order_by is None:
- order_by = 'ctime'
- self.order_by = order_by
-
- self.request = kwargs
-
- def __repr__(self):
- return 'offset=%s limit=%s request=%r query=%r order_by=%s ' \
- 'group_by=%s' % (self.offset, self.limit, self.request,
- self.query, self.order_by, self.group_by)
diff --git a/sugar_network/db/index.py b/sugar_network/db/index.py
index 3c8579f..156ff76 100644
--- a/sugar_network/db/index.py
+++ b/sugar_network/db/index.py
@@ -82,6 +82,9 @@ class IndexReader(object):
pass
os.utime(self._mtime_path, (value, value))
+ def ensure_open(self):
+ pass
+
def get_cached(self, guid):
"""Return cached document.
@@ -125,20 +128,46 @@ class IndexReader(object):
"""
raise NotImplementedError()
- def find(self, query):
- """Search documents within the index.
-
- Function interface is the same as for `db.Resource.find`.
+ def find(self, offset=0, limit=64, query='', reply=('guid',),
+ order_by=None, no_cache=False, group_by=None, **request):
+ """Search resources within the index.
+
+ The result will be an array of dictionaries with found documents'
+ properties.
+
+ :param offset:
+ the resulting list should start with this offset;
+ 0 by default
+ :param limit:
+ the resulting list will be at least `limit` size;
+ the `--find-limit` will be used by default
+ :param query:
+ a string in Xapian serach format, empty to avoid text search
+ :param reply:
+ an array of property names to use only in the resulting list;
+ only GUID property will be used by default
+ :param order_by:
+ property name to sort resulting list; might be prefixed with ``+``
+ (or without any prefixes) for ascending order, and ``-`` for
+ descending order
+ :param group_by:
+ property name to group resulting list by; no groupping by default
+ :param request:
+ a dictionary with property values to restrict the search
+ :returns:
+ a tuple of (`documents`, `total_count`); where the `total_count` is
+ the total number of documents conforming the search parameters,
+ i.e., not only documents that are included to the resulting list
"""
+ self.ensure_open()
+
start_timestamp = time.time()
# This will assure that the results count is exact.
- check_at_least = query.offset + query.limit + 1
+ check_at_least = offset + limit + 1
- enquire = self._enquire(query.request, query.query, query.order_by,
- query.group_by)
- mset = self._call_db(enquire.get_mset, query.offset, query.limit,
- check_at_least)
+ enquire = self._enquire(request, query, order_by, group_by)
+ mset = self._call_db(enquire.get_mset, offset, limit, check_at_least)
_logger.debug('Found in %s: %s time=%s total=%s parsed=%s',
self.metadata.name, query, time.time() - start_timestamp,
@@ -152,7 +181,7 @@ class IndexReader(object):
def _enquire(self, request, query, order_by, group_by):
enquire = xapian.Enquire(self._db)
- queries = []
+ all_queries = []
and_not_queries = []
boolean_queries = []
@@ -184,50 +213,37 @@ class IndexReader(object):
xapian.QueryParser.FLAG_WILDCARD |
xapian.QueryParser.FLAG_PURE_NOT,
'')
- queries.append(query)
+ all_queries.append(query)
for name, value in request.items():
+ queries = sub_queries = []
+ if name.startswith('!'):
+ queries = and_not_queries
+ name = name[1:]
+ elif name.startswith('not_'):
+ queries = and_not_queries
+ name = name[4:]
prop = self._props.get(name)
if prop is None or not prop.prefix:
continue
-
- sub_queries = []
- not_queries = []
for needle in value if type(value) in (tuple, list) else [value]:
if needle is None:
continue
if prop.parse is not None:
needle = prop.parse(needle)
needle = next(_fmt_prop_value(prop, needle))
- if needle.startswith('!'):
- term = _term(prop.prefix, needle[1:])
- not_queries.append(xapian.Query(term))
- elif needle.startswith('-'):
- term = _term(prop.prefix, needle[1:])
- and_not_queries.append(xapian.Query(term))
- else:
- term = _term(prop.prefix, needle)
- sub_queries.append(xapian.Query(term))
-
- if not_queries:
- not_query = xapian.Query(xapian.Query.OP_AND_NOT,
- [xapian.Query(''),
- xapian.Query(xapian.Query.OP_OR, not_queries)])
- sub_queries.append(not_query)
-
- if sub_queries:
- if len(sub_queries) == 1:
- query = sub_queries[0]
- else:
- query = xapian.Query(xapian.Query.OP_OR, sub_queries)
- if prop.boolean:
- boolean_queries.append(query)
- else:
- queries.append(query)
+ queries.append(xapian.Query(_term(prop.prefix, needle)))
+ if len(sub_queries) == 1:
+ all_queries.append(sub_queries[0])
+ elif sub_queries:
+ all_queries.append(
+ xapian.Query(xapian.Query.OP_OR, sub_queries))
final = None
- if queries:
- final = xapian.Query(xapian.Query.OP_AND, queries)
+ if len(all_queries) == 1:
+ final = all_queries[0]
+ elif all_queries:
+ final = xapian.Query(xapian.Query.OP_AND, all_queries)
if boolean_queries:
query = xapian.Query(xapian.Query.OP_AND, boolean_queries)
if final is None:
@@ -313,8 +329,7 @@ class IndexWriter(IndexReader):
# Let `_commit_handler()` call `wait()` to not miss immediate commit
coroutine.dispatch()
-
- self._do_open()
+ self.ensure_open()
def close(self):
"""Flush index write pending queue and close the index."""
@@ -325,14 +340,8 @@ class IndexWriter(IndexReader):
self._commit_job = None
self._db = None
- def find(self, query):
- if self._db is None:
- self._do_open()
- return IndexReader.find(self, query)
-
def store(self, guid, properties, pre_cb=None, post_cb=None, *args):
- if self._db is None:
- self._do_open()
+ self.ensure_open()
if pre_cb is not None:
pre_cb(guid, properties, *args)
@@ -377,8 +386,7 @@ class IndexWriter(IndexReader):
self._check_for_commit()
def delete(self, guid, post_cb=None, *args):
- if self._db is None:
- self._do_open()
+ self.ensure_open()
_logger.debug('Delete %r document from %r',
guid, self.metadata.name)
@@ -402,7 +410,9 @@ class IndexWriter(IndexReader):
with file(self._mtime_path, 'w'):
pass
- def _do_open(self):
+ def ensure_open(self):
+ if self._db is not None:
+ return
try:
self._db = xapian.WritableDatabase(self._path,
xapian.DB_CREATE_OR_OPEN)
diff --git a/sugar_network/db/resource.py b/sugar_network/db/resource.py
index 7484a89..fe071dc 100644
--- a/sugar_network/db/resource.py
+++ b/sugar_network/db/resource.py
@@ -73,7 +73,7 @@ class Resource(object):
})
return result
- @indexed_property(prefix='RL', typecast=[], default=['public'])
+ @indexed_property(prefix='RL', typecast=[], default=[])
def layer(self, value):
return value
diff --git a/sugar_network/node/routes.py b/sugar_network/node/routes.py
index f2db4ca..41cebc3 100644
--- a/sugar_network/node/routes.py
+++ b/sugar_network/node/routes.py
@@ -23,6 +23,7 @@ from os.path import join, isdir, exists
from sugar_network import db, node, toolkit, model
from sugar_network.node import stats_node, stats_user
+# pylint: disable-msg=W0611
from sugar_network.toolkit.router import route, preroute, postroute
from sugar_network.toolkit.router import ACL, fallbackroute
from sugar_network.toolkit.spec import EMPTY_LICENSE
@@ -223,7 +224,7 @@ class NodeRoutes(db.Routes, model.Routes):
versions = []
impls, __ = implementations.find(limit=db.MAX_LIMIT,
- context=context.guid, layer=layer)
+ context=context.guid, layer=layer, not_layer='deleted')
for impl in impls:
for arch, spec in impl.meta('data')['spec'].items():
spec['guid'] = impl.guid
@@ -334,11 +335,11 @@ class NodeRoutes(db.Routes, model.Routes):
_logger.warning('The find limit is restricted to %s',
node.find_limit.value)
request['limit'] = node.find_limit.value
- layer = request.get('layer', ['public'])
+ layer = request.setdefault('layer', [])
if 'deleted' in layer:
_logger.warning('Requesting "deleted" layer')
layer.remove('deleted')
- request['layer'] = layer
+ request.add('not_layer', 'deleted')
return db.Routes.find(self, request, reply)
def get(self, request, reply):
@@ -385,11 +386,10 @@ class NodeRoutes(db.Routes, model.Routes):
if 'stability' not in request:
request['stability'] = 'stable'
- if 'layer' not in request:
- request['layer'] = 'public'
impls, __ = self.volume['implementation'].find(
- context=request.guid, order_by='-version', **request)
+ context=request.guid, order_by='-version', not_layer='deleted',
+ **request)
impl = None
for impl in impls:
if requires:
@@ -445,16 +445,19 @@ def load_bundle(volume, bundle_path, impl=None):
http.BadRequest, 'Inappropriate bundle type')
if impl.get('license') in (None, EMPTY_LICENSE):
existing, total = volume['implementation'].find(
- context=impl['context'], order_by='-version')
+ context=impl['context'], order_by='-version',
+ not_layer='deleted')
enforce(total, 'License is not specified')
impl['license'] = next(existing)['license']
yield impl
existing, __ = volume['implementation'].find(
- context=impl['context'], version=impl['version'])
+ context=impl['context'], version=impl['version'],
+ not_layer='deleted')
for i in existing:
- volume['implementation'].update(i.guid, {'layer': ['deleted']})
+ layer = i['layer'] + ['deleted']
+ volume['implementation'].update(i.guid, {'layer': layer})
impl['guid'] = volume['implementation'].create(impl)
diff --git a/sugar_network/node/slave.py b/sugar_network/node/slave.py
index bbf9e00..2ad1d5a 100644
--- a/sugar_network/node/slave.py
+++ b/sugar_network/node/slave.py
@@ -83,10 +83,9 @@ class SlaveRoutes(NodeRoutes):
@route('POST', cmd='offline-sync', acl=ACL.LOCAL)
def offline_sync(self, path):
- enforce(node.sync_layers.value and
- 'public' not in node.sync_layers.value,
- '--layers is not specified, the full master dump might be '
- 'too big and should be limited')
+ enforce(node.sync_layers.value,
+ '--sync-layers is not specified, the full master dump '
+ 'might be too big and should be limited')
enforce(isabs(path), 'Argument \'path\' should be an absolute path')
_logger.debug('Start %r synchronization session in %r',
diff --git a/sugar_network/toolkit/router.py b/sugar_network/toolkit/router.py
index 9ecf556..5c19729 100644
--- a/sugar_network/toolkit/router.py
+++ b/sugar_network/toolkit/router.py
@@ -229,6 +229,15 @@ class Request(dict):
self._pos += len(result)
return result
+ def add(self, key, value):
+ existing_value = self.get(key)
+ if existing_value is None:
+ self[key] = value
+ elif type(existing_value) is list:
+ existing_value.append(value)
+ else:
+ self[key] = [existing_value, value]
+
def __repr__(self):
return '<Request method=%s path=%r cmd=%s query=%r>' % \
(self.method, self.path, self.cmd, dict(self))
@@ -336,7 +345,7 @@ class Router(object):
fallback, method, path, cmd, kwargs = attr.route
routes = self._routes
for i, part in enumerate(path):
- enforce(i == 0 or not routes.fallback_ops or \
+ enforce(i == 0 or not routes.fallback_ops or
(fallback and i == len(path) - 1),
'Fallback route should not have sub-routes')
if part is None:
diff --git a/tests/units/db/index.py b/tests/units/db/index.py
index 9b7d130..45dcbb8 100755
--- a/tests/units/db/index.py
+++ b/tests/units/db/index.py
@@ -14,7 +14,6 @@ from sugar_network import toolkit
from sugar_network.db import index
from sugar_network.db.index import _fmt_prop_value
from sugar_network.db.metadata import Metadata, IndexedProperty, GUID_PREFIX, Property
-from sugar_network.db.directory import _Query
from sugar_network.toolkit.router import ACL
from sugar_network.toolkit import coroutine
@@ -673,7 +672,7 @@ class IndexTest(tests.Test):
]),
db._find(prop=['b', 'foo', 'bar'], reply=['guid'])[0])
- def test_find_NotFilter(self):
+ def test_find_AndNotFilter(self):
db = Index({'prop': IndexedProperty('prop', 1, 'A')})
db.store('1', {'prop': 'a'})
@@ -685,70 +684,38 @@ class IndexTest(tests.Test):
{'guid': '2'},
{'guid': '3'},
]),
- db._find(prop='!a', reply=['guid'])[0])
-
- self.assertEqual(
- sorted([
- {'guid': '3'},
- ]),
- db._find(prop=['!a', '!b'], reply=['guid'])[0])
-
- self.assertEqual(
- sorted([
- ]),
- db._find(prop=['!a', '!b', '!c'], reply=['guid'])[0])
-
- self.assertEqual(
- sorted([
- {'guid': '1'},
- {'guid': '3'},
- ]),
- db._find(prop=['!b', 'c'], reply=['guid'])[0])
-
- self.assertEqual(
- sorted([
- {'guid': '1'},
- {'guid': '3'},
- ]),
- db._find(prop=['a', '!b', 'c'], reply=['guid'])[0])
-
- def test_find_AndNotFilter(self):
- db = Index({'prop': IndexedProperty('prop', 1, 'A')})
-
- db.store('1', {'prop': 'a'})
- db.store('2', {'prop': 'b'})
- db.store('3', {'prop': 'c'})
+ sorted(db._find(reply=['guid'], not_prop='a')[0]))
self.assertEqual(
sorted([
{'guid': '2'},
{'guid': '3'},
]),
- db._find(prop='-a', reply=['guid'])[0])
+ sorted(db._find(reply=['guid'], **{'!prop': 'a'})[0]))
self.assertEqual(
sorted([
{'guid': '3'},
]),
- db._find(prop=['-a', '-b'], reply=['guid'])[0])
+ sorted(db._find(reply=['guid'], **{'!prop': ['a', 'b']})[0]))
self.assertEqual(
sorted([
]),
- db._find(prop=['-a', '-b', '-c'], reply=['guid'])[0])
+ sorted(db._find(reply=['guid'], **{'!prop': ['a', 'b', 'c']})[0]))
self.assertEqual(
sorted([
{'guid': '3'},
]),
- db._find(prop=['-b', 'c'], reply=['guid'])[0])
+ sorted(db._find(prop='c', reply=['guid'], **{'!prop': 'b'})[0]))
self.assertEqual(
sorted([
{'guid': '1'},
{'guid': '3'},
]),
- db._find(prop=['a', '-b', 'c'], reply=['guid'])[0])
+ sorted(db._find(prop=['a', 'c'], reply=['guid'], **{'!prop': 'b'})[0]))
def test_fmt_prop_value(self):
prop = Property('prop')
@@ -785,18 +752,13 @@ class Index(index.IndexWriter):
index.IndexWriter.__init__(self, tests.tmpdir + '/index', metadata, *args)
- def _find(self, *args, **kwargs):
- if 'reply' not in kwargs:
- kwargs['reply'] = {}
- if 'order_by' not in kwargs:
- kwargs['order_by'] = 'guid'
-
- mset = self.find(_Query(*args, **kwargs))
+ def _find(self, reply=None, **kwargs):
+ mset = self.find(**kwargs)
result = []
- for hit in self.find(_Query(*args, **kwargs)):
+ for hit in mset:
props = {}
- for name in kwargs['reply']:
+ for name in (reply or []):
prop = self.metadata[name]
if prop.slot is not None:
props[name] = hit.document.get_value(prop.slot).decode('utf8')
diff --git a/tests/units/db/resource.py b/tests/units/db/resource.py
index ed37664..f8a56b1 100755
--- a/tests/units/db/resource.py
+++ b/tests/units/db/resource.py
@@ -45,13 +45,13 @@ class ResourceTest(tests.Test):
directory.create({'slotted': 'slotted', 'not_slotted': 'not_slotted'})
- docs, total = directory.find(0, 100, order_by='slotted')
+ docs, total = directory.find(order_by='slotted')
self.assertEqual(1, total)
self.assertEqual(
[('slotted', 'not_slotted')],
[(i.slotted, i.not_slotted) for i in docs])
- self.assertRaises(RuntimeError, directory.find, 0, 100, order_by='not_slotted')
+ self.assertRaises(RuntimeError, directory.find, order_by='not_slotted')
def test_ActiveProperty_SlottedIUnique(self):
@@ -84,14 +84,14 @@ class ResourceTest(tests.Test):
guid = directory.create({'term': 'term', 'not_term': 'not_term'})
- docs, total = directory.find(0, 100, term='term')
+ docs, total = directory.find(term='term')
self.assertEqual(1, total)
self.assertEqual(
[('term', 'not_term')],
[(i.term, i.not_term) for i in docs])
- self.assertEqual(0, directory.find(0, 100, query='not_term:not_term')[-1])
- self.assertEqual(1, directory.find(0, 100, query='not_term:=not_term')[-1])
+ self.assertEqual(0, directory.find(query='not_term:not_term')[-1])
+ self.assertEqual(1, directory.find(query='not_term:=not_term')[-1])
def test_ActiveProperty_TermsUnique(self):
@@ -125,8 +125,8 @@ class ResourceTest(tests.Test):
guid = directory.create({'no': 'foo', 'yes': 'bar'})
- self.assertEqual(0, directory.find(0, 100, query='foo')[-1])
- self.assertEqual(1, directory.find(0, 100, query='bar')[-1])
+ self.assertEqual(0, directory.find(query='foo')[-1])
+ self.assertEqual(1, directory.find(query='bar')[-1])
def test_update(self):
@@ -145,12 +145,12 @@ class ResourceTest(tests.Test):
guid = directory.create({'prop_1': '1', 'prop_2': '2'})
self.assertEqual(
[('1', '2')],
- [(i.prop_1, i.prop_2) for i in directory.find(0, 1024)[0]])
+ [(i.prop_1, i.prop_2) for i in directory.find()[0]])
directory.update(guid, {'prop_1': '3', 'prop_2': '4'})
self.assertEqual(
[('3', '4')],
- [(i.prop_1, i.prop_2) for i in directory.find(0, 1024)[0]])
+ [(i.prop_1, i.prop_2) for i in directory.find()[0]])
def test_delete(self):
@@ -168,22 +168,22 @@ class ResourceTest(tests.Test):
self.assertEqual(
['1', '2', '3'],
- [i.prop for i in directory.find(0, 1024)[0]])
+ [i.prop for i in directory.find()[0]])
directory.delete(guid_2)
self.assertEqual(
['1', '3'],
- [i.prop for i in directory.find(0, 1024)[0]])
+ [i.prop for i in directory.find()[0]])
directory.delete(guid_3)
self.assertEqual(
['1'],
- [i.prop for i in directory.find(0, 1024)[0]])
+ [i.prop for i in directory.find()[0]])
directory.delete(guid_1)
self.assertEqual(
[],
- [i.prop for i in directory.find(0, 1024)[0]])
+ [i.prop for i in directory.find()[0]])
def test_populate(self):
@@ -229,7 +229,7 @@ class ResourceTest(tests.Test):
(1, 1, 'prop-1'),
(2, 2, 'prop-2'),
],
- [(i.ctime, i.mtime, i.prop) for i in directory.find(0, 10)[0]])
+ [(i.ctime, i.mtime, i.prop) for i in directory.find()[0]])
def test_populate_IgnoreBadDocuments(self):
@@ -267,7 +267,7 @@ class ResourceTest(tests.Test):
self.assertEqual(1, populated)
self.assertEqual(
sorted(['1']),
- sorted([i.guid for i in directory.find(0, 10)[0]]))
+ sorted([i.guid for i in directory.find()[0]]))
assert exists('1/1/guid')
assert not exists('2/2/guid')
assert not exists('3/3/guid')
@@ -285,12 +285,12 @@ class ResourceTest(tests.Test):
guid = directory.create({'guid': 'guid', 'prop': 'foo'})
self.assertEqual(
[('guid', 'foo')],
- [(i.guid, i.prop) for i in directory.find(0, 1024)[0]])
+ [(i.guid, i.prop) for i in directory.find()[0]])
directory.update(guid, {'prop': 'probe'})
self.assertEqual(
[('guid', 'probe')],
- [(i.guid, i.prop) for i in directory.find(0, 1024)[0]])
+ [(i.guid, i.prop) for i in directory.find()[0]])
def test_seqno(self):
@@ -623,7 +623,7 @@ class ResourceTest(tests.Test):
(2, '2', 2, '2'),
(3, '3', 3, '3'),
]),
- sorted([(i['ctime'], i['prop'], i['mtime'], i['guid']) for i in directory2.find(0, 1024)[0]]))
+ sorted([(i['ctime'], i['prop'], i['mtime'], i['guid']) for i in directory2.find()[0]]))
doc = directory2.get('1')
self.assertEqual(1, doc.get('seqno'))
@@ -675,7 +675,7 @@ class ResourceTest(tests.Test):
self.assertEqual(
[(2, 2, 'guid')],
- [(i['ctime'], i['mtime'], i['guid']) for i in directory2.find(0, 1024)[0]])
+ [(i['ctime'], i['mtime'], i['guid']) for i in directory2.find()[0]])
doc = directory2.get('guid')
self.assertEqual(2, doc.get('seqno'))
self.assertEqual(2, doc.meta('guid')['mtime'])
@@ -689,7 +689,7 @@ class ResourceTest(tests.Test):
self.assertEqual(
[(2, 2, 'guid')],
- [(i['ctime'], i['mtime'], i['guid']) for i in directory2.find(0, 1024)[0]])
+ [(i['ctime'], i['mtime'], i['guid']) for i in directory2.find()[0]])
doc = directory2.get('guid')
self.assertEqual(2, doc.get('seqno'))
self.assertEqual(2, doc.meta('guid')['mtime'])
@@ -704,7 +704,7 @@ class ResourceTest(tests.Test):
self.assertEqual(
[(2, 1, 'guid')],
- [(i['ctime'], i['mtime'], i['guid']) for i in directory2.find(0, 1024)[0]])
+ [(i['ctime'], i['mtime'], i['guid']) for i in directory2.find()[0]])
doc = directory2.get('guid')
self.assertEqual(3, doc.get('seqno'))
self.assertEqual(2, doc.meta('guid')['mtime'])
@@ -719,7 +719,7 @@ class ResourceTest(tests.Test):
self.assertEqual(
[(2, 1, 'guid')],
- [(i['ctime'], i['mtime'], i['guid']) for i in directory2.find(0, 1024)[0]])
+ [(i['ctime'], i['mtime'], i['guid']) for i in directory2.find()[0]])
doc = directory2.get('guid')
self.assertEqual(4, doc.get('seqno'))
self.assertEqual(2, doc.meta('guid')['mtime'])
@@ -744,7 +744,7 @@ class ResourceTest(tests.Test):
directory2.merge(shift_seqno=False, **patch)
self.assertEqual(
[(1, 1, '1', '1')],
- [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory2.find(0, 1024)[0]])
+ [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory2.find()[0]])
doc = directory2.get('1')
self.assertEqual(0, doc.get('seqno'))
self.assertEqual(0, doc.meta('guid')['seqno'])
@@ -755,7 +755,7 @@ class ResourceTest(tests.Test):
directory3.merge(**patch)
self.assertEqual(
[(1, 1, '1', '1')],
- [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory3.find(0, 1024)[0]])
+ [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory3.find()[0]])
doc = directory3.get('1')
self.assertEqual(1, doc.get('seqno'))
self.assertEqual(1, doc.meta('guid')['seqno'])
@@ -768,7 +768,7 @@ class ResourceTest(tests.Test):
directory3.merge(shift_seqno=False, **patch)
self.assertEqual(
[(2, 2, '1', '2')],
- [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory3.find(0, 1024)[0]])
+ [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory3.find()[0]])
doc = directory3.get('1')
self.assertEqual(1, doc.get('seqno'))
self.assertEqual(1, doc.meta('guid')['seqno'])
@@ -781,7 +781,7 @@ class ResourceTest(tests.Test):
directory3.merge(**patch)
self.assertEqual(
[(3, 3, '1', '3')],
- [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory3.find(0, 1024)[0]])
+ [(i['ctime'], i['mtime'], i['guid'], i['prop']) for i in directory3.find()[0]])
doc = directory3.get('1')
self.assertEqual(2, doc.get('seqno'))
self.assertEqual(1, doc.meta('guid')['seqno'])
@@ -828,7 +828,7 @@ class ResourceTest(tests.Test):
self.assertEqual(
[(2, 3, '1')],
- [(i['ctime'], i['mtime'], i['guid']) for i in directory.find(0, 1024)[0]])
+ [(i['ctime'], i['mtime'], i['guid']) for i in directory.find()[0]])
doc = directory.get('1')
self.assertEqual(1, doc.get('seqno'))
@@ -853,12 +853,12 @@ class ResourceTest(tests.Test):
directory = Directory(tests.tmpdir, Document, IndexWriter)
guid = directory.create({'prop': '1'})
- self.assertEqual([guid], [i.guid for i in directory.find(0, 1024)[0]])
+ self.assertEqual([guid], [i.guid for i in directory.find()[0]])
directory.commit()
assert directory.mtime != 0
directory.wipe()
- self.assertEqual([], [i.guid for i in directory.find(0, 1024)[0]])
+ self.assertEqual([], [i.guid for i in directory.find()[0]])
assert directory.mtime == 0
diff --git a/tests/units/db/routes.py b/tests/units/db/routes.py
index 3d2d7f1..f5d44db 100755
--- a/tests/units/db/routes.py
+++ b/tests/units/db/routes.py
@@ -409,28 +409,28 @@ class RoutesTest(tests.Test):
self.assertEqual({'en': 'value_raw'}, directory.get(guid)['localized_prop'])
self.assertEqual(
[guid],
- [i.guid for i in directory.find(0, 100, localized_prop='value_raw')[0]])
+ [i.guid for i in directory.find(localized_prop='value_raw')[0]])
directory.update(guid, {'localized_prop': 'value_raw2'})
self.assertEqual({'en': 'value_raw2'}, directory.get(guid)['localized_prop'])
self.assertEqual(
[guid],
- [i.guid for i in directory.find(0, 100, localized_prop='value_raw2')[0]])
+ [i.guid for i in directory.find(localized_prop='value_raw2')[0]])
guid = self.call('POST', path=['testdocument'], accept_language=['ru'], content={'localized_prop': 'value_ru'})
self.assertEqual({'ru': 'value_ru'}, directory.get(guid)['localized_prop'])
self.assertEqual(
[guid],
- [i.guid for i in directory.find(0, 100, localized_prop='value_ru')[0]])
+ [i.guid for i in directory.find(localized_prop='value_ru')[0]])
self.call('PUT', path=['testdocument', guid], accept_language=['en'], content={'localized_prop': 'value_en'})
self.assertEqual({'ru': 'value_ru', 'en': 'value_en'}, directory.get(guid)['localized_prop'])
self.assertEqual(
[guid],
- [i.guid for i in directory.find(0, 100, localized_prop='value_ru')[0]])
+ [i.guid for i in directory.find(localized_prop='value_ru')[0]])
self.assertEqual(
[guid],
- [i.guid for i in directory.find(0, 100, localized_prop='value_en')[0]])
+ [i.guid for i in directory.find(localized_prop='value_en')[0]])
def test_LocalizedGet(self):
@@ -1572,6 +1572,24 @@ class RoutesTest(tests.Test):
prop = Property('prop', typecast=lambda x: x + 1)
self.assertEqual(1, _typecast_prop_value(prop.typecast, 0))
+ def test_DefaultOrder(self):
+
+ class Document(db.Resource):
+ pass
+
+ self.volume = db.Volume('db', [Document])
+
+ self.volume['document'].create({'guid': '3', 'ctime': 3})
+ self.volume['document'].create({'guid': '2', 'ctime': 2})
+ self.volume['document'].create({'guid': '1', 'ctime': 1})
+
+ self.assertEqual([
+ {'guid': '1'},
+ {'guid': '2'},
+ {'guid': '3'},
+ ],
+ self.call('GET', ['document'])['result'])
+
def call(self, method=None, path=None,
accept_language=None, content=None, content_stream=None, cmd=None,
content_type=None, host=None, request=None, routes=db.Routes, principal=None,
diff --git a/tests/units/node/node.py b/tests/units/node/node.py
index cf9523b..8a9ce5f 100755
--- a/tests/units/node/node.py
+++ b/tests/units/node/node.py
@@ -150,10 +150,10 @@ class NodeTest(tests.Test):
self.assertEqual({
'guid': guid,
'title': 'title',
- 'layer': ['public'],
+ 'layer': [],
},
call(cp, method='GET', document='context', guid=guid, reply=['guid', 'title', 'layer']))
- self.assertEqual(['public'], volume['context'].get(guid)['layer'])
+ self.assertEqual([], volume['context'].get(guid)['layer'])
def subscribe():
for event in cp.subscribe():
@@ -700,9 +700,9 @@ class NodeTest(tests.Test):
guid2 = json.load(conn.request('POST', ['implementation'], bundle2, params={'cmd': 'release'}).raw)
self.assertEqual('1', volume['implementation'].get(guid1)['version'])
- self.assertEqual(['public'], volume['implementation'].get(guid1)['layer'])
+ self.assertEqual([], volume['implementation'].get(guid1)['layer'])
self.assertEqual('2', volume['implementation'].get(guid2)['version'])
- self.assertEqual(['public'], volume['implementation'].get(guid2)['layer'])
+ self.assertEqual([], volume['implementation'].get(guid2)['layer'])
self.assertEqual(bundle2, conn.get(['context', 'bundle_id'], cmd='clone'))
activity_info = '\n'.join([
@@ -721,9 +721,9 @@ class NodeTest(tests.Test):
self.assertEqual('1', volume['implementation'].get(guid1)['version'])
self.assertEqual(['deleted'], volume['implementation'].get(guid1)['layer'])
self.assertEqual('2', volume['implementation'].get(guid2)['version'])
- self.assertEqual(['public'], volume['implementation'].get(guid2)['layer'])
+ self.assertEqual([], volume['implementation'].get(guid2)['layer'])
self.assertEqual('1', volume['implementation'].get(guid3)['version'])
- self.assertEqual(['public'], volume['implementation'].get(guid3)['layer'])
+ self.assertEqual([], volume['implementation'].get(guid3)['layer'])
self.assertEqual(bundle2, conn.get(['context', 'bundle_id'], cmd='clone'))
activity_info = '\n'.join([
@@ -744,9 +744,9 @@ class NodeTest(tests.Test):
self.assertEqual('2', volume['implementation'].get(guid2)['version'])
self.assertEqual(['deleted'], volume['implementation'].get(guid2)['layer'])
self.assertEqual('1', volume['implementation'].get(guid3)['version'])
- self.assertEqual(['public'], volume['implementation'].get(guid3)['layer'])
+ self.assertEqual([], volume['implementation'].get(guid3)['layer'])
self.assertEqual('2', volume['implementation'].get(guid4)['version'])
- self.assertEqual(['public'], volume['implementation'].get(guid4)['layer'])
+ self.assertEqual([], volume['implementation'].get(guid4)['layer'])
self.assertEqual(bundle3, conn.get(['context', 'bundle_id'], cmd='clone'))
diff --git a/tests/units/node/sync_offline.py b/tests/units/node/sync_offline.py
index f3b7111..0353e58 100755
--- a/tests/units/node/sync_offline.py
+++ b/tests/units/node/sync_offline.py
@@ -54,11 +54,7 @@ class SyncOfflineTest(tests.Test):
node.sync_layers.value = None
self.assertRaises(RuntimeError, cp.offline_sync, tests.tmpdir + '/mnt')
node.sync_layers.value = 'public'
- self.assertRaises(RuntimeError, cp.offline_sync, tests.tmpdir + '/mnt')
- node.sync_layers.value = ['public']
- self.assertRaises(RuntimeError, cp.offline_sync, tests.tmpdir + '/mnt')
- node.sync_layers.value = ['public', 'foo']
- self.assertRaises(RuntimeError, cp.offline_sync, tests.tmpdir + '/mnt')
+ cp.offline_sync(tests.tmpdir + '/mnt')
def test_Export(self):
diff --git a/tests/units/node/sync_online.py b/tests/units/node/sync_online.py
index 4b46306..6a88875 100755
--- a/tests/units/node/sync_online.py
+++ b/tests/units/node/sync_online.py
@@ -103,8 +103,8 @@ class SyncOnlineTest(tests.Test):
client.post(cmd='online-sync')
self.assertEqual([
{'guid': guid1, 'content': {'en-us': '1'}, 'layer': ['deleted']},
- {'guid': guid2, 'content': {'en-us': '22'}, 'layer': ['public']},
- {'guid': guid3, 'content': {'en-us': '3'}, 'layer': ['public']},
+ {'guid': guid2, 'content': {'en-us': '22'}, 'layer': []},
+ {'guid': guid3, 'content': {'en-us': '3'}, 'layer': []},
],
[i.properties(['guid', 'content', 'layer']) for i in self.master_volume['document'].find()[0]])
self.assertEqual([[8, None]], json.load(file('slave/pull.sequence')))
@@ -120,8 +120,8 @@ class SyncOnlineTest(tests.Test):
self.assertEqual([
{'guid': guid1, 'content': {'en-us': 'a'}, 'layer': ['deleted']},
{'guid': guid2, 'content': {'en-us': 'b'}, 'layer': ['deleted']},
- {'guid': guid3, 'content': {'en-us': 'c'}, 'layer': ['public']},
- {'guid': guid4, 'content': {'en-us': 'd'}, 'layer': ['public']},
+ {'guid': guid3, 'content': {'en-us': 'c'}, 'layer': []},
+ {'guid': guid4, 'content': {'en-us': 'd'}, 'layer': []},
],
[i.properties(['guid', 'content', 'layer']) for i in self.master_volume['document'].find()[0]])
self.assertEqual([[12, None]], json.load(file('slave/pull.sequence')))
@@ -180,8 +180,8 @@ class SyncOnlineTest(tests.Test):
slave_client.post(cmd='online-sync')
self.assertEqual([
{'guid': guid1, 'content': {'en-us': '1'}, 'layer': ['deleted']},
- {'guid': guid2, 'content': {'en-us': '22'}, 'layer': ['public']},
- {'guid': guid3, 'content': {'en-us': '3'}, 'layer': ['public']},
+ {'guid': guid2, 'content': {'en-us': '22'}, 'layer': []},
+ {'guid': guid3, 'content': {'en-us': '3'}, 'layer': []},
],
[i.properties(['guid', 'content', 'layer']) for i in self.slave_volume['document'].find()[0]])
self.assertEqual([[8, None]], json.load(file('slave/pull.sequence')))
@@ -197,8 +197,8 @@ class SyncOnlineTest(tests.Test):
self.assertEqual([
{'guid': guid1, 'content': {'en-us': 'a'}, 'layer': ['deleted']},
{'guid': guid2, 'content': {'en-us': 'b'}, 'layer': ['deleted']},
- {'guid': guid3, 'content': {'en-us': 'c'}, 'layer': ['public']},
- {'guid': guid4, 'content': {'en-us': 'd'}, 'layer': ['public']},
+ {'guid': guid3, 'content': {'en-us': 'c'}, 'layer': []},
+ {'guid': guid4, 'content': {'en-us': 'd'}, 'layer': []},
],
[i.properties(['guid', 'content', 'layer']) for i in self.slave_volume['document'].find()[0]])
self.assertEqual([[13, None]], json.load(file('slave/pull.sequence')))
diff --git a/tests/units/node/volume.py b/tests/units/node/volume.py
index 9a3a113..f6b2105 100755
--- a/tests/units/node/volume.py
+++ b/tests/units/node/volume.py
@@ -49,7 +49,7 @@ class VolumeTest(tests.Test):
'ctime': {'value': 0, 'mtime': 1},
'prop': {'value': 'a', 'mtime': 1},
'author': {'mtime': 1, 'value': {}},
- 'layer': {'mtime': 1, 'value': ['public']},
+ 'layer': {'mtime': 1, 'value': []},
'tags': {'mtime': 1, 'value': []},
},
},
@@ -60,7 +60,7 @@ class VolumeTest(tests.Test):
'ctime': {'value': 0, 'mtime': 2},
'prop': {'value': 'b', 'mtime': 2},
'author': {'mtime': 2, 'value': {}},
- 'layer': {'mtime': 2, 'value': ['public']},
+ 'layer': {'mtime': 2, 'value': []},
'tags': {'mtime': 2, 'value': []},
},
},
@@ -375,7 +375,7 @@ class VolumeTest(tests.Test):
'artifact': {'value': artifact, 'mtime': 4.0},
'rating': {'value': 1, 'mtime': 1.0},
'author': {'mtime': 1, 'value': {}},
- 'layer': {'mtime': 1, 'value': ['public']},
+ 'layer': {'mtime': 1, 'value': []},
'tags': {'mtime': 1, 'value': []},
}},
{'guid': '2', 'diff': {
@@ -385,7 +385,7 @@ class VolumeTest(tests.Test):
'context': {'value': context, 'mtime': 2.0},
'rating': {'value': 2, 'mtime': 2.0},
'author': {'mtime': 2, 'value': {}},
- 'layer': {'mtime': 2, 'value': ['public']},
+ 'layer': {'mtime': 2, 'value': []},
'tags': {'mtime': 2, 'value': []},
}},
{'commit': [[1, 2]]},
@@ -433,7 +433,7 @@ class VolumeTest(tests.Test):
{'guid': guid, 'diff': {
'guid': {'value': guid, 'mtime': 0},
'author': {'mtime': 0, 'value': {}},
- 'layer': {'mtime': 0, 'value': ['public']},
+ 'layer': {'mtime': 0, 'value': []},
'tags': {'mtime': 0, 'value': []},
'mtime': {'value': 0, 'mtime': 0},
'ctime': {'value': 0, 'mtime': 0},
@@ -467,7 +467,7 @@ class VolumeTest(tests.Test):
'diff': {
'guid': {'value': guid, 'mtime': 1},
'author': {'mtime': 1, 'value': {}},
- 'layer': {'mtime': 1, 'value': ['public']},
+ 'layer': {'mtime': 1, 'value': []},
'tags': {'mtime': 1, 'value': []},
'mtime': {'value': 0, 'mtime': 1},
'ctime': {'value': 0, 'mtime': 1},
@@ -491,7 +491,7 @@ class VolumeTest(tests.Test):
{'guid': guid, 'diff': {
'guid': {'value': guid, 'mtime': 1},
'author': {'mtime': 1, 'value': {}},
- 'layer': {'mtime': 1, 'value': ['public']},
+ 'layer': {'mtime': 1, 'value': []},
'tags': {'mtime': 1, 'value': []},
'mtime': {'value': 0, 'mtime': 1},
'ctime': {'value': 0, 'mtime': 1},
@@ -524,7 +524,7 @@ class VolumeTest(tests.Test):
'diff': {
'guid': {'value': guid1, 'mtime': 1},
'author': {'mtime': 1, 'value': {}},
- 'layer': {'mtime': 1, 'value': ['public']},
+ 'layer': {'mtime': 1, 'value': []},
'tags': {'mtime': 1, 'value': []},
'mtime': {'value': 0, 'mtime': 1},
'ctime': {'value': 0, 'mtime': 1},
@@ -535,7 +535,7 @@ class VolumeTest(tests.Test):
'diff': {
'guid': {'value': guid2, 'mtime': 1},
'author': {'mtime': 1, 'value': {}},
- 'layer': {'mtime': 1, 'value': ['public']},
+ 'layer': {'mtime': 1, 'value': []},
'tags': {'mtime': 1, 'value': []},
'mtime': {'value': 0, 'mtime': 1},
'ctime': {'value': 0, 'mtime': 1},
@@ -551,7 +551,7 @@ class VolumeTest(tests.Test):
'diff': {
'guid': {'value': guid1, 'mtime': 1},
'author': {'mtime': 1, 'value': {}},
- 'layer': {'mtime': 1, 'value': ['public']},
+ 'layer': {'mtime': 1, 'value': []},
'tags': {'mtime': 1, 'value': []},
'mtime': {'value': 0, 'mtime': 1},
'ctime': {'value': 0, 'mtime': 1},
@@ -561,7 +561,7 @@ class VolumeTest(tests.Test):
'diff': {
'guid': {'value': guid2, 'mtime': 1},
'author': {'mtime': 1, 'value': {}},
- 'layer': {'mtime': 1, 'value': ['public']},
+ 'layer': {'mtime': 1, 'value': []},
'tags': {'mtime': 1, 'value': []},
'mtime': {'value': 0, 'mtime': 1},
'ctime': {'value': 0, 'mtime': 1},