[CalendarServer-changes] [11142] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Mon May 6 13:22:12 PDT 2013


Revision: 11142
          http://trac.calendarserver.org//changeset/11142
Author:   cdaboo at apple.com
Date:     2013-05-06 13:22:12 -0700 (Mon, 06 May 2013)
Log Message:
-----------
Addition "on delete xxx" SQL statement parsing.

Modified Paths:
--------------
    CalendarServer/trunk/twext/enterprise/dal/model.py
    CalendarServer/trunk/twext/enterprise/dal/parseschema.py
    CalendarServer/trunk/twext/enterprise/dal/record.py
    CalendarServer/trunk/twext/enterprise/dal/test/test_parseschema.py
    CalendarServer/trunk/twext/enterprise/dal/test/test_record.py
    CalendarServer/trunk/twext/enterprise/dal/test/test_sqlsyntax.py
    CalendarServer/trunk/txdav/common/datastore/sql_tables.py

Modified: CalendarServer/trunk/twext/enterprise/dal/model.py
===================================================================
--- CalendarServer/trunk/twext/enterprise/dal/model.py	2013-05-06 18:51:32 UTC (rev 11141)
+++ CalendarServer/trunk/twext/enterprise/dal/model.py	2013-05-06 20:22:12 UTC (rev 11142)
@@ -102,7 +102,7 @@
     @ivar expression: the expression that should evaluate to True.
     @type expression: L{twext.enterprise.dal.syntax.ExpressionSyntax}
     """
-    # XXX TODO: model for expression, rather than 
+    # XXX TODO: model for expression, rather than
 
     def __init__(self, syntaxExpression, name=None):
         self.expression = syntaxExpression
@@ -160,10 +160,13 @@
         this will be a reference to that table; otherwise (normally) C{None}.
     @type references: L{Table} or C{NoneType}
 
-    @ivar cascade: If this column references another table, will this column's
-        row be deleted when the matching row in that other table is deleted?
-        (In other words, the SQL feature 'on delete cascade'.)
-    @type cascade: C{bool}
+    @ivar deleteAction: If this column references another table, home will this column's
+        row be altered when the matching row in that other table is deleted? Possible values are
+        None - for 'on delete no action'
+        'cascade' - for 'on delete cascade'
+        'set null' - for 'on delete set null'
+        'set default' - for 'on delete set default'
+    @type deleteAction: C{bool}
     """
 
     compareAttributes = 'table name'.split()
@@ -175,7 +178,7 @@
         self.type = type
         self.default = NO_DEFAULT
         self.references = None
-        self.cascade = False
+        self.deleteAction = None
 
 
     def __repr__(self):
@@ -435,5 +438,3 @@
 
     def indexNamed(self, name):
         return _namedFrom(name, self.indexes)
-
-

Modified: CalendarServer/trunk/twext/enterprise/dal/parseschema.py
===================================================================
--- CalendarServer/trunk/twext/enterprise/dal/parseschema.py	2013-05-06 18:51:32 UTC (rev 11141)
+++ CalendarServer/trunk/twext/enterprise/dal/parseschema.py	2013-05-06 20:22:12 UTC (rev 11142)
@@ -434,8 +434,20 @@
                     theColumn.doesReferenceName(target)
                 elif val.match(Keyword, 'ON'):
                     expect(self, ttype=Keyword.DML, value='DELETE')
-                    expect(self, ttype=Keyword, value='CASCADE')
-                    theColumn.cascade = True
+                    refAction = self.next()
+                    if refAction.ttype == Keyword and refAction.value.upper() == 'CASCADE':
+                        theColumn.deleteAction = 'cascade'
+                    elif refAction.ttype == Keyword and refAction.value.upper() == 'SET':
+                        setAction = self.next()
+                        if setAction.ttype == Keyword and setAction.value.upper() == 'NULL':
+                            theColumn.deleteAction = 'set null'
+                        elif setAction.ttype == Keyword and setAction.value.upper() == 'DEFAULT':
+                            theColumn.deleteAction = 'set default'
+                        else:
+                            raise RuntimeError("Invalid on delete set %r" % (setAction.value,))
+                    else:
+                        raise RuntimeError("Invalid on delete %r" % (refAction.value,))
+
                 else:
                     expected = False
                 if not expected:
@@ -447,7 +459,6 @@
 
 
 
