[CalendarServer-changes] [14448] twext/branches/users/cdaboo/pod2pod-migration/twext/enterprise/dal

source_changes at macosforge.org source_changes at macosforge.org
Thu Feb 19 13:40:25 PST 2015


Revision: 14448
          http://trac.calendarserver.org//changeset/14448
Author:   cdaboo at apple.com
Date:     2015-02-19 13:40:25 -0800 (Thu, 19 Feb 2015)
Log Message:
-----------
Record tweaks to support return cols on Delete and Distinct with Select. Allow some list/tuple/set types to be used directly in an In() or NotIn() query expression.

Modified Paths:
--------------
    twext/branches/users/cdaboo/pod2pod-migration/twext/enterprise/dal/record.py
    twext/branches/users/cdaboo/pod2pod-migration/twext/enterprise/dal/syntax.py
    twext/branches/users/cdaboo/pod2pod-migration/twext/enterprise/dal/test/test_sqlsyntax.py

Modified: twext/branches/users/cdaboo/pod2pod-migration/twext/enterprise/dal/record.py
===================================================================
--- twext/branches/users/cdaboo/pod2pod-migration/twext/enterprise/dal/record.py	2015-02-19 20:18:20 UTC (rev 14447)
+++ twext/branches/users/cdaboo/pod2pod-migration/twext/enterprise/dal/record.py	2015-02-19 21:40:25 UTC (rev 14448)
@@ -472,7 +472,7 @@
 
 
     @classmethod
-    def query(cls, transaction, expr, order=None, ascending=True, group=None, forUpdate=False, noWait=False, limit=None):
+    def query(cls, transaction, expr, order=None, group=None, limit=None, forUpdate=False, noWait=False, ascending=True, distinct=False):
         """
         Query the table that corresponds to C{cls}, and return instances of
         C{cls} corresponding to the rows that are returned from that table.
@@ -501,18 +501,19 @@
             cls.queryExpr(
                 expr,
                 order=order,
-                ascending=ascending,
                 group=group,
+                limit=limit,
                 forUpdate=forUpdate,
                 noWait=noWait,
-                limit=limit,
+                ascending=ascending,
+                distinct=distinct,
             ),
             None
         )
 
 
     @classmethod
-    def queryExpr(cls, expr, attributes=None, order=None, ascending=True, group=None, forUpdate=False, noWait=False, limit=None):
+    def queryExpr(cls, expr, attributes=None, order=None, group=None, limit=None, forUpdate=False, noWait=False, ascending=True, distinct=False):
         """
         Query expression that corresponds to C{cls}. Used in cases where a sub-select
         on this record's table is needed.
@@ -541,12 +542,14 @@
             kw.update(OrderBy=order, Ascending=ascending)
         if group is not None:
             kw.update(GroupBy=group)
+        if limit is not None:
+            kw.update(Limit=limit)
         if forUpdate:
             kw.update(ForUpdate=True)
             if noWait:
                 kw.update(NoWait=True)
-        if limit is not None:
-            kw.update(Limit=limit)
+        if distinct:
+            kw.update(Distinct=True)
         if attributes is None:
             attributes = list(cls.table)
         return Select(
@@ -599,13 +602,14 @@
 
 
     @classmethod
-    def deletesome(cls, transaction, where):
+    def deletesome(cls, transaction, where, returnCols=None):
         """
         Delete all rows matching the where expression from the table that corresponds to C{cls}.
         """
         return Delete(
             From=cls.table,
             Where=where,
+            Return=returnCols,
         ).on(transaction)
 
 

Modified: twext/branches/users/cdaboo/pod2pod-migration/twext/enterprise/dal/syntax.py
===================================================================
--- twext/branches/users/cdaboo/pod2pod-migration/twext/enterprise/dal/syntax.py	2015-02-19 20:18:20 UTC (rev 14447)
+++ twext/branches/users/cdaboo/pod2pod-migration/twext/enterprise/dal/syntax.py	2015-02-19 21:40:25 UTC (rev 14448)
@@ -439,6 +439,8 @@
                     "{} expression needs an explicit count of parameters".format(op.upper())
                 )
             return CompoundComparison(self, op, Constant(other))
