Revision 235a4227

b/snf-pithos-backend/pithos/backends/lib/sqlalchemy/dbworker.py
31 31
# interpreted as representing official policies, either expressed
32 32
# or implied, of GRNET S.A.
33 33

  
34
ESCAPE_CHAR = '@'
34 35

  
35 36
class DBWorker(object):
36 37
    """Database connection handler."""
......
42 43
        self.conn = wrapper.conn
43 44
        self.engine = wrapper.engine
44 45

  
45
    def escape_like(self, s):
46
        return s.replace('\\', '\\\\').replace('%', '\%').replace('_', '\_')
46
    def escape_like(self, s, escape_char=ESCAPE_CHAR):
47
        return (
48
                s
49
                .replace(escape_char, escape_char * 2)
50
                .replace('%', escape_char + '%')
51
                .replace('_', escape_char + '_')
52
        )
b/snf-pithos-backend/pithos/backends/lib/sqlalchemy/node.py
40 40
from sqlalchemy.engine.reflection import Inspector
41 41
from sqlalchemy.exc import NoSuchTableError
42 42

  
43
from dbworker import DBWorker
43
from dbworker import DBWorker, ESCAPE_CHAR
44 44

  
45 45
from pithos.backends.filter import parse_filters
46 46

  
......
237 237

  
238 238
        # Use LIKE for comparison to avoid MySQL problems with trailing spaces.
239 239
        s = select([self.nodes.c.node], self.nodes.c.path.like(
240
            self.escape_like(path), escape='\\'))
240
            self.escape_like(path), escape=ESCAPE_CHAR))
241 241
        r = self.conn.execute(s)
242 242
        row = r.fetchone()
243 243
        r.close()
......
617 617
            c1 = select([self.nodes.c.serial],
618 618
                        self.nodes.c.node == v.c.node)
619 619
        c2 = select([self.nodes.c.node], self.nodes.c.path.like(
620
            self.escape_like(path) + '%', escape='\\'))
620
            self.escape_like(path) + '%', escape=ESCAPE_CHAR))
621 621
        s = s.where(and_(v.c.serial == c1,
622 622
                         v.c.cluster != except_cluster,
623 623
                         v.c.node.in_(c2)))
......
904 904
        for path, match in pathq:
905 905
            if match == MATCH_PREFIX:
906 906
                conj.append(
907
                    n.c.path.like(self.escape_like(path) + '%', escape='\\'))
907
                    n.c.path.like(
908
                        self.escape_like(path) + '%',
909
                        escape=ESCAPE_CHAR
910
                    )
911
                )
908 912
            elif match == MATCH_EXACT:
909 913
                conj.append(n.c.path == path)
910 914
        if conj:
......
999 1003
        for path, match in pathq:
1000 1004
            if match == MATCH_PREFIX:
1001 1005
                conj.append(
1002
                    n.c.path.like(self.escape_like(path) + '%', escape='\\'))
1006
                    n.c.path.like(
1007
                        self.escape_like(path) + '%',
1008
                        escape=ESCAPE_CHAR
1009
                    )
1010
                )
1003 1011
            elif match == MATCH_EXACT:
1004 1012
                conj.append(n.c.path == path)
1005 1013
        if conj:
b/snf-pithos-backend/pithos/backends/lib/sqlalchemy/permissions.py
38 38
from groups import Groups
39 39
from public import Public
40 40

  
41
from dbworker import ESCAPE_CHAR
42

  
41 43

  
42 44
READ = 0
43 45
WRITE = 1
......
172 174
        s = select([self.xfeatures.c.path], from_obj=[inner_join]).distinct()
173 175
        if prefix:
174 176
            s = s.where(self.xfeatures.c.path.like(
175
                self.escape_like(prefix) + '%', escape='\\'))
177
                self.escape_like(prefix) + '%', escape=ESCAPE_CHAR
178
            ))
176 179
        r = self.conn.execute(s)
177 180
        l = [row[0] for row in r.fetchall()]
178 181
        r.close()
......
182 185
        """Return the list of shared paths."""
183 186

  
184 187
        s = select([self.xfeatures.c.path],
185
                   self.xfeatures.c.path.like(self.escape_like(prefix) + '%', escape='\\')).order_by(self.xfeatures.c.path.asc())
188
                   self.xfeatures.c.path.like(self.escape_like(prefix) + '%',
189
                                              escape=ESCAPE_CHAR
190
                   )
191
        ).order_by(self.xfeatures.c.path.asc())
186 192
        r = self.conn.execute(s)
187 193
        l = [row[0] for row in r.fetchall()]
188 194
        r.close()
b/snf-pithos-backend/pithos/backends/lib/sqlalchemy/public.py
39 39

  
40 40
from pithos.backends.random_word import get_random_word
41 41

  
42
from dbworker import ESCAPE_CHAR
43

  
42 44
import logging
43 45

  
44 46
logger = logging.getLogger(__name__)
......
124 126
    def public_list(self, prefix):
125 127
        s = select([self.public.c.path, self.public.c.url])
126 128
        s = s.where(self.public.c.path.like(
127
            self.escape_like(prefix) + '%', escape='\\'))
129
            self.escape_like(prefix) + '%', escape=ESCAPE_CHAR))
128 130
        s = s.where(self.public.c.active == True)
129 131
        r = self.conn.execute(s)
130 132
        rows = r.fetchall()

Also available in: Unified diff