-
 class ViolatedExpectation(Exception):
     """
     An expectation about the structure of the SQL syntax was violated.
@@ -546,6 +557,3 @@
     here.  The only quoting syntax respected is "''".)
     """
     return strval[1:-1].replace("''", "'")
-
-
-

Modified: CalendarServer/trunk/twext/enterprise/dal/record.py
===================================================================
--- CalendarServer/trunk/twext/enterprise/dal/record.py	2013-05-06 18:51:32 UTC (rev 11141)
+++ CalendarServer/trunk/twext/enterprise/dal/record.py	2013-05-06 20:22:12 UTC (rev 11142)
@@ -51,6 +51,7 @@
     """
 
 
+
 class _RecordMeta(type):
     """
     Metaclass for associating a L{fromTable} with a L{Record} at inheritance

Modified: CalendarServer/trunk/twext/enterprise/dal/test/test_parseschema.py
===================================================================
--- CalendarServer/trunk/twext/enterprise/dal/test/test_parseschema.py	2013-05-06 18:51:32 UTC (rev 11141)
+++ CalendarServer/trunk/twext/enterprise/dal/test/test_parseschema.py	2013-05-06 20:22:12 UTC (rev 11142)
@@ -318,18 +318,22 @@
         )
 
 
-    def test_cascade(self):
+    def test_deleteAction(self):
         """
         A column with an 'on delete cascade' constraint will have its C{cascade}
         attribute set to True.
         """
         s = self.schemaFromString(
             """
-            create table a (b integer primary key);
-            create table c (d integer references a on delete cascade);
+            create table a1 (b1 integer primary key);
+            create table c2 (d2 integer references a1 on delete cascade);
+            create table e3 (f3 integer references a1 on delete set null);
+            create table g4 (h4 integer references a1 on delete set default);
             """)
-        self.assertEquals(s.tableNamed("a").columnNamed("b").cascade, False)
-        self.assertEquals(s.tableNamed("c").columnNamed("d").cascade, True)
+        self.assertEquals(s.tableNamed("a1").columnNamed("b1").deleteAction, None)
+        self.assertEquals(s.tableNamed("c2").columnNamed("d2").deleteAction, "cascade")
+        self.assertEquals(s.tableNamed("e3").columnNamed("f3").deleteAction, "set null")
+        self.assertEquals(s.tableNamed("g4").columnNamed("h4").deleteAction, "set default")
 
 
     def test_indexes(self):
@@ -354,5 +358,3 @@
         self.assertEquals(b.columns, [a.columnNamed("b")])
         self.assertEquals(bc.table, a)
         self.assertEquals(bc.columns, [a.columnNamed("c"), a.columnNamed("b")])
-
-

Modified: CalendarServer/trunk/twext/enterprise/dal/test/test_record.py
===================================================================
--- CalendarServer/trunk/twext/enterprise/dal/test/test_record.py	2013-05-06 18:51:32 UTC (rev 11141)
+++ CalendarServer/trunk/twext/enterprise/dal/test/test_record.py	2013-05-06 20:22:12 UTC (rev 11142)
@@ -168,7 +168,6 @@
         self.assertEquals(rec.zeta, datetime.datetime(2012, 12, 12, 12, 12, 12))
 
 
-
     @inlineCallbacks
     def test_tooManyAttributes(self):
         """
@@ -269,6 +268,7 @@
             sorted(data)
         )
 
+
     @inlineCallbacks
     def test_repr(self):
         """
@@ -327,7 +327,3 @@
         self.assertEqual(Record.namingConvention(u"like_this"), "likeThis")
         self.assertEqual(Record.namingConvention(u"LIKE_THIS"), "likeThis")
         self.assertEqual(Record.namingConvention(u"LIKE_THIS_ID"), "likeThisID")
-
-
-
-

Modified: CalendarServer/trunk/twext/enterprise/dal/test/test_sqlsyntax.py
===================================================================
--- CalendarServer/trunk/twext/enterprise/dal/test/test_sqlsyntax.py	2013-05-06 18:51:32 UTC (rev 11141)
+++ CalendarServer/trunk/twext/enterprise/dal/test/test_sqlsyntax.py	2013-05-06 20:22:12 UTC (rev 11142)
@@ -60,6 +60,7 @@
     TIMESTAMP = 'for timestamps!'
 
 
+
 class CatchSQL(object):
     """
     L{IAsyncTransaction} emulator that records the SQL executed on it.
@@ -136,7 +137,6 @@
     Tests for syntactic helpers to generate SQL queries.
     """
 
