[CalendarServer-changes] [6886] CalendarServer/trunk/twext/enterprise/dal
source_changes at macosforge.org
source_changes at macosforge.org
Fri Feb 4 17:14:12 PST 2011
Revision: 6886
http://trac.macosforge.org/projects/calendarserver/changeset/6886
Author: glyph at apple.com
Date: 2011-02-04 17:14:09 -0800 (Fri, 04 Feb 2011)
Log Message:
-----------
Expressions involving aggregates
Modified Paths:
--------------
CalendarServer/trunk/twext/enterprise/dal/syntax.py
CalendarServer/trunk/twext/enterprise/dal/test/test_sqlsyntax.py
Modified: CalendarServer/trunk/twext/enterprise/dal/syntax.py
===================================================================
--- CalendarServer/trunk/twext/enterprise/dal/syntax.py 2011-02-05 00:36:03 UTC (rev 6885)
+++ CalendarServer/trunk/twext/enterprise/dal/syntax.py 2011-02-05 01:14:09 UTC (rev 6886)
@@ -82,12 +82,46 @@
-class FunctionInvocation(object):
+def comparison(comparator):
+ def __(self, other):
+ if other is None:
+ return NullComparison(self, comparator)
+ if isinstance(other, ColumnSyntax):
+ return ColumnComparison(self, comparator, other)
+ else:
+ return ConstantComparison(self, comparator, other)
+ return __
+
+
+
+class ExpressionSyntax(Syntax):
+ __eq__ = comparison('=')
+ __ne__ = comparison('!=')
+ __gt__ = comparison('>')
+ __ge__ = comparison('>=')
+ __lt__ = comparison('<')
+ __le__ = comparison('<=')
+ __add__ = comparison("+")
+ __sub__ = comparison("-")
+
+
+ def In(self, subselect):
+ # Can't be Select.__contains__ because __contains__ gets __nonzero__
+ # called on its result by the 'in' syntax.
+ return CompoundComparison(self, 'in', subselect)
+
+
+
+class FunctionInvocation(ExpressionSyntax):
def __init__(self, name, arg):
self.name = name
self.arg = arg
+ def allColumns(self):
+ return self.arg.allColumns()
+
+
def subSQL(self, placeholder, quote, allTables):
result = SQLFragment(self.name)
result.text += "("
@@ -217,35 +251,18 @@
-def comparison(comparator):
- def __(self, other):
- if other is None:
- return NullComparison(self, comparator)
- if isinstance(other, ColumnSyntax):
- return ColumnComparison(self, comparator, other)
- else:
- return ConstantComparison(self, comparator, other)
- return __
-
-
-
-class ColumnSyntax(Syntax):
+class ColumnSyntax(ExpressionSyntax):
"""
Syntactic convenience for L{Column}.
"""
modelType = Column
- __eq__ = comparison('=')
- __ne__ = comparison('!=')
- __gt__ = comparison('>')
- __ge__ = comparison('>=')
- __lt__ = comparison('<')
- __le__ = comparison('<=')
- __add__ = comparison("+")
- __sub__ = comparison("-")
+ def allColumns(self):
+ return [self]
+
def subSQL(self, placeholder, quote, allTables):
# XXX This, and 'model', could in principle conflict with column names.
# Maybe do something about that.
@@ -258,13 +275,7 @@
return SQLFragment(self.model.name)
- def In(self, subselect):
- # Can't be Select.__contains__ because __contains__ gets __nonzero__
- # called on its result by the 'in' syntax.
- return CompoundComparison(self, 'in', subselect)
-
-
class Comparison(object):
def __init__(self, a, op, b):
@@ -310,8 +321,13 @@
return sqls
+
class ConstantComparison(Comparison):
+ def allColumns(self):
+ return [self.a]
+
+
def subSQL(self, placeholder, quote, allTables):
sqls = SQLFragment()
sqls.append(self.a.subSQL(placeholder, quote, allTables))
@@ -372,6 +388,18 @@
+def _columnsMatchTables(columns, tables):
+ for expression in columns:
+ for column in expression.allColumns():
+ for table in tables:
+ if column in table:
+ break
+ else:
+ return False
+ return True
+
+
+
class Select(_Statement):
"""
'select' statement.
@@ -387,12 +415,9 @@
if columns is None:
columns = ALL_COLUMNS
else:
- for column in columns:
- for table in From.tables():
- if column in table:
- break
- else:
- raise TableMismatch()
+ if not _columnsMatchTables(columns, From.tables()):
+ raise TableMismatch()
+
columns = _SomeColumns(columns)
self.columns = columns
Modified: CalendarServer/trunk/twext/enterprise/dal/test/test_sqlsyntax.py
===================================================================
--- CalendarServer/trunk/twext/enterprise/dal/test/test_sqlsyntax.py 2011-02-05 00:36:03 UTC (rev 6885)
+++ CalendarServer/trunk/twext/enterprise/dal/test/test_sqlsyntax.py 2011-02-05 01:14:09 UTC (rev 6886)
@@ -274,7 +274,8 @@
def test_max(self):
"""
- Test for the 'Max' function.
+ L{Max}C{(column)} produces an object in the 'columns' clause that
+ renders the 'max' aggregate in SQL.
"""
self.assertEquals(
Select([Max(self.schema.BOZ.QUX)], From=self.schema.BOZ).toSQL(),
@@ -282,6 +283,16 @@
"select max(QUX) from BOZ"))
+ def test_aggregateComparison(self):
+ """
+ L{Max}C{(column) > constant} produces an object in the 'columns' clause
+ that renders a comparison to the 'max' aggregate in SQL.
+ """
+ self.assertEquals(Select([Max(self.schema.BOZ.QUX) + 12],
+ From=self.schema.BOZ).toSQL(),
+ SQLFragment("select max(QUX) + ? from BOZ", [12]))
+
+
def test_len(self):
"""
Test for the 'Len' function for determining character length of a
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110204/47e0e0fd/attachment-0001.html>
More information about the calendarserver-changes
mailing list