Revision f897bea9

b/pithos/backends/lib/sqlalchemy/node.py
41 41

  
42 42
from dbworker import DBWorker
43 43

  
44
from pithos.lib.filter import parse_filters
45

  
44
from pithos.lib.filter import parse_filters, OPERATORS
46 45

  
47 46
ROOTNODE  = 0
48 47

  
......
830 829
        s = s.where(v.c.cluster != except_cluster)
831 830
        s = s.where(v.c.node.in_(select([self.nodes.c.node],
832 831
            self.nodes.c.parent == parent)))
833
        if domain and filterq:
834
            s = s.where(a.c.serial == v.c.serial)
835
            s = s.where(a.c.domain == domain)
836 832
        
837 833
        s = s.where(n.c.node == v.c.node)
838 834
        s = s.where(and_(n.c.path > bindparam('start'), n.c.path < nextling))
......
843 839
        if conj:
844 840
            s = s.where(or_(*conj))
845 841
        
846
        if domain and filterq:
842
        s = s.order_by(n.c.path)
843
        
844
        def filterout(r):
845
            if not filterq:
846
                return False
847
            path, serial = r
847 848
            included, excluded, opers = parse_filters(filterq)
849
            
850
            #retrieve metadata
851
            s = select([a.c.key, a.c.value])
852
            s = s.where(a.c.domain == domain)
853
            s = s.where(a.c.serial == serial)
854
            rp = self.conn.execute(s)
855
            meta = dict(rp.fetchall())
856
            keyset= set([k.encode('utf8') for k in meta.keys()])
857
            
848 858
            if included:
849
                s = s.where(a.c.key.in_(x for x in included))
859
                if not set(included) & keyset:
860
                    return True
850 861
            if excluded:
851
                s = s.where(not_(a.c.key.in_(x for x in excluded)))
852
            if opers:
853
                for k, o, v in opers:
854
                    s = s.where(or_(a.c.key == k and a.c.value.op(o)(v)))
855
        
856
        s = s.order_by(n.c.path)
857
        
862
                if set(excluded) & keyset:
863
                    return True
864
            for k, op, v in opers:
865
                k = k.decode('utf8')
866
                v = v.decode('utf8')
867
                if k not in meta:
868
                    return True
869
                operation = OPERATORS[op]
870
                if not operation(meta[k], v):
871
                    return True
872
            return False
873
    
858 874
        if not delimiter:
859 875
            s = s.limit(limit)
860 876
            rp = self.conn.execute(s, start=start)
861
            r = rp.fetchall()
877
            filter_ = lambda r : [t for t in r if not filterout(t)]
878
            r = filter_(rp.fetchall())
862 879
            rp.close()
863 880
            return r, ()
864 881
        
......
875 892
            props = rp.fetchone()
876 893
            if props is None:
877 894
                break
895
            if filterout(props):
896
                continue
878 897
            path, serial = props
879 898
            idx = path.find(delimiter, pfz)
880 899
            
b/pithos/lib/filter.py
32 32
# or implied, of GRNET S.A.
33 33

  
34 34
import re
35
import operator
35 36

  
37
_regexfilter = re.compile('(!?)\s*(\S+?)\s*(?:(=|!=|<=|>=|<|>)\s*(\S*?)\s*)?$', re.UNICODE)
36 38

  
37
_regexfilter = re.compile('(!?)\s*(.+)\s*(=|!=|<=|>=|<|>)?\s*(.*)$', re.UNICODE)
38

  
39
OPERATORS = {'=':operator.eq,
40
             '!=':operator.ne,
41
             '<=':operator.le,
42
             '>=':operator.ge,
43
             '<':operator.lt,
44
             '>':operator.gt
45
}
39 46

  
40 47
def parse_filters(terms):
41 48
    included = []
......
49 56
        neg, key, op, value = m.groups()
50 57
        if neg:
51 58
            excluded.append(key)
52
        elif not value:
53
            included.append(key)
54 59
        elif op:
55 60
            opers.append((key, op, value))
56

  
61
        elif not value:
62
            included.append(key)
63
    
57 64
    return included, excluded, opers
b/pithos/tools/pithos-test
1684 1684
        self.assertTrue('o2' not in my_shared_objects)
1685 1685
    
1686 1686
class TestGreek(BaseTestCase):
1687
    def tearDown(self):
1688
        pass
1689
    
1690 1687
    def test_create_container(self):
1691 1688
        self.client.create_container('φάκελος')
1692 1689
        self.assert_container_exists('φάκελος')
......
1796 1793
        
1797 1794
        meta = {'ποιότητα':'ΑΒ'}
1798 1795
        self.client.update_object_metadata('φάκελος', 'ο2', **meta)
1799
        objects = self.client.list_objects('φάκελος', meta='ποιότητα==ΑΑΑ')
1796
        objects = self.client.list_objects('φάκελος', meta='ποιότητα=ΑΑΑ')
1800 1797
        self.assertEquals(objects, ['ο1'])
1801 1798
        objects = self.client.list_objects('φάκελος', meta='ποιότητα!=ΑΑΑ')
1802 1799
        self.assertEquals(objects, ['ο2'])
......
1806 1803
        meta = {'έτος':'2012'}
1807 1804
        self.client.update_object_metadata('φάκελος', 'ο2', **meta)
1808 1805
        objects = self.client.list_objects('φάκελος', meta='έτος<2012')
1809
        self.assertEquals(objects, ['ο1'])
1806
        self.assertEquals(objects, ['ο3'])
1810 1807
        objects = self.client.list_objects('φάκελος', meta='έτος<=2012')
1811
        self.assertEquals(objects, ['ο1', 'ο2'])
1812
        objects = self.client.list_objects('φάκελος', meta='έτος<2012,έτος!=2012')
1813
        self.assertEquals(objects, ['ο2'])
1808
        self.assertEquals(objects, ['ο2', 'ο3'])
1809
        objects = self.client.list_objects('φάκελος', meta='έτος<2012,έτος!=2011')
1810
        self.assertEquals(objects, '')
1814 1811
    
1815 1812
    def test_groups(self):
1816 1813
        #create a group

Also available in: Unified diff