-
     def test_simplestSelect(self):
         """
         L{Select} generates a 'select' statement, by default, asking for all
@@ -155,7 +155,6 @@
         self.assertNotEquals(self.schema.FOO, self.schema.BOZ)
 
 
-
     def test_simpleWhereClause(self):
         """
         L{Select} generates a 'select' statement with a 'where' clause
@@ -587,7 +586,7 @@
             Select(
                 From=self.schema.FOO,
                 Where=(self.schema.FOO.BAR == 1),
-                SetExpression= Union(
+                SetExpression=Union(
                     Select(
                         From=self.schema.FOO,
                         Where=(self.schema.FOO.BAR == 2),
@@ -659,7 +658,7 @@
             Select(
                 From=self.schema.FOO,
                 Where=(self.schema.FOO.BAR == 1),
-                SetExpression= Union(
+                SetExpression=Union(
                     Select(
                         From=self.schema.FOO,
                         Where=(self.schema.FOO.BAR == 2),
@@ -713,7 +712,7 @@
                     [self.schema.FOO.BAR],
                     From=self.schema.FOO,
                     Where=(self.schema.FOO.BAR == 1),
-                    SetExpression= Union(
+                    SetExpression=Union(
                         Select(
                             [self.schema.FOO.BAR],
                             From=self.schema.FOO,
@@ -725,6 +724,7 @@
             SQLFragment(
                 "select max(BAR) from ((select BAR from FOO where BAR = ?) UNION (select BAR from FOO where BAR = ?)) genid_1", [1, 2]))
 
+
     def test_selectColumnAliases(self):
         """
         L{Select} works with aliased columns.
@@ -837,13 +837,13 @@
         self.assertRaises(DALError, self.schema.FOO.BAR.In, Parameter("names"))
 
         # count=0 not allowed
-        self.assertRaises(DALError, Parameter,"names", 0)
+        self.assertRaises(DALError, Parameter, "names", 0)
 
         # Mismatched count and len(items)
         self.assertRaises(
             DALError,
             Select(From=self.schema.FOO, Where=self.schema.FOO.BAR.In(Parameter("names", len(items)))).toSQL().bind,
-            names=["a", "b", "c",]
+            names=["a", "b", "c", ]
         )
 
 
@@ -1321,6 +1321,7 @@
         self.assertEquals(Savepoint("test").toSQL(),
                           SQLFragment("savepoint test"))
 
+
     def test_rollbacktosavepoint(self):
         """
         L{RollbackToSavepoint} generates a ('rollback to savepoint') statement.
@@ -1328,6 +1329,7 @@
         self.assertEquals(RollbackToSavepoint("test").toSQL(),
                           SQLFragment("rollback to savepoint test"))
 
+
     def test_releasesavepoint(self):
         """
         L{ReleaseSavepoint} generates a ('release savepoint') statement.
@@ -1432,8 +1434,8 @@
         sequence default value.
         """
         addSQLToSchema(
-            schema=self.schema.model, schemaData=
-            "create table DFLTR (a varchar(255), "
+            schema=self.schema.model,
+            schemaData="create table DFLTR (a varchar(255), "
             "b integer default nextval('A_SEQ'));"
         )
         self.assertEquals(
@@ -1744,7 +1746,6 @@
 
 
 
-
 class OracleNetConnectionTests(NetworkedPoolHelper, ExampleSchemaHelper,
                                OracleConnectionMethods, TestCase):
 
@@ -1755,5 +1756,3 @@
         super(OracleNetConnectionTests, self).setUp()
         ExampleSchemaHelper.setUp(self)
         self.pump.client.dialect = ORACLE_DIALECT
-
-

Modified: CalendarServer/trunk/txdav/common/datastore/sql_tables.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_tables.py	2013-05-06 18:51:32 UTC (rev 11141)
+++ CalendarServer/trunk/txdav/common/datastore/sql_tables.py	2013-05-06 20:22:12 UTC (rev 11142)
@@ -344,8 +344,8 @@
                 out.write(' unique')
             if column.model.references is not None:
                 out.write(" references %s" % (column.model.references.name,))
-            if column.model.cascade:
-                out.write(" on delete cascade")
+            if column.model.deleteAction is not None:
+                out.write(" on delete %s" % (column.model.deleteAction,))
 
         def writeConstraint(name, cols):
             out.write(", \n") # the table has to have some preceding columns
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20130506/ea828858/attachment-0001.html>


More information about the calendarserver-changes mailing list