summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/operators.py
diff options
context:
space:
mode:
authorDiana Clarke <diana.joan.clarke@gmail.com>2016-04-10 15:19:03 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2017-03-14 09:49:52 -0400
commit2895c57b29c500fe4388ef23e61f13c5e1e9b4b2 (patch)
tree25a323bc7b9d7a05b9845d338dabb91ba7c55985 /lib/sqlalchemy/sql/operators.py
parent7b07ea67dc4a578be977a9f618dfb12fd12e852e (diff)
downloadsqlalchemy-2895c57b29c500fe4388ef23e61f13c5e1e9b4b2.tar.gz
add autoescape option to startswith, endswith, and contains
Fixes: #2694 Change-Id: I34c0bdcb01c2b76b9ab6cd315dae13e3dd8a502b Pull-request: https://github.com/zzzeek/sqlalchemy/pull/207
Diffstat (limited to 'lib/sqlalchemy/sql/operators.py')
-rw-r--r--lib/sqlalchemy/sql/operators.py123
1 files changed, 110 insertions, 13 deletions
diff --git a/lib/sqlalchemy/sql/operators.py b/lib/sqlalchemy/sql/operators.py
index d88339299..1690d546b 100644
--- a/lib/sqlalchemy/sql/operators.py
+++ b/lib/sqlalchemy/sql/operators.py
@@ -196,7 +196,7 @@ class Operators(object):
class custom_op(object):
"""Represent a 'custom' operator.
- :class:`.custom_op` is normally instantitated when the
+ :class:`.custom_op` is normally instantiated when the
:meth:`.ColumnOperators.op` method is used to create a
custom operator callable. The class can also be used directly
when programmatically constructing expressions. E.g.
@@ -541,6 +541,31 @@ class ColumnOperators(Operators):
In a column context, produces the clause ``LIKE '<other>%'``
+ E.g.::
+
+ select([sometable]).where(sometable.c.column.startswith("foobar"))
+
+ :param other: expression to be compared, with SQL wildcard
+ matching (``%`` and ``_``) enabled, e.g.::
+
+ somecolumn.startswith("foo%bar")
+
+ :param escape: optional escape character, renders the ``ESCAPE``
+ keyword allowing that escape character to be used to manually
+ disable SQL wildcard matching (``%`` and ``_``) in the expression,
+ e.g.::
+
+ somecolumn.startswith("foo/%bar", escape="/")
+
+ :param autoescape: optional escape character, renders the ``ESCAPE``
+ keyword and uses that escape character to auto escape the
+ expression, disabling all SQL wildcard matching (``%`` and ``_``),
+ e.g.::
+
+ somecolumn.startswith("foo%bar", autoescape="/")
+
+ .. versionadded:: 1.2
+
"""
return self.operate(startswith_op, other, **kwargs)
@@ -549,6 +574,31 @@ class ColumnOperators(Operators):
In a column context, produces the clause ``LIKE '%<other>'``
+ E.g.::
+
+ select([sometable]).where(sometable.c.column.endswith("foobar"))
+
+ :param other: expression to be compared, with SQL wildcard
+ matching (``%`` and ``_``) enabled, e.g.::
+
+ somecolumn.endswith("foo%bar")
+
+ :param escape: optional escape character, renders the ``ESCAPE``
+ keyword allowing that escape character to be used to manually
+ disable SQL wildcard matching (``%`` and ``_``) in the expression,
+ e.g.::
+
+ somecolumn.endswith("foo/%bar", escape="/")
+
+ :param autoescape: optional escape character, renders the ``ESCAPE``
+ keyword and uses that escape character to auto escape the
+ expression, disabling all SQL wildcard matching (``%`` and ``_``),
+ e.g.::
+
+ somecolumn.endswith("foo%bar", autoescape="/")
+
+ .. versionadded:: 1.2
+
"""
return self.operate(endswith_op, other, **kwargs)
@@ -557,6 +607,31 @@ class ColumnOperators(Operators):
In a column context, produces the clause ``LIKE '%<other>%'``
+ E.g.::
+
+ select([sometable]).where(sometable.c.column.contains("foobar"))
+
+ :param other: expression to compare, with SQL wildcard
+ matching (``%`` and ``_``) enabled, e.g.::
+
+ somecolumn.contains("foo%bar")
+
+ :param escape: optional escape character, renders the ``ESCAPE``
+ keyword allowing that escape character to be used to manually
+ disable SQL wildcard matching (``%`` and ``_``) in the expression,
+ e.g.::
+
+ somecolumn.contains("foo/%bar", escape="/")
+
+ :param autoescape: optional escape character, renders the ``ESCAPE``
+ keyword and uses that escape character to auto escape the
+ expression, disabling all SQL wildcard matching (``%`` and ``_``),
+ e.g.::
+
+ somecolumn.contains("foo%bar", autoescape="/")
+
+ .. versionadded:: 1.2
+
"""
return self.operate(contains_op, other, **kwargs)
@@ -736,6 +811,10 @@ class ColumnOperators(Operators):
return self.reverse_operate(truediv, other)
+def _escaped(value, escape):
+ return value.replace('%', escape + '%').replace('_', escape + '_')
+
+
def from_():
raise NotImplementedError()
@@ -824,28 +903,46 @@ def all_op(a):
return a.all_()
-def startswith_op(a, b, escape=None):
- return a.startswith(b, escape=escape)
+def startswith_op(a, b, escape=None, autoescape=None):
+ if autoescape:
+ return a.startswith(_escaped(b, autoescape), escape=autoescape)
+ else:
+ return a.startswith(b, escape=escape)
-def notstartswith_op(a, b, escape=None):
- return ~a.startswith(b, escape=escape)
+def notstartswith_op(a, b, escape=None, autoescape=None):
+ if autoescape:
+ return ~a.startswith(_escaped(b, autoescape), escape=autoescape)
+ else:
+ return ~a.startswith(b, escape=escape)
-def endswith_op(a, b, escape=None):
- return a.endswith(b, escape=escape)
+def endswith_op(a, b, escape=None, autoescape=None):
+ if autoescape:
+ return a.endswith(_escaped(b, autoescape), escape=autoescape)
+ else:
+ return a.endswith(b, escape=escape)
-def notendswith_op(a, b, escape=None):
- return ~a.endswith(b, escape=escape)
+def notendswith_op(a, b, escape=None, autoescape=None):
+ if autoescape:
+ return ~a.endswith(_escaped(b, autoescape), escape=autoescape)
+ else:
+ return ~a.endswith(b, escape=escape)
-def contains_op(a, b, escape=None):
- return a.contains(b, escape=escape)
+def contains_op(a, b, escape=None, autoescape=None):
+ if autoescape:
+ return a.contains(_escaped(b, autoescape), escape=autoescape)
+ else:
+ return a.contains(b, escape=escape)
-def notcontains_op(a, b, escape=None):
- return ~a.contains(b, escape=escape)
+def notcontains_op(a, b, escape=None, autoescape=None):
+ if autoescape:
+ return ~a.contains(_escaped(b, autoescape), escape=autoescape)
+ else:
+ return ~a.contains(b, escape=escape)
def match_op(a, b, **kw):