[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