summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2007-08-07 17:12:35 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2007-08-07 17:12:35 +0000
commitc7ee47e545316272ff0864e46c5afbd338df9cb1 (patch)
tree81d93dff2b8ffea77f4af9b7d0d13959c8f263b1
parent2babbe7843ac2d15ce415b6b604144f5d0d30359 (diff)
downloadsqlalchemy-c7ee47e545316272ff0864e46c5afbd338df9cb1.tar.gz
- migrated 'desc', 'asc', and 'distinct' to be in the Operators framework
- fixes to operator() method signature/calling
-rw-r--r--lib/sqlalchemy/ansisql.py6
-rw-r--r--lib/sqlalchemy/orm/attributes.py4
-rw-r--r--lib/sqlalchemy/orm/interfaces.py6
-rw-r--r--lib/sqlalchemy/orm/properties.py4
-rw-r--r--lib/sqlalchemy/sql.py40
-rw-r--r--test/orm/eager_relations.py4
-rw-r--r--test/sql/select.py8
7 files changed, 50 insertions, 22 deletions
diff --git a/lib/sqlalchemy/ansisql.py b/lib/sqlalchemy/ansisql.py
index 13e2c985d..ce3830db8 100644
--- a/lib/sqlalchemy/ansisql.py
+++ b/lib/sqlalchemy/ansisql.py
@@ -60,6 +60,7 @@ OPERATORS = {
operator.gt : '>',
operator.ge : '>=',
operator.eq : '=',
+ sql.ColumnOperators.distinct_op : 'DISTINCT',
sql.ColumnOperators.concat_op : '||',
sql.ColumnOperators.like_op : 'LIKE',
sql.ColumnOperators.notlike_op : 'NOT LIKE',
@@ -69,6 +70,9 @@ OPERATORS = {
sql.ColumnOperators.in_op : 'IN',
sql.ColumnOperators.notin_op : 'NOT IN',
sql.ColumnOperators.comma_op : ', ',
+ sql.ColumnOperators.desc_op : 'DESC',
+ sql.ColumnOperators.asc_op : 'ASC',
+
sql.Operators.from_ : 'FROM',
sql.Operators.as_ : 'AS',
sql.Operators.exists : 'EXISTS',
@@ -392,7 +396,7 @@ class ANSICompiler(engine.Compiled, sql.ClauseVisitor):
if unary.operator:
s = self.operator_string(unary.operator) + " " + s
if unary.modifier:
- s = s + " " + unary.modifier
+ s = s + " " + self.operator_string(unary.modifier)
return s
def visit_binary(self, binary, **kwargs):
diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py
index acff87332..6218371e0 100644
--- a/lib/sqlalchemy/orm/attributes.py
+++ b/lib/sqlalchemy/orm/attributes.py
@@ -98,8 +98,8 @@ class InstrumentedAttribute(interfaces.PropComparator):
def expression_element(self):
return self.comparator.expression_element()
- def operate(self, op, other, **kwargs):
- return op(self.comparator, other, **kwargs)
+ def operate(self, op, *other, **kwargs):
+ return op(self.comparator, *other, **kwargs)
def reverse_operate(self, op, other, **kwargs):
return op(other, self.comparator, **kwargs)
diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py
index 775892da1..abaeff49c 100644
--- a/lib/sqlalchemy/orm/interfaces.py
+++ b/lib/sqlalchemy/orm/interfaces.py
@@ -369,12 +369,6 @@ class PropComparator(sql.ColumnOperators):
def expression_element(self):
return self.clause_element()
- def desc(self):
- return self.clause_element().desc()
-
- def asc(self):
- return self.clause_element().desc()
-
def contains_op(a, b):
return a.contains(b)
contains_op = staticmethod(contains_op)
diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py
index 0a47c0256..670fcccc9 100644
--- a/lib/sqlalchemy/orm/properties.py
+++ b/lib/sqlalchemy/orm/properties.py
@@ -70,8 +70,8 @@ class ColumnProperty(StrategizedProperty):
def clause_element(self):
return self.prop.columns[0]
- def operate(self, op, other):
- return op(self.prop.columns[0], other)
+ def operate(self, op, *other):
+ return op(self.prop.columns[0], *other)
def reverse_operate(self, op, other):
col = self.prop.columns[0]
diff --git a/lib/sqlalchemy/sql.py b/lib/sqlalchemy/sql.py
index 06802cf6f..bc255c5af 100644
--- a/lib/sqlalchemy/sql.py
+++ b/lib/sqlalchemy/sql.py
@@ -47,7 +47,7 @@ def desc(column):
order_by = [desc(table1.mycol)]
"""
- return _UnaryExpression(column, modifier="DESC")
+ return _UnaryExpression(column, modifier=ColumnOperators.desc_op)
def asc(column):
"""Return an ascending ``ORDER BY`` clause element.
@@ -56,7 +56,7 @@ def asc(column):
order_by = [asc(table1.mycol)]
"""
- return _UnaryExpression(column, modifier="ASC")
+ return _UnaryExpression(column, modifier=ColumnOperators.asc_op)
def outerjoin(left, right, onclause=None, **kwargs):
"""Return an ``OUTER JOIN`` clause element.
@@ -362,7 +362,7 @@ def not_(clause):
def distinct(expr):
"""return a ``DISTINCT`` clause."""
- return _UnaryExpression(expr, operator="DISTINCT")
+ return _UnaryExpression(expr, operator=ColumnOperators.distinct_op)
def between(ctest, cleft, cright):
"""Return a ``BETWEEN`` predicate clause.
@@ -1196,7 +1196,7 @@ class Operators(object):
def operate(self, op, *other, **kwargs):
raise NotImplementedError()
- def reverse_operate(self, op, *other, **kwargs):
+ def reverse_operate(self, op, other, **kwargs):
raise NotImplementedError()
class ColumnOperators(Operators):
@@ -1230,6 +1230,10 @@ class ColumnOperators(Operators):
raise NotImplementedError()
notin_op = staticmethod(notin_op)
+ def distinct_op(a):
+ return a.distinct()
+ distinct_op = staticmethod(distinct_op)
+
def startswith_op(a, b):
return a.startswith(b)
startswith_op = staticmethod(startswith_op)
@@ -1246,6 +1250,14 @@ class ColumnOperators(Operators):
return a.concat(b)
concat_op = staticmethod(concat_op)
+ def desc_op(a):
+ return a.desc()
+ desc_op = staticmethod(desc_op)
+
+ def asc_op(a):
+ return a.asc()
+ asc_op = staticmethod(asc_op)
+
def __lt__(self, other):
return self.operate(operator.lt, other)
@@ -1278,7 +1290,13 @@ class ColumnOperators(Operators):
def endswith(self, other):
return self.operate(ColumnOperators.endswith_op, other)
-
+
+ def desc(self):
+ return self.operate(ColumnOperators.desc_op)
+
+ def asc(self):
+ return self.operate(ColumnOperators.asc_op)
+
def __radd__(self, other):
return self.reverse_operate(operator.add, other)
@@ -1292,8 +1310,11 @@ class ColumnOperators(Operators):
return self.reverse_operate(operator.div, other)
def between(self, cleft, cright):
- return self.operate(Operators.between_op, (cleft, cright))
+ return self.operate(ColumnOperators.between_op, cleft, cright)
+ def distinct(self):
+ return self.operate(ColumnOperators.distinct_op)
+
def __add__(self, other):
return self.operate(operator.add, other)
@@ -1340,6 +1361,7 @@ PRECEDENCE = {
operator.ge:5,
operator.le:5,
ColumnOperators.between_op:5,
+ ColumnOperators.distinct_op:5,
operator.inv:4,
operator.and_:3,
operator.or_:2,
@@ -1394,9 +1416,9 @@ class _CompareMixin(ColumnOperators):
ColumnOperators.like_op : (__compare, ColumnOperators.notlike_op),
}
- def operate(self, op, other):
+ def operate(self, op, *other):
o = _CompareMixin.operators[op]
- return o[0](self, op, other, *o[1:])
+ return o[0](self, op, other[0], *o[1:])
def reverse_operate(self, op, other):
return self._bind_param(other).operate(op, self)
@@ -1456,7 +1478,7 @@ class _CompareMixin(ColumnOperators):
def distinct(self):
"""produce a DISTINCT clause, i.e. ``DISTINCT <columnname>``"""
- return _UnaryExpression(self, operator="DISTINCT")
+ return _UnaryExpression(self, operator=ColumnOperators.distinct_op)
def between(self, cleft, cright):
"""produce a BETWEEN clause, i.e. ``<column> BETWEEN <cleft> AND <cright>``"""
diff --git a/test/orm/eager_relations.py b/test/orm/eager_relations.py
index d94332c09..dffc5322c 100644
--- a/test/orm/eager_relations.py
+++ b/test/orm/eager_relations.py
@@ -299,7 +299,7 @@ class EagerTest(QueryTest):
q = sess.query(User)
if testbase.db.engine.name != 'mssql':
- l = q.join('orders').order_by(desc(Order.user_id)).limit(2).offset(1)
+ l = q.join('orders').order_by(Order.user_id.desc()).limit(2).offset(1)
assert [
User(id=9,
orders=[Order(id=2), Order(id=4)],
@@ -311,7 +311,7 @@ class EagerTest(QueryTest):
)
] == l.all()
- l = q.join('addresses').order_by(desc(Address.email_address)).limit(1).offset(0)
+ l = q.join('addresses').order_by(Address.email_address.desc()).limit(1).offset(0)
assert [
User(id=7,
orders=[Order(id=1), Order(id=3), Order(id=5)],
diff --git a/test/sql/select.py b/test/sql/select.py
index 2e099b01a..0edaab071 100644
--- a/test/sql/select.py
+++ b/test/sql/select.py
@@ -314,6 +314,14 @@ sq.myothertable_othername AS sq_myothertable_othername FROM (" + sqstring + ") A
self.runtest(
select([table1.c.myid]).distinct(), "SELECT DISTINCT mytable.myid FROM mytable"
)
+
+ self.runtest(
+ select([func.count(table1.c.myid.distinct())]), "SELECT count(DISTINCT mytable.myid) FROM mytable"
+ )
+
+ self.runtest(
+ select([func.count(distinct(table1.c.myid))]), "SELECT count(DISTINCT mytable.myid) FROM mytable"
+ )
def testoperators(self):