Author: phd
Date: 2009-09-20 10:25:09 -0600 (Sun, 20 Sep 2009)
New Revision: 3981
Modified:
SQLObject/branches/0.10/docs/News.txt
SQLObject/branches/0.10/sqlobject/sqlbuilder.py
SQLObject/branches/0.10/sqlobject/tests/test_select.py
Log:
Fixed a bug: q.startswith(), q.contains() and q.endswith() escape (with a
backslash) all special characters (backslashes, underscores and percent signs).
Modified: SQLObject/branches/0.10/docs/News.txt
===================================================================
--- SQLObject/branches/0.10/docs/News.txt 2009-09-20 15:53:02 UTC (rev 3980)
+++ SQLObject/branches/0.10/docs/News.txt 2009-09-20 16:25:09 UTC (rev 3981)
@@ -12,6 +12,10 @@
* Fixed a bug: Sybase tables with identity column fire two identity_inserts.
+* Fixed a bug: q.startswith(), q.contains() and q.endswith() escape (with a
+ backslash) all special characters (backslashes, underscores and percent
+ signs).
+
SQLObject 0.10.6
================
Modified: SQLObject/branches/0.10/sqlobject/sqlbuilder.py
===================================================================
--- SQLObject/branches/0.10/sqlobject/sqlbuilder.py 2009-09-20 15:53:02 UTC (rev 3980)
+++ SQLObject/branches/0.10/sqlobject/sqlbuilder.py 2009-09-20 16:25:09 UTC (rev 3981)
@@ -883,7 +883,7 @@
values = []
if self.prefix:
values.append("'%s'" % self.prefix)
- s = _quote_percent(sqlrepr(s, db), db)
+ s = _quote_like_special(sqlrepr(s, db), db)
values.append(s)
if self.postfix:
values.append("'%s'" % self.postfix)
@@ -892,16 +892,17 @@
else:
return " || ".join(values)
elif isinstance(s, basestring):
- s = _quote_percent(sqlrepr(s, db)[1:-1], db)
+ s = _quote_like_special(sqlrepr(s, db)[1:-1], db)
return "'%s%s%s'" % (self.prefix, s, self.postfix)
else:
raise TypeError, "expected str, unicode or SQLExpression, got %s" % type(s)
-def _quote_percent(s, db):
- if db in ('postgres', 'mysql'):
- s = s.replace('%', '\\%')
+def _quote_like_special(s, db):
+ if db == 'postgres':
+ escape = r'\\'
else:
- s = s.replace('%', '%%')
+ escape = '\\'
+ s = s.replace('\\', r'\\').replace('%', escape+'%').replace('_', escape+'_')
return s
########################################
@@ -1140,7 +1141,7 @@
if escape is None:
return "(%s)" % like
else:
- return "(%s ESCAPE '%s')" % (like, escape)
+ return "(%s ESCAPE %s)" % (like, sqlrepr(escape, db))
def components(self):
return [self.expr, self.string]
def execute(self, executor):
Modified: SQLObject/branches/0.10/sqlobject/tests/test_select.py
===================================================================
--- SQLObject/branches/0.10/sqlobject/tests/test_select.py 2009-09-20 15:53:02 UTC (rev 3980)
+++ SQLObject/branches/0.10/sqlobject/tests/test_select.py 2009-09-20 16:25:09 UTC (rev 3981)
@@ -69,14 +69,23 @@
assert len(list(IterTest.select(limit=2))) == 2
raises(AssertionError, IterTest.select(limit=2).count)
-def test_06_like():
+def test_06_contains():
setupIter()
assert len(list(IterTest.select(IterTest.q.name.startswith('a')))) == 1
- assert len(list(IterTest.select(IterTest.q.name.endswith('a')))) == 1
assert len(list(IterTest.select(IterTest.q.name.contains('a')))) == 1
assert len(list(IterTest.select(IterTest.q.name.contains(func.lower('A'))))) == 1
assert len(list(IterTest.select(IterTest.q.name.contains("a'b")))) == 0
+ assert len(list(IterTest.select(IterTest.q.name.endswith('a')))) == 1
+def test_07_contains_special():
+ setupClass(IterTest)
+ a = IterTest(name='\\test')
+ b = IterTest(name='100%')
+ c = IterTest(name='test_')
+ assert list(IterTest.select(IterTest.q.name.startswith('\\'))) == [a]
+ assert list(IterTest.select(IterTest.q.name.contains('%'))) == [b]
+ assert list(IterTest.select(IterTest.q.name.endswith('_'))) == [c]
+
def test_select_getOne():
setupClass(IterTest)
a = IterTest(name='a')
|