+        elif isinstance(other, set) or isinstance(other, frozenset) or isinstance(other, list) or isinstance(other, tuple):
+            return CompoundComparison(self, op, Constant(other))
         else:
             # Can't be Select.__contains__ because __contains__ gets
             # __nonzero__ called on its result by the "in" syntax.
@@ -548,6 +550,13 @@
                     for counter in range(self.value.count)
                 ]).subSQL(queryGenerator, allTables)
             )
+        elif isinstance(self.value, set) or isinstance(self.value, frozenset) or isinstance(self.value, list) or isinstance(self.value, tuple):
+            return _inParens(
+                _CommaList([
+                    SQLFragment(queryGenerator.placeholder.placeholder(), [value])
+                    for value in self.value
+                ]).subSQL(queryGenerator, allTables)
+            )
         else:
             return SQLFragment(
                 queryGenerator.placeholder.placeholder(), [self.value]

Modified: twext/branches/users/cdaboo/pod2pod-migration/twext/enterprise/dal/test/test_sqlsyntax.py
===================================================================
--- twext/branches/users/cdaboo/pod2pod-migration/twext/enterprise/dal/test/test_sqlsyntax.py	2015-02-19 20:18:20 UTC (rev 14447)
+++ twext/branches/users/cdaboo/pod2pod-migration/twext/enterprise/dal/test/test_sqlsyntax.py	2015-02-19 21:40:25 UTC (rev 14448)
@@ -1006,6 +1006,90 @@
         )
 
 
+    def test_inIterable(self):
+        """
+        L{ColumnSyntax.In} returns a sub-expression using the SQL C{in} syntax
+        with parameter list.
+        """
+        # One item with IN only
+        items = set(("A",))
+        for items in (set(items), list(items), tuple(items),):
+            self.assertEquals(
+                Select(
+                    From=self.schema.FOO,
+                    Where=self.schema.FOO.BAR.In(items),
+                ).toSQL().bind(),
+                SQLFragment("select * from FOO where BAR in (?)", ["A"])
+            )
+
+        # Two items with IN only
+        items = set(("A", "B"))
+        for items in (set(items), list(items), tuple(items),):
+            self.assertEquals(
+                Select(
+                    From=self.schema.FOO,
+                    Where=self.schema.FOO.BAR.In(items),
+                ).toSQL().bind(names=items),
+                SQLFragment(
+                    "select * from FOO where BAR in (?, ?)", ["A", "B"]
+                )
+            )
+
+            # Two items with preceding AND
+            self.assertEquals(
+                Select(
+                    From=self.schema.FOO,
+                    Where=(
+                        (
+                            self.schema.FOO.BAZ == Parameter("P1")
+                        ).And(
+                            self.schema.FOO.BAR.In(items)
+                        )
+                    )
+                ).toSQL().bind(P1="P1"),
+                SQLFragment(
+                    "select * from FOO where BAZ = ? and BAR in (?, ?)",
+                    ["P1", "A", "B"]
+                ),
+            )
+
+            # Two items with following AND
+            self.assertEquals(
+                Select(
+                    From=self.schema.FOO,
+                    Where=(
+                        (
+                            self.schema.FOO.BAR.In(items)
+                        ).And(
+                            self.schema.FOO.BAZ == Parameter("P2")
+                        )
+                    )
+                ).toSQL().bind(P2="P2"),
+                SQLFragment(
+                    "select * from FOO where BAR in (?, ?) and BAZ = ?",
+                    ["A", "B", "P2"]
+                ),
+            )
+
+            # Two items with preceding OR and following AND
+            self.assertEquals(
+                Select(
+                    From=self.schema.FOO,
+                    Where=((
+                        self.schema.FOO.BAZ == Parameter("P1")
+                    ).Or(
+                        self.schema.FOO.BAR.In(items).And(
+                            self.schema.FOO.BAZ == Parameter("P2")
+                        )
+                    ))
+                ).toSQL().bind(P1="P1", P2="P2"),
+                SQLFragment(
+                    "select * from FOO where BAZ = ? or BAR in (?, ?) and BAZ = ?",
+                    ["P1", "A", "B", "P2"]
+                ),
+            )
+
+
     def test_max(self):
         """
         L{Max}C{(column)} produces an object in the C{columns} clause that
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20150219/42e24f54/attachment.html>


More information about the calendarserver-changes mailing list