included, excluded, opers = parse_filters(keys)
keys = []
keys += [format_header_key('X-Object-Meta-' + x) for x in included]
- keys += [format_header_key('!X-Object-Meta-' + x) for x in excluded]
+ keys += ['!'+format_header_key('X-Object-Meta-' + x) for x in excluded]
keys += ['%s%s%s' % (format_header_key('X-Object-Meta-' + k), o, v) for k, o, v in opers]
else:
keys = []
from sqlalchemy import Table, Integer, BigInteger, DECIMAL, Column, String, MetaData, ForeignKey
from sqlalchemy.types import Text
from sqlalchemy.schema import Index, Sequence
-from sqlalchemy.sql import func, and_, or_, null, select, bindparam, text
+from sqlalchemy.sql import func, and_, or_, not_, null, select, bindparam, text
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.engine.reflection import Inspector
from dbworker import DBWorker
+from pithos.lib.filter import parse_filters
+
ROOTNODE = 0
( SERIAL, NODE, HASH, SIZE, SOURCE, MTIME, MUSER, CLUSTER ) = range(8)
s += unichr(c-1) + unichr(0xffff)
return s
-
_propnames = {
'serial' : 0,
'node' : 1,
def latest_version_list(self, parent, prefix='', delimiter=None,
start='', limit=10000, before=inf,
- except_cluster=0, pathq=[], filterq=None):
+ except_cluster=0, pathq=[], filterq=[]):
"""Return a (list of (path, serial) tuples, list of common prefixes)
for the current versions of the paths with the given parent,
matching the following criteria.
s = s.where(or_(*conj))
if filterq:
- s = s.where(a.c.key.in_(filterq.split(',')))
+ included, excluded, opers = parse_filters(filterq)
+ if included:
+ s = s.where(a.c.key.in_(x for x in included))
+ if excluded:
+ s = s.where(not_(a.c.key.in_(x for x in excluded)))
+ if opers:
+ for k, o, v in opers:
+ s = s.where(or_(a.c.key == k and a.c.value.op(o)(v)))
s = s.order_by(n.c.path)
subqlist = []
append = subqlist.append
- included, excluded, opers = parse_filters(filterq.split(','))
+ included, excluded, opers = parse_filters(filterq)
args = []
if included:
if not subqlist:
return None, None
- subq = ' ' + ' and '.join(subqlist)
-
+ subq = ' and ' + ' and '.join(subqlist)
return subq, args
def _construct_paths(self, pathq):
def latest_version_list(self, parent, prefix='', delimiter=None,
start='', limit=10000, before=inf,
- except_cluster=0, pathq=[], filterq=None):
+ except_cluster=0, pathq=[], filterq=[]):
"""Return a (list of (path, serial) tuples, list of common prefixes)
for the current versions of the paths with the given parent,
matching the following criteria.
prefix = cont_prefix + prefix
start = cont_prefix + marker if marker else None
before = until if until is not None else inf
- filterq = ','.join(keys) if keys else None
- objects, prefixes = self.node.latest_version_list(parent, prefix, delimiter, start, limit, before, CLUSTER_DELETED, allowed, filterq)
+ objects, prefixes = self.node.latest_version_list(parent, prefix, delimiter, start, limit, before, CLUSTER_DELETED, allowed, keys)
objects.extend([(p, None) for p in prefixes] if virtual else [])
objects.sort(key=lambda x: x[0])
objects = [(x[0][len(cont_prefix):], x[1]) for x in objects]
import re
-_regexfilter = re.compile('(!?)\s*([\w-]+)\s*(=|!=|<=|>=|<|>)?\s*(.*)$', re.UNICODE)
+_regexfilter = re.compile('(!?)\s*(.+)\s*(=|!=|<=|>=|<|>)?\s*(.*)$', re.UNICODE)
def parse_filters(terms):
self.assertTrue('o2' not in my_shared_objects)
class TestGreek(BaseTestCase):
+ def tearDown(self):
+ pass
+
def test_create_container(self):
self.client.create_container('φάκελος')
self.assert_container_exists('φάκελος')
meta = {'ποσότητα':'μεγάλη'}
self.client.update_object_metadata('φάκελος', 'ο2', **meta)
objects = self.client.list_objects('φάκελος', meta='ποιότητα, ποσότητα')
- self.assertTrue('ο1' in objects)
- self.assertTrue('ο2' in objects)
- self.assertTrue('ο3' not in objects)
+ self.assertEquals(objects, ['ο1', 'ο2'])
+
+ objects = self.client.list_objects('φάκελος', meta='!ποιότητα')
+ self.assertEquals(objects, ['ο2', 'ο3'])
+
+ objects = self.client.list_objects('φάκελος', meta='!ποιότητα, !ποσότητα')
+ self.assertEquals(objects, ['ο3'])
+
+ meta = {'ποιότητα':'ΑΒ'}
+ self.client.update_object_metadata('φάκελος', 'ο2', **meta)
+ objects = self.client.list_objects('φάκελος', meta='ποιότητα==ΑΑΑ')
+ self.assertEquals(objects, ['ο1'])
+ objects = self.client.list_objects('φάκελος', meta='ποιότητα!=ΑΑΑ')
+ self.assertEquals(objects, ['ο2'])
+
+ meta = {'έτος':'2011'}
+ self.client.update_object_metadata('φάκελος', 'ο3', **meta)
+ meta = {'έτος':'2012'}
+ self.client.update_object_metadata('φάκελος', 'ο2', **meta)
+ objects = self.client.list_objects('φάκελος', meta='έτος<2012')
+ self.assertEquals(objects, ['ο1'])
+ objects = self.client.list_objects('φάκελος', meta='έτος<=2012')
+ self.assertEquals(objects, ['ο1', 'ο2'])
+ objects = self.client.list_objects('φάκελος', meta='έτος<2012,έτος!=2012')
+ self.assertEquals(objects, ['ο2'])
def test_groups(self):
#create a group