fix like behaviour
This commit is contained in:
+8
-7
@@ -1399,12 +1399,13 @@ class BaseAdapter(ConnectionPool):
|
|||||||
|
|
||||||
def LIKE(self, first, second):
|
def LIKE(self, first, second):
|
||||||
"""Case sensitive like operator"""
|
"""Case sensitive like operator"""
|
||||||
raise NotImplementedError
|
return '(%s LIKE %s)' % (self.expand(first),
|
||||||
|
self.expand(second, 'string'))
|
||||||
|
|
||||||
def ILIKE(self, first, second):
|
def ILIKE(self, first, second):
|
||||||
"""Case insensitive like operator"""
|
"""Case insensitive like operator"""
|
||||||
return '(%s LIKE %s)' % (self.expand(first),
|
return '(LOWER(%s) LIKE %s)' % (self.expand(first),
|
||||||
self.expand(second, 'string'))
|
self.expand(second, 'string').lower())
|
||||||
|
|
||||||
def STARTSWITH(self, first, second):
|
def STARTSWITH(self, first, second):
|
||||||
return '(%s LIKE %s)' % (self.expand(first),
|
return '(%s LIKE %s)' % (self.expand(first),
|
||||||
@@ -1414,7 +1415,7 @@ class BaseAdapter(ConnectionPool):
|
|||||||
return '(%s LIKE %s)' % (self.expand(first),
|
return '(%s LIKE %s)' % (self.expand(first),
|
||||||
self.expand('%'+second, 'string'))
|
self.expand('%'+second, 'string'))
|
||||||
|
|
||||||
def CONTAINS(self, first, second, case_sensitive=False):
|
def CONTAINS(self, first, second, case_sensitive=True):
|
||||||
if first.type in ('string', 'text', 'json'):
|
if first.type in ('string', 'text', 'json'):
|
||||||
if isinstance(second, Expression):
|
if isinstance(second, Expression):
|
||||||
second = Expression(None, self.CONCAT('%', Expression(
|
second = Expression(None, self.CONCAT('%', Expression(
|
||||||
@@ -2920,11 +2921,11 @@ class PostgreSQLAdapter(BaseAdapter):
|
|||||||
self.expand(second, 'string'))
|
self.expand(second, 'string'))
|
||||||
|
|
||||||
def STARTSWITH(self, first, second):
|
def STARTSWITH(self, first, second):
|
||||||
return '(%s ILIKE %s)' % (self.expand(first),
|
return '(%s LIKE %s)' % (self.expand(first),
|
||||||
self.expand(second+'%', 'string'))
|
self.expand(second+'%', 'string'))
|
||||||
|
|
||||||
def ENDSWITH(self, first, second):
|
def ENDSWITH(self, first, second):
|
||||||
return '(%s ILIKE %s)' % (self.expand(first),
|
return '(%s LIKE %s)' % (self.expand(first),
|
||||||
self.expand('%'+second, 'string'))
|
self.expand('%'+second, 'string'))
|
||||||
|
|
||||||
# GIS functions
|
# GIS functions
|
||||||
@@ -9735,7 +9736,7 @@ class Expression(object):
|
|||||||
db = self.db
|
db = self.db
|
||||||
return Query(db, db._adapter.GE, self, value)
|
return Query(db, db._adapter.GE, self, value)
|
||||||
|
|
||||||
def like(self, value, case_sensitive=False):
|
def like(self, value, case_sensitive=True):
|
||||||
db = self.db
|
db = self.db
|
||||||
op = case_sensitive and db._adapter.LIKE or db._adapter.ILIKE
|
op = case_sensitive and db._adapter.LIKE or db._adapter.ILIKE
|
||||||
return Query(db, op, self, value)
|
return Query(db, op, self, value)
|
||||||
|
|||||||
+29
-8
@@ -381,14 +381,35 @@ class TestLike(unittest.TestCase):
|
|||||||
self.assertEqual(db(db.tt.aa.like('%b%')).count(), 1)
|
self.assertEqual(db(db.tt.aa.like('%b%')).count(), 1)
|
||||||
self.assertEqual(db(db.tt.aa.like('%c')).count(), 1)
|
self.assertEqual(db(db.tt.aa.like('%c')).count(), 1)
|
||||||
self.assertEqual(db(db.tt.aa.like('%d%')).count(), 0)
|
self.assertEqual(db(db.tt.aa.like('%d%')).count(), 0)
|
||||||
self.assertEqual(db(db.tt.aa.lower().like('A%')).count(), 1)
|
#DAL maps like() (and contains(), startswith(), endswith())
|
||||||
self.assertEqual(db(db.tt.aa.lower().like('%B%')).count(),
|
#to the LIKE operator, that in ANSI-SQL is case-sensitive
|
||||||
1)
|
#There are backends supporting case-sensitivity by default
|
||||||
self.assertEqual(db(db.tt.aa.lower().like('%C')).count(), 1)
|
#and backends that needs additional care to turn
|
||||||
self.assertEqual(db(db.tt.aa.upper().like('A%')).count(), 1)
|
#case-sensitivity on. To discern among those, let's run
|
||||||
self.assertEqual(db(db.tt.aa.upper().like('%B%')).count(),
|
#this query comparing previously inserted 'abc' with 'ABC':
|
||||||
1)
|
#if the result is 0, then the backend recognizes
|
||||||
self.assertEqual(db(db.tt.aa.upper().like('%C')).count(), 1)
|
#case-sensitivity, if 1 it isn't
|
||||||
|
is_case_insensitive = db(db.tt.aa.like('%ABC%')).count()
|
||||||
|
if is_case_insensitive:
|
||||||
|
self.assertEqual(db(db.tt.aa.like('A%')).count(), 1)
|
||||||
|
self.assertEqual(db(db.tt.aa.like('%B%')).count(), 1)
|
||||||
|
self.assertEqual(db(db.tt.aa.like('%C')).count(), 1)
|
||||||
|
self.assertEqual(db(db.tt.aa.like('A%', case_sensitive=False)).count(), 1)
|
||||||
|
self.assertEqual(db(db.tt.aa.like('%B%', case_sensitive=False)).count(), 1)
|
||||||
|
self.assertEqual(db(db.tt.aa.like('%C', case_sensitive=False)).count(), 1)
|
||||||
|
self.assertEqual(db(db.tt.aa.upper().like('A%')).count(), 1)
|
||||||
|
self.assertEqual(db(db.tt.aa.upper().like('%B%')).count(),1)
|
||||||
|
self.assertEqual(db(db.tt.aa.upper().like('%C')).count(), 1)
|
||||||
|
else:
|
||||||
|
self.assertEqual(db(db.tt.aa.like('A%')).count(), 0)
|
||||||
|
self.assertEqual(db(db.tt.aa.like('%B%')).count(), 0)
|
||||||
|
self.assertEqual(db(db.tt.aa.like('%C')).count(), 0)
|
||||||
|
self.assertEqual(db(db.tt.aa.like('A%', case_sensitive=False)).count(), 1)
|
||||||
|
self.assertEqual(db(db.tt.aa.like('%B%', case_sensitive=False)).count(), 1)
|
||||||
|
self.assertEqual(db(db.tt.aa.like('%C', case_sensitive=False)).count(), 1)
|
||||||
|
self.assertEqual(db(db.tt.aa.upper().like('A%')).count(), 1)
|
||||||
|
self.assertEqual(db(db.tt.aa.upper().like('%B%')).count(),1)
|
||||||
|
self.assertEqual(db(db.tt.aa.upper().like('%C')).count(), 1)
|
||||||
db.tt.drop()
|
db.tt.drop()
|
||||||
db.define_table('tt', Field('aa', 'integer'))
|
db.define_table('tt', Field('aa', 'integer'))
|
||||||
self.assertEqual(db.tt.insert(aa=1111111111), 1)
|
self.assertEqual(db.tt.insert(aa=1111111111), 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user