From 6b9d7af4ed353f7e4272a9533ddb1e72d15cc1f1 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Mon, 4 Feb 2013 09:55:21 -0600 Subject: [PATCH] passing parameters for contains case_sensitive but often ignored. :-( --- VERSION | 2 +- gluon/dal.py | 43 +++++++++++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/VERSION b/VERSION index 012b9c25..dc95465d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.4.1-alpha.2+timestamp.2013.02.04.09.37.03 +Version 2.4.1-alpha.2+timestamp.2013.02.04.09.54.44 diff --git a/gluon/dal.py b/gluon/dal.py index 0d94769d..fd987234 100644 --- a/gluon/dal.py +++ b/gluon/dal.py @@ -1233,9 +1233,9 @@ class BaseAdapter(ConnectionPool): return '(%s LIKE %s)' % (self.expand(first), self.expand('%'+second, 'string')) - def CONTAINS(self, first, second): - field = self.expand(first) + def CONTAINS(self, first, second, case_sensitive=False): if isinstance(second,Expression): + field = self.expand(first) expr = self.expand(second,'string') if first.type.startswith('list:'): expr = 'CONCAT("|", %s, "|")' % expr @@ -1249,7 +1249,8 @@ class BaseAdapter(ConnectionPool): key = '%|'+str(second).replace('|','||').replace('%','%%')+'|%' else: raise RuntimeError("Expression Not Supported") - return '(%s LIKE %s)' % (field,self.expand(key,'string')) + op = case_sensitive and self.LIKE or self.ILIKE + return op(first,key) def EQ(self, first, second=None): if second is None: @@ -2627,12 +2628,13 @@ class PostgreSQLAdapter(BaseAdapter): return '(%s ILIKE %s)' % (self.expand(first), self.expand('%'+second,'string')) - def CONTAINS(self,first,second): + def CONTAINS(self,first,second,case_sensitive=False): if first.type in ('string','text', 'json'): key = '%'+str(second).replace('%','%%')+'%' elif first.type.startswith('list:'): key = '%|'+str(second).replace('|','||').replace('%','%%')+'|%' - return '(%s ILIKE %s)' % (self.expand(first),self.expand(key,'string')) + op = case_sensitive and self.LIKE or self.ILIKE + return op(first,key) # GIS functions @@ -3406,13 +3408,17 @@ class FireBirdAdapter(BaseAdapter): def SUBSTRING(self,field,parameters): return 'SUBSTRING(%s from %s for %s)' % (self.expand(field), parameters[0], parameters[1]) - def CONTAINS(self, first, second): + def CONTAINING(self,first,second): + "case in-sensitive like operator" + return '(%s CONTAINING %s)' % (self.expand(first), + self.expand(second, 'string')) + + def CONTAINS(self, first, second, case_sensitive=False): if first.type in ('string','text'): key = str(second).replace('%','%%') elif first.type.startswith('list:'): key = '|'+str(second).replace('|','||').replace('%','%%')+'|' - return '(%s CONTAINING %s)' % (self.expand(first), - self.expand(key,'string')) + return self.CONTAINING(first,second) def _drop(self,table,mode): sequence_name = table._sequence_name @@ -4572,7 +4578,8 @@ class GoogleDatastoreAdapter(NoSQLAdapter): second = [Key.from_path(first._tablename, int(i)) for i in second] return [GAEF(first.name,'in',second,lambda a,b:a in b)] - def CONTAINS(self,first,second): + def CONTAINS(self,first,second,case_sensitive=False): + # silently ignoring: GAE can only do case sensitive matches! if not first.type.startswith('list:'): raise SyntaxError("Not supported") return [GAEF(first.name,'=',self.expand(second,first.type[5:]),lambda a,b:b in a)] @@ -5525,8 +5532,9 @@ class MongoDBAdapter(NoSQLAdapter): return {self.expand(first): ('/%s^/' % \ self.expand(second, 'string'))} - def CONTAINS(self, first, second): - #There is a technical difference, but mongodb doesn't support + def CONTAINS(self, first, second, case_sensitive=False): + # silently ignore, only case sensitive + # There is a technical difference, but mongodb doesn't support # that, but the result will be the same return {self.expand(first) : ('/%s/' % \ self.expand(second, 'string'))} @@ -5556,7 +5564,8 @@ class MongoDBAdapter(NoSQLAdapter): re.escape(self.expand(second, 'string')) + '$'}} #TODO verify full compatibilty with official oracle contains operator - def CONTAINS(self, first, second): + def CONTAINS(self, first, second, case_sensitive=False): + # silently ignore, only case sensitive #There is a technical difference, but mongodb doesn't support # that, but the result will be the same #TODO contains operators need to be transformed to Regex @@ -6346,7 +6355,8 @@ class IMAPAdapter(NoSQLAdapter): # result = "(%s %s)" % (self.expand(first), self.expand(second)) return result - def CONTAINS(self, first, second): + def CONTAINS(self, first, second, case_sensitive=False): + # silently ignore, only case sensitive result = None name = self.search_fields[first.name] @@ -8764,17 +8774,18 @@ class Expression(object): raise SyntaxError("endswith used with incompatible field type") return Query(db, db._adapter.ENDSWITH, self, value) - def contains(self, value, all=False): + def contains(self, value, all=False, case_sensitive=False): db = self.db if isinstance(value,(list, tuple)): - subqueries = [self.contains(str(v).strip()) for v in value if str(v).strip()] + subqueries = [self.contains(str(v).strip(),case_sensitive=case_sensitive) + for v in value if str(v).strip()] if not subqueries: return self.contains('') else: return reduce(all and AND or OR,subqueries) if not self.type in ('string', 'text', 'json') and not self.type.startswith('list:'): raise SyntaxError("contains used with incompatible field type") - return Query(db, db._adapter.CONTAINS, self, value) + return Query(db, db._adapter.CONTAINS, self, value, case_sensitive=case_sensitive) def with_alias(self, alias): db = self.db