[CalendarServer-changes] [6773] CalendarServer/branches/users/glyph/dal/txdav/base/datastore
source_changes at macosforge.org
source_changes at macosforge.org
Wed Jan 19 12:58:44 PST 2011
Revision: 6773
http://trac.macosforge.org/projects/calendarserver/changeset/6773
Author: glyph at apple.com
Date: 2011-01-19 12:58:44 -0800 (Wed, 19 Jan 2011)
Log Message:
-----------
">" and "<", "and" and "or".
Modified Paths:
--------------
CalendarServer/branches/users/glyph/dal/txdav/base/datastore/sqlsyntax.py
CalendarServer/branches/users/glyph/dal/txdav/base/datastore/test/test_sqlsyntax.py
Modified: CalendarServer/branches/users/glyph/dal/txdav/base/datastore/sqlsyntax.py
===================================================================
--- CalendarServer/branches/users/glyph/dal/txdav/base/datastore/sqlsyntax.py 2011-01-19 20:58:33 UTC (rev 6772)
+++ CalendarServer/branches/users/glyph/dal/txdav/base/datastore/sqlsyntax.py 2011-01-19 20:58:44 UTC (rev 6773)
@@ -15,6 +15,10 @@
# limitations under the License.
##
+"""
+Syntax wrappers and generators for SQL.
+"""
+
from txdav.base.datastore.sqlmodel import Schema, Table, Column
class Syntax(object):
@@ -73,7 +77,15 @@
yield ColumnSyntax(column)
+def comparison(comparator):
+ def __(self, other):
+ if isinstance(other, ColumnSyntax):
+ return ColumnComparison(self, comparator, other)
+ else:
+ return ConstantComparison(self, comparator, other)
+ return __
+
class ColumnSyntax(Syntax):
"""
Syntactic convenience for L{Column}.
@@ -81,11 +93,14 @@
modelType = Column
- def __eq__(self, other):
- if isinstance(other, ColumnSyntax):
- return ColumnComparison(self, '=', other)
- else:
- return ConstantComparison(self, '=', other)
+ __eq__ = comparison('=')
+ __ne__ = comparison('!=')
+ __gt__ = comparison('>')
+ __ge__ = comparison('>=')
+ __lt__ = comparison('<')
+ __le__ = comparison('<=')
+ __add__ = comparison("+")
+ __sub__ = comparison("-")
@@ -102,21 +117,49 @@
"column comparisons should not be tested for truth value")
+ def booleanOp(self, operand, other):
+ return CompoundComparison(self, operand, other)
+ def And(self, other):
+ return self.booleanOp('and', other)
+
+
+ def Or(self, other):
+ return self.booleanOp('or', other)
+
+
+
class ConstantComparison(Comparison):
def toSQL(self, placeholder, quote):
- return (' '.join([self.a.model.name, self.op, placeholder]), [self.b])
+ return SQLStatement(
+ ' '.join([self.a.model.name, self.op, placeholder]), [self.b])
class ColumnComparison(Comparison):
+
def toSQL(self, placeholder, quote):
- return (' '.join([self.a.model.name, self.op, self.b.model.name]), [])
+ return SQLStatement(
+ ' '.join([self.a.model.name, self.op, self.b.model.name]), [])
+class CompoundComparison(Comparison):
+ """
+ A compound comparison; two or more constraints, joined by an operation
+ (currently only AND or OR).
+ """
+ def toSQL(self, placeholder, quote):
+ stmt = SQLStatement()
+ stmt.append(self.a.toSQL(placeholder, quote))
+ stmt.text += ' %s ' % (self.op,)
+ stmt.append(self.b.toSQL(placeholder, quote))
+ return stmt
+
+
+
class Select(object):
"""
'select' statement.
@@ -131,11 +174,39 @@
"""
@return: a 2-tuple of (sql, args).
"""
- sql = quote("select * from ") + self.From.model.name
- args = []
+ stmt = SQLStatement(quote("select * from ") + self.From.model.name)
if self.Where is not None:
- moreSQL, moreArgs = self.Where.toSQL(placeholder, quote)
- sql += (quote(" where ") + moreSQL)
- args.extend(moreArgs)
- return (sql, args)
+ wherestmt = self.Where.toSQL(placeholder, quote)
+ stmt.text += quote(" where ")
+ stmt.append(wherestmt)
+ return stmt
+
+class SQLStatement(object):
+ """
+ Combination of SQL text and arguments; a statement which may be executed
+ against a database.
+ """
+
+ def __init__(self, text="", parameters=None):
+ self.text = text
+ if parameters is None:
+ parameters = []
+ self.parameters = parameters
+
+
+ def append(self, anotherStatement):
+ self.text += anotherStatement.text
+ self.parameters += anotherStatement.parameters
+
+
+ def __eq__(self, stmt):
+ if not isinstance(stmt, SQLStatement):
+ return NotImplemented
+ return (self.text, self.parameters) == (stmt.text, stmt.parameters)
+
+
+ def __ne__(self, stmt):
+ if not isinstance(stmt, SQLStatement):
+ return NotImplemented
+ return not self.__eq__(stmt)
Modified: CalendarServer/branches/users/glyph/dal/txdav/base/datastore/test/test_sqlsyntax.py
===================================================================
--- CalendarServer/branches/users/glyph/dal/txdav/base/datastore/test/test_sqlsyntax.py 2011-01-19 20:58:33 UTC (rev 6772)
+++ CalendarServer/branches/users/glyph/dal/txdav/base/datastore/test/test_sqlsyntax.py 2011-01-19 20:58:44 UTC (rev 6773)
@@ -17,7 +17,7 @@
from txdav.base.datastore.sqlmodel import Schema
from txdav.base.datastore.sqlparser import addSQLToSchema
-from txdav.base.datastore.sqlsyntax import SchemaSyntax, Select
+from txdav.base.datastore.sqlsyntax import SchemaSyntax, Select, SQLStatement
from twisted.trial.unittest import TestCase
@@ -41,7 +41,7 @@
rows in a table.
"""
self.assertEquals(Select(From=self.schema.FOO).toSQL(),
- ("select * from FOO", []))
+ SQLStatement("select * from FOO", []))
def test_simpleWhereClause(self):
@@ -51,7 +51,7 @@
"""
self.assertEquals(Select(From=self.schema.FOO,
Where=self.schema.FOO.BAR == 1).toSQL(),
- ("select * from FOO where BAR = ?", [1]))
+ SQLStatement("select * from FOO where BAR = ?", [1]))
def test_quotingAndPlaceholder(self):
@@ -63,7 +63,7 @@
Where=self.schema.FOO.BAR == 1).toSQL(
placeholder="*",
quote=lambda partial: partial.replace("*", "**")),
- ("select ** from FOO where BAR = *", [1]))
+ SQLStatement("select ** from FOO where BAR = *", [1]))
def test_columnComparison(self):
@@ -73,7 +73,7 @@
self.assertEquals(Select(From=self.schema.FOO,
Where=self.schema.FOO.BAR ==
self.schema.FOO.BAZ).toSQL(),
- ("select * from FOO where BAR = BAZ", []))
+ SQLStatement("select * from FOO where BAR = BAZ", []))
def test_comparisonTestErrorPrevention(self):
@@ -88,3 +88,15 @@
self.assertRaises(ValueError, sampleComparison)
+
+ def test_compoundWhere(self):
+ """
+ L{Select.And} and L{Select.Or} will return compound columns.
+ """
+ self.assertEquals(
+ Select(From=self.schema.FOO,
+ Where=(self.schema.FOO.BAR < 2).Or(
+ self.schema.FOO.BAR > 5)).toSQL(),
+ SQLStatement("select * from FOO where BAR < ? or BAR > ?", [2, 5]))
+
+
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110119/7597a77f/attachment-0001.html>
More information about the calendarserver-changes
mailing list