[CalendarServer-changes] [14598] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Sun Mar 15 20:04:20 PDT 2015


Revision: 14598
          http://trac.calendarserver.org//changeset/14598
Author:   cdaboo at apple.com
Date:     2015-03-15 20:04:19 -0700 (Sun, 15 Mar 2015)
Log Message:
-----------
Fixes to support Oracle DB unit testing. Fixes to Oracle schema upgrades.

Modified Paths:
--------------
    CalendarServer/trunk/requirements-stable.txt
    CalendarServer/trunk/twistedcaldav/stdconfig.py
    CalendarServer/trunk/txdav/common/datastore/sql.py
    CalendarServer/trunk/txdav/common/datastore/sql_dump.py
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v10.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v11.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v12.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v13.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v3.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v35.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v36.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v37.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v38.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v39.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v4.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v40.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v41.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v42.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v43.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v49.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v5.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v50.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v51.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v52.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v6.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v7.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v8.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v9.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_15_to_16.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_19_to_20.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_23_to_24.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_30_to_31.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_36_to_37.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_41_to_42.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_43_to_44.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_45_to_46.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_48_to_49.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_49_to_50.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_4_to_5.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_51_to_52.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_52_to_53.sql
    CalendarServer/trunk/txdav/common/datastore/test/test_sql_dump.py
    CalendarServer/trunk/txdav/common/datastore/test/util.py
    CalendarServer/trunk/txdav/common/datastore/upgrade/sql/test/test_upgrade.py

Added Paths:
-----------
    CalendarServer/trunk/txdav/base/datastore/suboracle.py
    CalendarServer/trunk/txdav/common/datastore/test/test_oracle_sql.py

Modified: CalendarServer/trunk/requirements-stable.txt
===================================================================
--- CalendarServer/trunk/requirements-stable.txt	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/requirements-stable.txt	2015-03-16 03:04:19 UTC (rev 14598)
@@ -36,7 +36,7 @@
             #pyOpenSSL
         pycrypto==2.6.1
 
-    --editable svn+http://svn.calendarserver.org/repository/calendarserver/twext/trunk@14586#egg=twextpy
+    --editable svn+http://svn.calendarserver.org/repository/calendarserver/twext/trunk@14597#egg=twextpy
         cffi==0.8.6
             pycparser==2.10
         #twisted

Modified: CalendarServer/trunk/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/stdconfig.py	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/twistedcaldav/stdconfig.py	2015-03-16 03:04:19 UTC (rev 14598)
@@ -421,7 +421,7 @@
         "LabelsInSQL"            : False,
         "Statistics"             : False,
         "StatisticsLogFile"      : "sqlstats.log",
-        "SQLStatements"          : False,
+        "SQLStatements"          : True,
         "TransactionWaitSeconds" : 0,
     },
 

Added: CalendarServer/trunk/txdav/base/datastore/suboracle.py
===================================================================
--- CalendarServer/trunk/txdav/base/datastore/suboracle.py	                        (rev 0)
+++ CalendarServer/trunk/txdav/base/datastore/suboracle.py	2015-03-16 03:04:19 UTC (rev 14598)
@@ -0,0 +1,157 @@
+# -*- test-case-name: txdav.base.datastore.test.test_subpostgres -*-
+# #
+# Copyright (c) 2010-2015 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# #
+from twisted.internet.defer import inlineCallbacks
+
+"""
+Stub service for Oracle.
+"""
+
+from twext.python.log import Logger
+
+from txdav.base.datastore.dbapiclient import OracleConnector
+from txdav.common.icommondatastore import InternalDataStoreError
+
+from twisted.application.service import MultiService
+
+log = Logger()
+
+
+
+class OracleService(MultiService):
+
+    def __init__(
+        self, dataStoreDirectory, subServiceFactory,
+        dsnUser=None,
+        testMode=False,
+        reactor=None,
+    ):
+        """
+        Initialize a L{OracleService} pointed at a data store directory.
+
+        @param dataStoreDirectory: the directory to
+        @type dataStoreDirectory: L{twext.python.filepath.CachingFilePath}
+
+        @param subServiceFactory: a 1-arg callable that will be called with a
+            1-arg callable which returns a DB-API cursor.
+        @type subServiceFactory: C{callable}
+        """
+
+        MultiService.__init__(self)
+        self.subServiceFactory = subServiceFactory
+        self.dataStoreDirectory = dataStoreDirectory
+        self.workingDir = self.dataStoreDirectory.child("working")
+
+        self.dsnUser = dsnUser
+        self.testMode = testMode
+
+        self._reactor = reactor
+
+
+    @property
+    def reactor(self):
+        if self._reactor is None:
+            from twisted.internet import reactor
+            self._reactor = reactor
+        return self._reactor
+
+
+    def _connectorFor(self):
+        m = getattr(self, "_connectorFor_{}".format("cx_oracle"), None)
+        if m is None:
+            raise InternalDataStoreError(
+                "Unknown Oracle DBM module: {}".format("cx_oracle")
+            )
+
+        return m()
+
+
+    def _connectorFor_cx_oracle(self):
+        dsn = "{}/oracle at 192.168.56.101:1521/orcl".format(self.dsnUser if self.dsnUser else "hr")
+
+        log.info(
+            "Connecting to Oracle with dsn={dsn!r}",
+            dsn=dsn,
+        )
+
+        return OracleConnector(dsn)
+
+
+    def produceConnection(self, label="<unlabeled>"):
+        """
+        Produce a DB-API 2.0 connection pointed at this database.
+        """
+        return self._connectorFor().connect(label)
+
+
+    def pauseMonitor(self):
+        """
+        Pause monitoring.
+        """
+        pass
+
+
+    def unpauseMonitor(self):
+        """
+        Unpause monitoring.
+
+        @see: L{pauseMonitor}
+        """
+        pass
+
+
+    def startService(self):
+        MultiService.startService(self)
+
+        if not self.dataStoreDirectory.isdir():
+            log.info("Creating {dir}", dir=self.dataStoreDirectory.path)
+            self.dataStoreDirectory.createDirectory()
+
+        if not self.workingDir.isdir():
+            log.info("Creating {dir}", dir=self.workingDir.path)
+            self.workingDir.createDirectory()
+
+        self.subServiceFactory(
+            self.produceConnection, self
+        ).setServiceParent(self)
+
+
+    def hardStop(self):
+        """
+        Stop quickly by sending it SIGQUIT
+        """
+        pass
+
+
+
+ at inlineCallbacks
+def cleanDatabase(txn):
+    tables = yield txn.execSQL("select table_name from user_tables")
+    for table in tables:
+        yield txn.execSQL("drop table {} cascade constraints purge".format(table[0]))
+    yield txn.execSQL("purge recyclebin")
+
+    sequences = yield txn.execSQL("select sequence_name from user_sequences")
+    for sequence in sequences:
+        yield txn.execSQL("drop sequence {}".format(sequence[0]))
+
+    indexes = yield txn.execSQL("select index_name from user_indexes")
+    for index in indexes:
+        yield txn.execSQL("drop index {}".format(index[0]))
+
+    constraints = yield txn.execSQL("select constraint_name from user_constraints")
+    for constraint in constraints:
+        yield txn.execSQL("drop constraint '{}'".format(constraint[0]))

Modified: CalendarServer/trunk/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql.py	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py	2015-03-16 03:04:19 UTC (rev 14598)
@@ -973,7 +973,8 @@
         for regular SQL operations - only upgrades.
         """
         for stmt in splitSQLString(sql):
-            yield self.execSQL(stmt)
+            if not stmt.startswith("--"):
+                yield self.execSQL(stmt)
 
 
     def commit(self):

Modified: CalendarServer/trunk/txdav/common/datastore/sql_dump.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_dump.py	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_dump.py	2015-03-16 03:04:19 UTC (rev 14598)
@@ -17,32 +17,56 @@
 
 from twisted.internet.defer import inlineCallbacks, returnValue
 from twext.enterprise.dal.model import Schema, Table, Column, Sequence, Function, \
-    SQLType, ProcedureCall, Constraint
+    SQLType, ProcedureCall, Constraint, Index
 from twext.enterprise.dal.parseschema import addSQLToSchema
+from twext.enterprise.ienterprise import POSTGRES_DIALECT, ORACLE_DIALECT
+import collections
 
 """
 Dump a postgres DB into an L{Schema} model object.
 """
 
-DTYPE_MAP = {
+DTYPE_MAP_POSTGRES = {
     "character": "char",
     "character varying": "varchar",
     "timestamp without time zone": "timestamp",
 }
 
-DEFAULTVALUE_MAP = {
+DTYPE_MAP_ORACLE = {
+    "number": "integer",
+    "timestamp(6)": "timestamp",
+}
+
+DEFAULTVALUE_MAP_POSTGRES = {
     "timezone('UTC'::text, now())": ProcedureCall("timezone", ["UTC", "CURRENT_TIMESTAMP"]),
     "NULL::character varying": None,
     "false": False,
     "true": True,
 }
 
- at inlineCallbacks
+DEFAULTVALUE_MAP_ORACLE = {
+    "CURRENT_TIMESTAMP at time zone 'UTC'": ProcedureCall("timezone", ["UTC", "CURRENT_TIMESTAMP"]),
+    "null": None,
+}
+
 def dumpSchema(txn, title, schemaname="public"):
     """
     Generate the L{Schema}.
     """
 
+    if txn.dialect == POSTGRES_DIALECT:
+        return dumpSchema_postgres(txn, title, schemaname)
+    elif txn.dialect == ORACLE_DIALECT:
+        return dumpSchema_oracle(txn, title, schemaname)
+
+
+
+ at inlineCallbacks
+def dumpSchema_postgres(txn, title, schemaname="public"):
+    """
+    Generate the L{Schema}.
+    """
+
     schemaname = schemaname.lower()
 
     schema = Schema(title)
@@ -66,14 +90,14 @@
         rows = yield txn.execSQL("select column_name, data_type, is_nullable, character_maximum_length, column_default from information_schema.columns where table_schema = '%s' and table_name = '%s';" % (schemaname, name,))
         for name, datatype, is_nullable, charlen, default in rows:
             # TODO: figure out the type
-            column = Column(table, name.upper(), SQLType(DTYPE_MAP.get(datatype, datatype), charlen))
+            column = Column(table, name.upper(), SQLType(DTYPE_MAP_POSTGRES.get(datatype, datatype), charlen))
             table.columns.append(column)
             if default:
                 if default.startswith("nextval("):
                     dname = default.split("'")[1].split(".")[-1]
                     column.default = seqs[dname.upper()]
-                elif default in DEFAULTVALUE_MAP:
-                    column.default = DEFAULTVALUE_MAP[default]
+                elif default in DEFAULTVALUE_MAP_POSTGRES:
+                    column.default = DEFAULTVALUE_MAP_POSTGRES[default]
                 else:
                     try:
                         column.default = int(default)
@@ -116,3 +140,92 @@
         Function(schema, name)
 
     returnValue(schema)
+
+
+
+ at inlineCallbacks
+def dumpSchema_oracle(txn, title, schemaname="public"):
+    """
+    Generate the L{Schema}.
+    """
+
+    schemaname = schemaname.lower()
+
+    schema = Schema(title)
+
+    # Sequences
+    seqs = {}
+    rows = yield txn.execSQL("select sequence_name from all_sequences where sequence_owner = '%s'" % (schemaname.upper(),))
+    for row in rows:
+        name = row[0]
+        seqs[name.upper()] = Sequence(schema, name.upper())
+
+    # Tables
+    tables = {}
+    rows = yield txn.execSQL("select table_name from all_tables where owner = '%s'" % (schemaname.upper(),))
+    for row in rows:
+        name = row[0]
+        table = Table(schema, name.upper())
+        tables[name.upper()] = table
+
+        # Columns
+        rows = yield txn.execSQL("select column_name, data_type, nullable, char_length, data_default from all_tab_columns where owner = '%s' and table_name = '%s'" % (schemaname.upper(), name,))
+        for name, datatype, is_nullable, charlen, default in rows:
+            # TODO: figure out the type
+            column = Column(table, name.upper(), SQLType(DTYPE_MAP_ORACLE.get(datatype.lower(), datatype.lower()), charlen))
+            table.columns.append(column)
+            if default:
+                default = default.strip()
+                if default.startswith("nextval("):
+                    dname = default.split("'")[1].split(".")[-1]
+                    column.default = seqs[dname.upper()]
+                elif default in DEFAULTVALUE_MAP_ORACLE:
+                    column.default = DEFAULTVALUE_MAP_ORACLE[default]
+                else:
+                    try:
+                        column.default = int(default)
+                    except ValueError:
+                        column.default = default
+            if is_nullable == "N":
+                table.tableConstraint(Constraint.NOT_NULL, [column.name, ])
+
+    # Constraints
+    constraints = collections.defaultdict(list)
+    rows = yield txn.execSQL("select constraint_name, table_name, column_name, position from all_cons_columns where owner = '%s'" % (schemaname.upper(),))
+    for conname, tname, cname, position in rows:
+        constraints[conname].append((tname, cname, position,))
+    rows = yield txn.execSQL("select constraint_name, constraint_type, table_name, r_constraint_name, delete_rule from all_constraints where owner = '%s'" % (schemaname.upper(),))
+    for conname, conntype, tname, r_constraint_name, delete_rule in rows:
+        if constraints[conname][0][0].upper() in tables:
+            constraint = constraints[conname]
+            constraint = sorted(constraint, key=lambda x: x[2])
+            table = tables[constraint[0][0].upper()]
+            column_names = [item[1].upper() for item in constraint]
+            columns = [table.columnNamed(column_name) for column_name in column_names]
+            if conntype == "P":
+                table.primaryKey = columns
+            elif conntype == "U":
+                table.tableConstraint(Constraint.UNIQUE, column_names)
+            elif conntype == "R":
+                columns[0].doesReferenceName(constraints[r_constraint_name][0][0].upper())
+                if delete_rule.lower() != "no action":
+                    columns[0].deleteAction = delete_rule.lower()
+
+    # Indexed columns
+    idx = collections.defaultdict(list)
+    rows = yield txn.execSQL("select index_name, column_name, column_position from all_ind_columns where index_owner = '%s'" % (schemaname.upper(),))
+    for index_name, column_name, column_position in rows:
+        idx[index_name].append((column_name, column_position))
+
+    # Indexes
+    rows = yield txn.execSQL("select index_name, table_name, uniqueness from all_indexes where owner = '%s'" % (schemaname.upper(),))
+    for index_name, table_name, uniqueness in rows:
+        if table_name in tables:
+            table = tables[table_name]
+            column_names = [item[0].upper() for item in sorted(idx[index_name], key=lambda x: x[1])]
+            columns = [table.columnNamed(column_name) for column_name in column_names]
+            index = Index(schema, index_name.upper(), table, uniqueness == "UNIQUE")
+            for column in columns:
+                index.addColumn(column)
+
+    returnValue(schema)

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v10.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v10.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v10.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -265,14 +265,6 @@
     INVITE_UID
 );
 
-create index INVITE_RESOURCE_ID_b36ddc23 on INVITE (
-    RESOURCE_ID
-);
-
-create index INVITE_HOME_RESOURCE__e9bdf77e on INVITE (
-    HOME_RESOURCE_ID
-);
-
 create index NOTIFICATION_NOTIFICA_f891f5f9 on NOTIFICATION (
     NOTIFICATION_HOME_RESOURCE_ID
 );

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v11.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v11.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v11.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -267,14 +267,6 @@
     INVITE_UID
 );
 
-create index INVITE_RESOURCE_ID_b36ddc23 on INVITE (
-    RESOURCE_ID
-);
-
-create index INVITE_HOME_RESOURCE__e9bdf77e on INVITE (
-    HOME_RESOURCE_ID
-);
-
 create index NOTIFICATION_NOTIFICA_f891f5f9 on NOTIFICATION (
     NOTIFICATION_HOME_RESOURCE_ID
 );

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v12.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v12.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v12.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -275,14 +275,6 @@
     INVITE_UID
 );
 
-create index INVITE_RESOURCE_ID_b36ddc23 on INVITE (
-    RESOURCE_ID
-);
-
-create index INVITE_HOME_RESOURCE__e9bdf77e on INVITE (
-    HOME_RESOURCE_ID
-);
-
 create index NOTIFICATION_NOTIFICA_f891f5f9 on NOTIFICATION (
     NOTIFICATION_HOME_RESOURCE_ID
 );

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v13.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v13.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v13.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -284,14 +284,6 @@
     INVITE_UID
 );
 
-create index INVITE_RESOURCE_ID_b36ddc23 on INVITE (
-    RESOURCE_ID
-);
-
-create index INVITE_HOME_RESOURCE__e9bdf77e on INVITE (
-    HOME_RESOURCE_ID
-);
-
 create index NOTIFICATION_NOTIFICA_f891f5f9 on NOTIFICATION (
     NOTIFICATION_HOME_RESOURCE_ID
 );

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v3.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v3.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v3.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -237,9 +237,6 @@
 );
 
 insert into CALENDARSERVER (NAME, VALUE) values ('VERSION', '3');
-create index CALENDAR_HOME_OWNER_U_78016c63 on CALENDAR_HOME (
-    OWNER_UID
-);
 
 create index CALENDAR_HOME_METADAT_35a84eec on CALENDAR_HOME_METADATA (
     RESOURCE_ID
@@ -249,18 +246,6 @@
     INVITE_UID
 );
 
-create index INVITE_RESOURCE_ID_b36ddc23 on INVITE (
-    INVITE_UID
-);
-
-create index INVITE_HOME_RESOURCE__e9bdf77e on INVITE (
-    INVITE_UID
-);
-
-create index NOTIFICATION_HOME_OWN_401a6203 on NOTIFICATION_HOME (
-    OWNER_UID
-);
-
 create index NOTIFICATION_NOTIFICA_f891f5f9 on NOTIFICATION (
     NOTIFICATION_HOME_RESOURCE_ID
 );
@@ -315,10 +300,6 @@
     DROPBOX_ID
 );
 
-create index ADDRESSBOOK_HOME_OWNE_44f7f53b on ADDRESSBOOK_HOME (
-    OWNER_UID
-);
-
 create index ADDRESSBOOK_HOME_META_cfe06701 on ADDRESSBOOK_HOME_METADATA (
     RESOURCE_ID
 );

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v35.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v35.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v35.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -651,7 +651,7 @@
     TOKEN
 );
 
-create index GROUPS_GROUP_UID_ebf7a1d4 on GROUPS (
+create index GROUPS_GROUP_UID_b35cce23 on GROUPS (
     GROUP_UID
 );
 

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v36.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v36.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v36.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -662,7 +662,7 @@
     TOKEN
 );
 
-create index GROUPS_GROUP_UID_ebf7a1d4 on GROUPS (
+create index GROUPS_GROUP_UID_b35cce23 on GROUPS (
     GROUP_UID
 );
 

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v37.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v37.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v37.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -803,17 +803,3 @@
     JOB_ID
 );
 
--- Skipped Function next_job
-
--- Extras
-
-create or replace function next_job return integer is
-  cursor c1 is select JOB_ID from JOB for update skip locked;
-  result integer;
-begin
-  open c1;
-  fetch c1 into result;
-  select JOB_ID from JOB where ID = result for update;
-  return result;
-end;
-/

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v38.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v38.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v38.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -834,17 +834,3 @@
     JOB_ID
 );
 
--- Skipped Function next_job
-
--- Extras
-
-create or replace function next_job return integer is
-  cursor c1 is select JOB_ID from JOB for update skip locked;
-  result integer;
-begin
-  open c1;
-  fetch c1 into result;
-  select JOB_ID from JOB where ID = result for update;
-  return result;
-end;
-/

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v39.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v39.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v39.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -834,17 +834,3 @@
     JOB_ID
 );
 
--- Skipped Function next_job
-
--- Extras
-
-create or replace function next_job return integer is
-  cursor c1 is select JOB_ID from JOB for update skip locked;
-  result integer;
-begin
-  open c1;
-  fetch c1 into result;
-  select JOB_ID from JOB where ID = result for update;
-  return result;
-end;
-/

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v4.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v4.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v4.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -237,9 +237,6 @@
 );
 
 insert into CALENDARSERVER (NAME, VALUE) values ('VERSION', '4');
-create index CALENDAR_HOME_OWNER_U_78016c63 on CALENDAR_HOME (
-    OWNER_UID
-);
 
 create index CALENDAR_HOME_METADAT_35a84eec on CALENDAR_HOME_METADATA (
     RESOURCE_ID
@@ -249,18 +246,6 @@
     INVITE_UID
 );
 
-create index INVITE_RESOURCE_ID_b36ddc23 on INVITE (
-    INVITE_UID
-);
-
-create index INVITE_HOME_RESOURCE__e9bdf77e on INVITE (
-    INVITE_UID
-);
-
-create index NOTIFICATION_HOME_OWN_401a6203 on NOTIFICATION_HOME (
-    OWNER_UID
-);
-
 create index NOTIFICATION_NOTIFICA_f891f5f9 on NOTIFICATION (
     NOTIFICATION_HOME_RESOURCE_ID
 );
@@ -315,10 +300,6 @@
     DROPBOX_ID
 );
 
-create index ADDRESSBOOK_HOME_OWNE_44f7f53b on ADDRESSBOOK_HOME (
-    OWNER_UID
-);
-
 create index ADDRESSBOOK_HOME_META_cfe06701 on ADDRESSBOOK_HOME_METADATA (
     RESOURCE_ID
 );

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v40.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v40.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v40.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -836,18 +836,3 @@
     JOB_ID
 );
 
--- Skipped Function next_job
-
--- Extras
-
-create or replace function next_job return integer is
-declare
-  cursor c1 is select JOB_ID from JOB for update skip locked;
-  result integer;
-begin
-  open c1;
-  fetch c1 into result;
-  select JOB_ID from JOB where ID = result for update;
-  return result;
-end;
-/

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v41.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v41.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v41.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -851,18 +851,3 @@
     HOME_RESOURCE_ID
 );
 
--- Skipped Function next_job
-
--- Extras
-
-create or replace function next_job return integer is
-declare
-  cursor c1 is select JOB_ID from JOB for update skip locked;
-  result integer;
-begin
-  open c1;
-  fetch c1 into result;
-  select JOB_ID from JOB where ID = result for update;
-  return result;
-end;
-/

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v42.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v42.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v42.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -852,18 +852,3 @@
     HOME_RESOURCE_ID
 );
 
--- Skipped Function next_job
-
--- Extras
-
-create or replace function next_job return integer is
-declare
-  cursor c1 is select JOB_ID from JOB for update skip locked;
-  result integer;
-begin
-  open c1;
-  fetch c1 into result;
-  select JOB_ID from JOB where ID = result for update;
-  return result;
-end;
-/

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v43.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v43.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v43.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -853,18 +853,3 @@
     HOME_RESOURCE_ID
 );
 
--- Skipped Function next_job
-
--- Extras
-
-create or replace function next_job return integer is
-declare
-  cursor c1 is select JOB_ID from JOB for update skip locked;
-  result integer;
-begin
-  open c1;
-  fetch c1 into result;
-  select JOB_ID from JOB where ID = result for update;
-  return result;
-end;
-/

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v49.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v49.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v49.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -904,7 +904,7 @@
 );
 
 create index PRINCIPAL_PURGE_CHECK_198388a5 on PRINCIPAL_PURGE_CHECK_WORK (
-    UID
+    "UID"
 );
 
 create index PRINCIPAL_PURGE_WORK__7a8141a3 on PRINCIPAL_PURGE_WORK (
@@ -912,7 +912,7 @@
 );
 
 create index PRINCIPAL_PURGE_WORK__db35cfdc on PRINCIPAL_PURGE_WORK (
-    UID
+    "UID"
 );
 
 create index PRINCIPAL_PURGE_HOME__f35eea7a on PRINCIPAL_PURGE_HOME_WORK (

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v5.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v5.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v5.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -239,14 +239,6 @@
     INVITE_UID
 );
 
-create index INVITE_RESOURCE_ID_b36ddc23 on INVITE (
-    RESOURCE_ID
-);
-
-create index INVITE_HOME_RESOURCE__e9bdf77e on INVITE (
-    HOME_RESOURCE_ID
-);
-
 create index NOTIFICATION_NOTIFICA_f891f5f9 on NOTIFICATION (
     NOTIFICATION_HOME_RESOURCE_ID
 );

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v50.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v50.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v50.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -894,7 +894,7 @@
 );
 
 create index PRINCIPAL_PURGE_CHECK_198388a5 on PRINCIPAL_PURGE_CHECK_WORK (
-    UID
+    "UID"
 );
 
 create index PRINCIPAL_PURGE_WORK__7a8141a3 on PRINCIPAL_PURGE_WORK (
@@ -902,7 +902,7 @@
 );
 
 create index PRINCIPAL_PURGE_WORK__db35cfdc on PRINCIPAL_PURGE_WORK (
-    UID
+    "UID"
 );
 
 create index PRINCIPAL_PURGE_HOME__f35eea7a on PRINCIPAL_PURGE_HOME_WORK (

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v51.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v51.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v51.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -908,7 +908,7 @@
 );
 
 create index PRINCIPAL_PURGE_CHECK_198388a5 on PRINCIPAL_PURGE_CHECK_WORK (
-    UID
+    "UID"
 );
 
 create index PRINCIPAL_PURGE_WORK__7a8141a3 on PRINCIPAL_PURGE_WORK (
@@ -916,7 +916,7 @@
 );
 
 create index PRINCIPAL_PURGE_WORK__db35cfdc on PRINCIPAL_PURGE_WORK (
-    UID
+    "UID"
 );
 
 create index PRINCIPAL_PURGE_HOME__f35eea7a on PRINCIPAL_PURGE_HOME_WORK (
@@ -926,5 +926,3 @@
 create index PRINCIPAL_PURGE_HOME__967e4480 on PRINCIPAL_PURGE_HOME_WORK (
     HOME_RESOURCE_ID
 );
-
--- Extra schema to add to current-oracle-dialect.sql

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v52.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v52.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v52.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -957,7 +957,7 @@
 );
 
 create index PRINCIPAL_PURGE_CHECK_198388a5 on PRINCIPAL_PURGE_CHECK_WORK (
-    UID
+    "UID"
 );
 
 create index PRINCIPAL_PURGE_WORK__7a8141a3 on PRINCIPAL_PURGE_WORK (
@@ -965,7 +965,7 @@
 );
 
 create index PRINCIPAL_PURGE_WORK__db35cfdc on PRINCIPAL_PURGE_WORK (
-    UID
+    "UID"
 );
 
 create index PRINCIPAL_PURGE_HOME__f35eea7a on PRINCIPAL_PURGE_HOME_WORK (

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v6.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v6.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v6.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -247,14 +247,6 @@
     INVITE_UID
 );
 
-create index INVITE_RESOURCE_ID_b36ddc23 on INVITE (
-    RESOURCE_ID
-);
-
-create index INVITE_HOME_RESOURCE__e9bdf77e on INVITE (
-    HOME_RESOURCE_ID
-);
-
 create index NOTIFICATION_NOTIFICA_f891f5f9 on NOTIFICATION (
     NOTIFICATION_HOME_RESOURCE_ID
 );

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v7.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v7.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v7.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -256,14 +256,6 @@
     INVITE_UID
 );
 
-create index INVITE_RESOURCE_ID_b36ddc23 on INVITE (
-    RESOURCE_ID
-);
-
-create index INVITE_HOME_RESOURCE__e9bdf77e on INVITE (
-    HOME_RESOURCE_ID
-);
-
 create index NOTIFICATION_NOTIFICA_f891f5f9 on NOTIFICATION (
     NOTIFICATION_HOME_RESOURCE_ID
 );

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v8.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v8.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v8.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -264,14 +264,6 @@
     INVITE_UID
 );
 
-create index INVITE_RESOURCE_ID_b36ddc23 on INVITE (
-    RESOURCE_ID
-);
-
-create index INVITE_HOME_RESOURCE__e9bdf77e on INVITE (
-    HOME_RESOURCE_ID
-);
-
 create index NOTIFICATION_NOTIFICA_f891f5f9 on NOTIFICATION (
     NOTIFICATION_HOME_RESOURCE_ID
 );

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v9.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v9.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v9.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -264,14 +264,6 @@
     INVITE_UID
 );
 
-create index INVITE_RESOURCE_ID_b36ddc23 on INVITE (
-    RESOURCE_ID
-);
-
-create index INVITE_HOME_RESOURCE__e9bdf77e on INVITE (
-    HOME_RESOURCE_ID
-);
-
 create index NOTIFICATION_NOTIFICA_f891f5f9 on NOTIFICATION (
     NOTIFICATION_HOME_RESOURCE_ID
 );

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_15_to_16.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_15_to_16.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_15_to_16.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -30,6 +30,10 @@
     primary key("ORGANIZER", "ATTENDEE", "ICALUID")
 );
 
+create index IMIP_TOKENS_TOKEN_e94b918f on IMIP_TOKENS (
+    TOKEN
+);
+
 create table IMIP_INVITATION_WORK (
     "WORK_ID" integer primary key not null,
     "NOT_BEFORE" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_19_to_20.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_19_to_20.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_19_to_20.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -231,6 +231,9 @@
 	 		)
   	);
 
+drop index ADDRESSBOOK_OBJECT_RE_f460d62d;
+drop index ADDRESSBOOK_OBJECT_RE_9a848f39;
+drop index ADDRESSBOOK_OBJECT_RE_cb101e6b;
 alter table ADDRESSBOOK_OBJECT_REVISIONS
 	drop ("ADDRESSBOOK_RESOURCE_ID");
 

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_23_to_24.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_23_to_24.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_23_to_24.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -45,6 +45,8 @@
     RESOURCE_ID
 );
 
+alter index ADDRESSBOOK_OBJECT_RE_40cc2d73 rename to ADDRESSBOOK_OBJECT_RE_2bfcf757;
+
 -- Now update the version
 -- No data upgrades
 update CALENDARSERVER set VALUE = '24' where NAME = 'VERSION';

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_30_to_31.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_30_to_31.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_30_to_31.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -22,6 +22,8 @@
 -- Change Address Book Object Members --
 ----------------------------------------
 
+alter table ABO_MEMBERS
+	 drop primary key;
 begin
     for i in (select constraint_name
               from   user_cons_columns

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_36_to_37.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_36_to_37.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_36_to_37.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -33,22 +33,11 @@
     "NOT_AFTER" timestamp default null
 );
 
-create or replace function next_job return integer is
-  cursor c1 is select ID from JOB for update skip locked;
-  result integer;
-begin
-  open c1;
-  fetch c1 into result;
-  select ID from JOB where ID = result for update;
-  return result;
-end;
-/
 
-
 -- IMIP_INVITATION_WORK --
 alter table IMIP_INVITATION_WORK
     add ("JOB_ID" integer default 0 not null);
-update IMIP_INVITATION_WORK set JOB_ID = JOB_SEQ.nextval
+update IMIP_INVITATION_WORK set JOB_ID = JOB_SEQ.nextval;
 
 insert into JOB
   (JOB_ID, WORK_TYPE, NOT_BEFORE)
@@ -57,7 +46,7 @@
 alter table IMIP_INVITATION_WORK
     drop column NOT_BEFORE;
 alter table IMIP_INVITATION_WORK
-    add constraint foreign key (JOB_ID) references JOB;
+    modify ("JOB_ID" integer default null references JOB);
 
 create index IMIP_INVITATION_WORK__586d064c on IMIP_INVITATION_WORK (
     JOB_ID
@@ -67,7 +56,7 @@
 -- IMIP_POLLING_WORK --
 alter table IMIP_POLLING_WORK
     add ("JOB_ID" integer default 0 not null);
-update IMIP_POLLING_WORK set JOB_ID = JOB_SEQ.nextval
+update IMIP_POLLING_WORK set JOB_ID = JOB_SEQ.nextval;
 
 insert into JOB
   (JOB_ID, WORK_TYPE, NOT_BEFORE)
@@ -76,7 +65,7 @@
 alter table IMIP_POLLING_WORK
     drop column NOT_BEFORE;
 alter table IMIP_POLLING_WORK
-    add constraint foreign key (JOB_ID) references JOB;
+    modify ("JOB_ID" integer default null references JOB);
 
 create index IMIP_POLLING_WORK_JOB_d5535891 on IMIP_POLLING_WORK (
     JOB_ID
@@ -86,7 +75,7 @@
 -- IMIP_REPLY_WORK --
 alter table IMIP_REPLY_WORK
     add ("JOB_ID" integer default 0 not null);
-update IMIP_REPLY_WORK set JOB_ID = JOB_SEQ.nextval
+update IMIP_REPLY_WORK set JOB_ID = JOB_SEQ.nextval;
 
 insert into JOB
   (JOB_ID, WORK_TYPE, NOT_BEFORE)
@@ -95,7 +84,7 @@
 alter table IMIP_REPLY_WORK
     drop column NOT_BEFORE;
 alter table IMIP_REPLY_WORK
-    add constraint foreign key (JOB_ID) references JOB;
+    modify ("JOB_ID" integer default null references JOB);
 
 create index IMIP_REPLY_WORK_JOB_I_bf4ae73e on IMIP_REPLY_WORK (
     JOB_ID
@@ -105,7 +94,9 @@
 -- PUSH_NOTIFICATION_WORK --
 alter table PUSH_NOTIFICATION_WORK
     add ("JOB_ID" integer default 0 not null);
-update PUSH_NOTIFICATION_WORK set JOB_ID = JOB_SEQ.nextval
+update PUSH_NOTIFICATION_WORK set JOB_ID = JOB_SEQ.nextval;
+alter table PUSH_NOTIFICATION_WORK
+    rename column "PRIORITY" to "PUSH_PRIORITY";
 
 insert into JOB
   (JOB_ID, WORK_TYPE, NOT_BEFORE)
@@ -114,7 +105,7 @@
 alter table PUSH_NOTIFICATION_WORK
     drop column NOT_BEFORE;
 alter table PUSH_NOTIFICATION_WORK
-    add constraint foreign key (JOB_ID) references JOB;
+    modify ("JOB_ID" integer default null references JOB);
 
 create index PUSH_NOTIFICATION_WOR_8bbab117 on PUSH_NOTIFICATION_WORK (
     JOB_ID
@@ -124,7 +115,7 @@
 -- GROUP_CACHER_POLLING_WORK --
 alter table GROUP_CACHER_POLLING_WORK
     add ("JOB_ID" integer default 0 not null);
-update GROUP_CACHER_POLLING_WORK set JOB_ID = JOB_SEQ.nextval
+update GROUP_CACHER_POLLING_WORK set JOB_ID = JOB_SEQ.nextval;
 
 insert into JOB
   (JOB_ID, WORK_TYPE, NOT_BEFORE)
@@ -133,7 +124,7 @@
 alter table GROUP_CACHER_POLLING_WORK
     drop column NOT_BEFORE;
 alter table GROUP_CACHER_POLLING_WORK
-    add constraint foreign key (JOB_ID) references JOB;
+    modify ("JOB_ID" integer default null references JOB);
 
 create index GROUP_CACHER_POLLING__6eb3151c on GROUP_CACHER_POLLING_WORK (
     JOB_ID
@@ -143,7 +134,7 @@
 -- GROUP_REFRESH_WORK --
 alter table GROUP_REFRESH_WORK
     add ("JOB_ID" integer default 0 not null);
-update GROUP_REFRESH_WORK set JOB_ID = JOB_SEQ.nextval
+update GROUP_REFRESH_WORK set JOB_ID = JOB_SEQ.nextval;
 
 insert into JOB
   (JOB_ID, WORK_TYPE, NOT_BEFORE)
@@ -152,28 +143,28 @@
 alter table GROUP_REFRESH_WORK
     drop column NOT_BEFORE;
 alter table GROUP_REFRESH_WORK
-    add constraint foreign key (JOB_ID) references JOB;
+    modify ("JOB_ID" integer default null references JOB);
 
 create index GROUP_REFRESH_WORK_JO_717ede20 on GROUP_REFRESH_WORK (
     JOB_ID
 );
 
 
--- GROUP_ATTENDEE_RECONCILIATION_WORK --
-alter table GROUP_ATTENDEE_RECONCILIATION_WORK
+-- GROUP_ATTENDEE_RECONCILIATION_ --
+alter table GROUP_ATTENDEE_RECONCILIATION_
     add ("JOB_ID" integer default 0 not null);
-update GROUP_ATTENDEE_RECONCILIATION_WORK set JOB_ID = JOB_SEQ.nextval
+update GROUP_ATTENDEE_RECONCILIATION_ set JOB_ID = JOB_SEQ.nextval;
 
 insert into JOB
   (JOB_ID, WORK_TYPE, NOT_BEFORE)
-  (select JOB_ID, 'GROUP_ATTENDEE_RECONCILIATION_WORK', NOT_BEFORE from GROUP_ATTENDEE_RECONCILIATION_WORK);
+  (select JOB_ID, 'GROUP_ATTENDEE_RECONCILIATION_', NOT_BEFORE from GROUP_ATTENDEE_RECONCILIATION_);
 
-alter table GROUP_ATTENDEE_RECONCILIATION_WORK
+alter table GROUP_ATTENDEE_RECONCILIATION_
     drop column NOT_BEFORE;
-alter table GROUP_ATTENDEE_RECONCILIATION_WORK
-    add constraint foreign key (JOB_ID) references JOB;
+alter table GROUP_ATTENDEE_RECONCILIATION_
+    modify ("JOB_ID" integer default null references JOB);
 
-create index GROUP_ATTENDEE_RECONC_cd2d61b9 on GROUP_ATTENDEE_RECONCILIATION_WORK (
+create index GROUP_ATTENDEE_RECONC_cd2d61b9 on GROUP_ATTENDEE_RECONCILIATION_ (
     JOB_ID
 );
 
@@ -181,7 +172,7 @@
 -- CALENDAR_OBJECT_SPLITTER_WORK --
 alter table CALENDAR_OBJECT_SPLITTER_WORK
     add ("JOB_ID" integer default 0 not null);
-update CALENDAR_OBJECT_SPLITTER_WORK set JOB_ID = JOB_SEQ.nextval
+update CALENDAR_OBJECT_SPLITTER_WORK set JOB_ID = JOB_SEQ.nextval;
 
 insert into JOB
   (JOB_ID, WORK_TYPE, NOT_BEFORE)
@@ -190,7 +181,7 @@
 alter table CALENDAR_OBJECT_SPLITTER_WORK
     drop column NOT_BEFORE;
 alter table CALENDAR_OBJECT_SPLITTER_WORK
-    add constraint foreign key (JOB_ID) references JOB;
+    modify ("JOB_ID" integer default null references JOB);
 
 create index CALENDAR_OBJECT_SPLIT_33603b72 on CALENDAR_OBJECT_SPLITTER_WORK (
     JOB_ID
@@ -200,7 +191,7 @@
 -- FIND_MIN_VALID_REVISION_WORK --
 alter table FIND_MIN_VALID_REVISION_WORK
     add ("JOB_ID" integer default 0 not null);
-update FIND_MIN_VALID_REVISION_WORK set JOB_ID = JOB_SEQ.nextval
+update FIND_MIN_VALID_REVISION_WORK set JOB_ID = JOB_SEQ.nextval;
 
 insert into JOB
   (JOB_ID, WORK_TYPE, NOT_BEFORE)
@@ -209,7 +200,7 @@
 alter table FIND_MIN_VALID_REVISION_WORK
     drop column NOT_BEFORE;
 alter table FIND_MIN_VALID_REVISION_WORK
-    add constraint foreign key (JOB_ID) references JOB;
+    modify ("JOB_ID" integer default null references JOB);
 
 create index FIND_MIN_VALID_REVISI_78d17400 on FIND_MIN_VALID_REVISION_WORK (
     JOB_ID
@@ -219,7 +210,7 @@
 -- REVISION_CLEANUP_WORK --
 alter table REVISION_CLEANUP_WORK
     add ("JOB_ID" integer default 0 not null);
-update REVISION_CLEANUP_WORK set JOB_ID = JOB_SEQ.nextval
+update REVISION_CLEANUP_WORK set JOB_ID = JOB_SEQ.nextval;
 
 insert into JOB
   (JOB_ID, WORK_TYPE, NOT_BEFORE)
@@ -228,7 +219,7 @@
 alter table REVISION_CLEANUP_WORK
     drop column NOT_BEFORE;
 alter table REVISION_CLEANUP_WORK
-    add constraint foreign key (JOB_ID) references JOB;
+    modify ("JOB_ID" integer default null references JOB);
 
 create index REVISION_CLEANUP_WORK_eb062686 on REVISION_CLEANUP_WORK (
     JOB_ID
@@ -238,7 +229,7 @@
 -- INBOX_CLEANUP_WORK --
 alter table INBOX_CLEANUP_WORK
     add ("JOB_ID" integer default 0 not null);
-update INBOX_CLEANUP_WORK set JOB_ID = JOB_SEQ.nextval
+update INBOX_CLEANUP_WORK set JOB_ID = JOB_SEQ.nextval;
 
 insert into JOB
   (JOB_ID, WORK_TYPE, NOT_BEFORE)
@@ -247,7 +238,7 @@
 alter table INBOX_CLEANUP_WORK
     drop column NOT_BEFORE;
 alter table INBOX_CLEANUP_WORK
-    add constraint foreign key (JOB_ID) references JOB;
+    modify ("JOB_ID" integer default null references JOB);
 
 create index INBOX_CLEANUP_WORK_JO_799132bd on INBOX_CLEANUP_WORK (
     JOB_ID
@@ -257,7 +248,7 @@
 -- CLEANUP_ONE_INBOX_WORK --
 alter table CLEANUP_ONE_INBOX_WORK
     add ("JOB_ID" integer default 0 not null);
-update CLEANUP_ONE_INBOX_WORK set JOB_ID = JOB_SEQ.nextval
+update CLEANUP_ONE_INBOX_WORK set JOB_ID = JOB_SEQ.nextval;
 
 insert into JOB
   (JOB_ID, WORK_TYPE, NOT_BEFORE)
@@ -266,7 +257,7 @@
 alter table CLEANUP_ONE_INBOX_WORK
     drop column NOT_BEFORE;
 alter table CLEANUP_ONE_INBOX_WORK
-    add constraint foreign key (JOB_ID) references JOB;
+    modify ("JOB_ID" integer default null references JOB);
 
 create index CLEANUP_ONE_INBOX_WOR_375dac36 on CLEANUP_ONE_INBOX_WORK (
     JOB_ID
@@ -276,7 +267,7 @@
 -- SCHEDULE_REFRESH_WORK --
 alter table SCHEDULE_REFRESH_WORK
     add ("JOB_ID" integer default 0 not null);
-update SCHEDULE_REFRESH_WORK set JOB_ID = JOB_SEQ.nextval
+update SCHEDULE_REFRESH_WORK set JOB_ID = JOB_SEQ.nextval;
 
 insert into JOB
   (JOB_ID, WORK_TYPE, NOT_BEFORE)
@@ -285,7 +276,7 @@
 alter table SCHEDULE_REFRESH_WORK
     drop column NOT_BEFORE;
 alter table SCHEDULE_REFRESH_WORK
-    add constraint foreign key (JOB_ID) references JOB;
+    modify ("JOB_ID" integer default null references JOB);
 
 create index SCHEDULE_REFRESH_WORK_3ffa2718 on SCHEDULE_REFRESH_WORK (
     JOB_ID
@@ -295,7 +286,7 @@
 -- SCHEDULE_AUTO_REPLY_WORK --
 alter table SCHEDULE_AUTO_REPLY_WORK
     add ("JOB_ID" integer default 0 not null);
-update SCHEDULE_AUTO_REPLY_WORK set JOB_ID = JOB_SEQ.nextval
+update SCHEDULE_AUTO_REPLY_WORK set JOB_ID = JOB_SEQ.nextval;
 
 insert into JOB
   (JOB_ID, WORK_TYPE, NOT_BEFORE)
@@ -304,7 +295,7 @@
 alter table SCHEDULE_AUTO_REPLY_WORK
     drop column NOT_BEFORE;
 alter table SCHEDULE_AUTO_REPLY_WORK
-    add constraint foreign key (JOB_ID) references JOB;
+    modify ("JOB_ID" integer default null references JOB);
 
 create index SCHEDULE_AUTO_REPLY_W_4d7bb5a8 on SCHEDULE_AUTO_REPLY_WORK (
     JOB_ID
@@ -314,7 +305,7 @@
 -- SCHEDULE_ORGANIZER_WORK --
 alter table SCHEDULE_ORGANIZER_WORK
     add ("JOB_ID" integer default 0 not null);
-update SCHEDULE_ORGANIZER_WORK set JOB_ID = JOB_SEQ.nextval
+update SCHEDULE_ORGANIZER_WORK set JOB_ID = JOB_SEQ.nextval;
 
 insert into JOB
   (JOB_ID, WORK_TYPE, NOT_BEFORE)
@@ -323,7 +314,7 @@
 alter table SCHEDULE_ORGANIZER_WORK
     drop column NOT_BEFORE;
 alter table SCHEDULE_ORGANIZER_WORK
-    add constraint foreign key (JOB_ID) references JOB;
+    modify ("JOB_ID" integer default null references JOB);
 
 create index SCHEDULE_ORGANIZER_WO_1e9f246d on SCHEDULE_ORGANIZER_WORK (
     JOB_ID
@@ -333,7 +324,7 @@
 -- SCHEDULE_REPLY_WORK --
 alter table SCHEDULE_REPLY_WORK
     add ("JOB_ID" integer default 0 not null);
-update SCHEDULE_REPLY_WORK set JOB_ID = JOB_SEQ.nextval
+update SCHEDULE_REPLY_WORK set JOB_ID = JOB_SEQ.nextval;
 
 insert into JOB
   (JOB_ID, WORK_TYPE, NOT_BEFORE)
@@ -342,7 +333,7 @@
 alter table SCHEDULE_REPLY_WORK
     drop column NOT_BEFORE;
 alter table SCHEDULE_REPLY_WORK
-    add constraint foreign key (JOB_ID) references JOB;
+    modify ("JOB_ID" integer default null references JOB);
 
 create index SCHEDULE_REPLY_WORK_J_5913b4a4 on SCHEDULE_REPLY_WORK (
     JOB_ID
@@ -352,7 +343,7 @@
 -- SCHEDULE_REPLY_CANCEL_WORK --
 alter table SCHEDULE_REPLY_CANCEL_WORK
     add ("JOB_ID" integer default 0 not null);
-update SCHEDULE_REPLY_CANCEL_WORK set JOB_ID = JOB_SEQ.nextval
+update SCHEDULE_REPLY_CANCEL_WORK set JOB_ID = JOB_SEQ.nextval;
 
 insert into JOB
   (JOB_ID, WORK_TYPE, NOT_BEFORE)
@@ -361,7 +352,7 @@
 alter table SCHEDULE_REPLY_CANCEL_WORK
     drop column NOT_BEFORE;
 alter table SCHEDULE_REPLY_CANCEL_WORK
-    add constraint foreign key (JOB_ID) references JOB;
+    modify ("JOB_ID" integer default null references JOB);
 
 create index SCHEDULE_REPLY_CANCEL_94a0c766 on SCHEDULE_REPLY_CANCEL_WORK (
     JOB_ID

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_41_to_42.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_41_to_42.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_41_to_42.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -23,11 +23,13 @@
 -----------------
 
 alter table JOB
-  modify ("NOT_BEFORE" timestamp not null)
+  modify ("NOT_BEFORE" timestamp not null);
+
+alter table JOB
   add ("FAILED" integer default 0);
 
 alter table JOB
-  rename column NOT_AFTER to ASSIGNED;
+  rename column "NOT_AFTER" to "ASSIGNED";
 
 -- update the version
 update CALENDARSERVER set VALUE = '42' where NAME = 'VERSION';

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_43_to_44.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_43_to_44.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_43_to_44.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -18,12 +18,6 @@
 -- Upgrade database schema from VERSION 43 to 44 --
 ---------------------------------------------------
 
------------------
--- Job Changes --
------------------
-
-drop function next_job;
-
 -- The scheduling work schema has changed a lot - to avoid a complex migration process this
 -- script just drops all the existing tables and adds back the new set
 

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_45_to_46.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_45_to_46.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_45_to_46.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -24,20 +24,22 @@
 drop table GROUP_ATTENDEE_RECONCILE_WORK;
 
 create table GROUP_ATTENDEE_RECONCILE_WORK (
-  WORK_ID                       integer primary key default nextval('WORKITEM_SEQ') not null, -- implicit index
-  JOB_ID                        integer not null references JOB,
-  RESOURCE_ID                   integer not null references CALENDAR_OBJECT on delete cascade,
-  GROUP_ID                      integer not null references GROUPS on delete cascade
+    "WORK_ID" integer primary key not null,
+    "JOB_ID" integer not null references JOB,
+    "RESOURCE_ID" integer not null references CALENDAR_OBJECT on delete cascade,
+    "GROUP_ID" integer not null references GROUPS on delete cascade
 );
 
-create index GROUP_ATTENDEE_RECONCILE_WORK_JOB_ID on GROUP_ATTENDEE_RECONCILE_WORK(
-	JOB_ID
+create index GROUP_ATTENDEE_RECONC_da73d3c2 on GROUP_ATTENDEE_RECONCILE_WORK (
+    JOB_ID
 );
-create index GROUP_ATTENDEE_RECONCILE_WORK_RESOURCE_ID on GROUP_ATTENDEE_RECONCILE_WORK(
-	RESOURCE_ID
+
+create index GROUP_ATTENDEE_RECONC_b894ee7a on GROUP_ATTENDEE_RECONCILE_WORK (
+    RESOURCE_ID
 );
-create index GROUP_ATTENDEE_RECONCILE_WORK_GROUP_ID on GROUP_ATTENDEE_RECONCILE_WORK(
-	GROUP_ID
+
+create index GROUP_ATTENDEE_RECONC_5eabc549 on GROUP_ATTENDEE_RECONCILE_WORK (
+    GROUP_ID
 );
 
   
@@ -49,34 +51,35 @@
 
 
 create table GROUP_SHAREE_RECONCILE_WORK (
-  WORK_ID                       integer primary key default nextval('WORKITEM_SEQ') not null, -- implicit index
-  JOB_ID                        integer not null references JOB,
-  CALENDAR_ID                   integer	not null references CALENDAR on delete cascade,
-  GROUP_ID                      integer not null references GROUPS on delete cascade
+    "WORK_ID" integer primary key not null,
+    "JOB_ID" integer not null references JOB,
+    "CALENDAR_ID" integer not null references CALENDAR on delete cascade,
+    "GROUP_ID" integer not null references GROUPS on delete cascade
 );
 
-create index GROUP_SHAREE_RECONCILE_WORK_JOB_ID on GROUP_SHAREE_RECONCILE_WORK(
-	JOB_ID
+create index GROUP_SHAREE_RECONCIL_9aad0858 on GROUP_SHAREE_RECONCILE_WORK (
+    JOB_ID
 );
-create index GROUP_SHAREE_RECONCILE_WORK_CALENDAR_ID on GROUP_SHAREE_RECONCILE_WORK(
-	CALENDAR_ID
+
+create index GROUP_SHAREE_RECONCIL_4dc60f78 on GROUP_SHAREE_RECONCILE_WORK (
+    CALENDAR_ID
 );
-create index GROUP_SHAREE_RECONCILE_WORK_GROUP_ID on GROUP_SHAREE_RECONCILE_WORK(
-	GROUP_ID
+
+create index GROUP_SHAREE_RECONCIL_1d14c921 on GROUP_SHAREE_RECONCILE_WORK (
+    GROUP_ID
 );
 
 
 create table GROUP_SHAREE (
-  GROUP_ID                      integer not null references GROUPS on delete cascade,
-  CALENDAR_ID      				integer not null references CALENDAR on delete cascade,
-  GROUP_BIND_MODE               integer not null, -- enum CALENDAR_BIND_MODE
-  MEMBERSHIP_HASH               varchar(255) not null,
-  
-  primary key (GROUP_ID, CALENDAR_ID) -- implicit index
+    "GROUP_ID" integer not null references GROUPS on delete cascade,
+    "CALENDAR_ID" integer not null references CALENDAR on delete cascade,
+    "GROUP_BIND_MODE" integer not null,
+    "MEMBERSHIP_HASH" nvarchar2(255), 
+    primary key ("GROUP_ID", "CALENDAR_ID")
 );
 
-create index GROUP_SHAREE_CALENDAR_ID on GROUP_SHAREE(
-	CALENDAR_ID
+create index GROUP_SHAREE_CALENDAR_28a88850 on GROUP_SHAREE (
+    CALENDAR_ID
 );
 
 

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_48_to_49.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_48_to_49.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_48_to_49.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -47,11 +47,11 @@
 );
 
 create index PRINCIPAL_PURGE_CHECK_198388a5 on PRINCIPAL_PURGE_CHECK_WORK (
-    UID
+    "UID"
 );
 
 create index PRINCIPAL_PURGE_WORK__db35cfdc on PRINCIPAL_PURGE_WORK (
-    UID
+    "UID"
 );
 
 

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_49_to_50.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_49_to_50.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_49_to_50.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -31,7 +31,6 @@
         execute immediate 'alter table SCHEDULE_REPLY_WORK drop constraint '|| i.constraint_name;
     end loop;
 end;
-alter table SCHEDULE_REPLY_WORK modify ("RESOURCE_ID" null);
 
 -- Copy over items from existing table about to be dropped
 insert into SCHEDULE_REPLY_WORK

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_4_to_5.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_4_to_5.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_4_to_5.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -18,41 +18,6 @@
 -- Upgrade database schema from VERSION 4 to 5 --
 -------------------------------------------------
 
--- We have changed the hashing schema for index names, so rename
--- all indexes first
-
--- Note that Oracle already suppressed some indexes because they were implicit or invalid
-
---implicit alter index IDX_0_CALENDAR_HOME_OWNER_UID rename to CALENDAR_HOME_OWNER_U_78016c63;
-alter index IDX_1_CALENDAR_HOME_METADATA_R rename to CALENDAR_HOME_METADAT_35a84eec;
-alter index IDX_2_INVITE_INVITE_UID rename to INVITE_INVITE_UID_9b0902ff;
---invalid alter index IDX_3_INVITE_RESOURCE_ID rename to INVITE_RESOURCE_ID_b36ddc23;
---invalid alter index IDX_4_INVITE_HOME_RESOURCE_ID rename to INVITE_HOME_RESOURCE__e9bdf77e;
---implicit alter index IDX_5_NOTIFICATION_HOME_OWNER_ rename to NOTIFICATION_HOME_OWN_401a6203;
-alter index IDX_6_NOTIFICATION_NOTIFICATIO rename to NOTIFICATION_NOTIFICA_f891f5f9;
-alter index IDX_7_NOTIFICATION_NOTIFICATIO rename to NOTIFICATION_NOTIFICA_62daf834;
-alter index IDX_8_CALENDAR_BIND_HOME_RESOU rename to CALENDAR_BIND_HOME_RE_0d980be6;
-alter index IDX_9_CALENDAR_BIND_RESOURCE_I rename to CALENDAR_BIND_RESOURC_e57964d4;
-alter index IDX_10_CALENDAR_OBJECT_CALENDA rename to CALENDAR_OBJECT_CALEN_06694fd0;
-alter index IDX_11_CALENDAR_OBJECT_CALENDA rename to CALENDAR_OBJECT_CALEN_a9a453a9;
-alter index IDX_12_CALENDAR_OBJECT_CALENDA rename to CALENDAR_OBJECT_CALEN_96e83b73;
-alter index IDX_13_CALENDAR_OBJECT_ORGANIZ rename to CALENDAR_OBJECT_ORGAN_7ce24750;
-alter index IDX_14_CALENDAR_OBJECT_DROPBOX rename to CALENDAR_OBJECT_DROPB_de041d80;
-alter index IDX_15_TIME_RANGE_CALENDAR_RES rename to TIME_RANGE_CALENDAR_R_beb6e7eb;
-alter index IDX_16_TIME_RANGE_CALENDAR_OBJ rename to TIME_RANGE_CALENDAR_O_acf37bd1;
-alter index IDX_17_TRANSPARENCY_TIME_RANGE rename to TRANSPARENCY_TIME_RAN_5f34467f;
-alter index IDX_18_ATTACHMENT_DROPBOX_ID rename to ATTACHMENT_DROPBOX_ID_5073cf23;
---implicit alter index IDX_19_ADDRESSBOOK_HOME_OWNER_ rename to ADDRESSBOOK_HOME_OWNE_44f7f53b;
-alter index IDX_20_ADDRESSBOOK_HOME_METADA rename to ADDRESSBOOK_HOME_META_cfe06701;
-alter index IDX_21_ADDRESSBOOK_BIND_HOME_R rename to ADDRESSBOOK_BIND_HOME_6a6dc8ce;
-alter index IDX_22_ADDRESSBOOK_BIND_RESOUR rename to ADDRESSBOOK_BIND_RESO_205aa75c;
-alter index IDX_23_ADDRESSBOOK_OBJECT_ADDR rename to ADDRESSBOOK_OBJECT_AD_1540450d;
-alter index IDX_24_CALENDAR_OBJECT_REVISIO rename to CALENDAR_OBJECT_REVIS_42be4d9e;
-alter index IDX_25_CALENDAR_OBJECT_REVISIO rename to CALENDAR_OBJECT_REVIS_3e41b7f0;
-alter index IDX_26_ADDRESSBOOK_OBJECT_REVI rename to ADDRESSBOOK_OBJECT_RE_5965a9e2;
-alter index IDX_27_ADDRESSBOOK_OBJECT_REVI rename to ADDRESSBOOK_OBJECT_RE_2ab44f33;
-alter index IDX_28_NOTIFICATION_OBJECT_REV rename to NOTIFICATION_OBJECT_R_47002cd8;
-
 -- Changes related to primary key and index optimizations
 
 --implicit drop index CALENDAR_HOME_OWNER_U_78016c63;
@@ -76,15 +41,14 @@
 drop index CALENDAR_OBJECT_CALEN_06694fd0;
 
 drop index ATTACHMENT_DROPBOX_ID_5073cf23;
--- This constraint was not properly translated in original v4 schema
---alter table ATTACHMENT 
--- drop unique(DROPBOX_ID, PATH);
+
+alter table ATTACHMENT 
+ drop unique(DROPBOX_ID, PATH);
 alter table ATTACHMENT
  add primary key(DROPBOX_ID, PATH);
-create index ATTACHMENT_CALENDAR_H_0078845c on
-  ATTACHMENT(CALENDAR_HOME_RESOURCE_ID);
 
---implicit drop index ADDRESSBOOK_HOME_OWNE_44f7f53b;
+ create index ATTACHMENT_CALENDAR_H_0078845c on
+  ATTACHMENT(CALENDAR_HOME_RESOURCE_ID);
   
 drop index ADDRESSBOOK_HOME_META_cfe06701;
 alter table ADDRESSBOOK_HOME_METADATA
@@ -105,45 +69,20 @@
 alter table CALENDARSERVER
  add primary key(NAME);
 
--- Changes to restore multi-column primary key and uniques lost in translation of v4
- 
-alter table NOTIFICATION
- add unique(NOTIFICATION_UID, NOTIFICATION_HOME_RESOURCE_ID);
- 
-alter table CALENDAR_BIND
- add primary key(CALENDAR_HOME_RESOURCE_ID, CALENDAR_RESOURCE_ID);
-alter table CALENDAR_BIND
- add unique(CALENDAR_HOME_RESOURCE_ID, CALENDAR_RESOURCE_NAME);
- 
-alter table CALENDAR_OBJECT
- add unique(CALENDAR_RESOURCE_ID, RESOURCE_NAME);
- 
---alter table ATTACHMENT
--- add primary key(DROPBOX_ID, PATH);
- 
-alter table RESOURCE_PROPERTY
- add primary key(RESOURCE_ID, NAME, VIEWER_UID);
- 
-alter table ADDRESSBOOK_BIND
- add primary key(ADDRESSBOOK_HOME_RESOURCE_ID, ADDRESSBOOK_RESOURCE_ID);
-alter table ADDRESSBOOK_BIND
- add unique(ADDRESSBOOK_HOME_RESOURCE_ID, ADDRESSBOOK_RESOURCE_NAME);
- 
-alter table ADDRESSBOOK_OBJECT
- add unique(ADDRESSBOOK_RESOURCE_ID, RESOURCE_NAME);
-alter table ADDRESSBOOK_OBJECT
- add unique(ADDRESSBOOK_RESOURCE_ID, VCARD_UID);
- 
-create index CALENDAR_OBJECT_REVIS_2643d556
-  on CALENDAR_OBJECT_REVISIONS(CALENDAR_RESOURCE_ID, RESOURCE_NAME);
- 
-create index ADDRESSBOOK_OBJECT_RE_9a848f39
-  on ADDRESSBOOK_OBJECT_REVISIONS(ADDRESSBOOK_RESOURCE_ID, RESOURCE_NAME);
- 
-alter table NOTIFICATION_OBJECT_REVISIONS
- add unique(NOTIFICATION_HOME_RESOURCE_ID, RESOURCE_NAME);
- 
+alter table CALENDAR_OBJECT_REVISIONS 
+ drop unique(CALENDAR_RESOURCE_ID, RESOURCE_NAME);
+create index CALENDAR_OBJECT_REVIS_2643d556 on CALENDAR_OBJECT_REVISIONS (
+    CALENDAR_RESOURCE_ID,
+    RESOURCE_NAME
+);
 
+alter table ADDRESSBOOK_OBJECT_REVISIONS 
+ drop unique(ADDRESSBOOK_RESOURCE_ID, RESOURCE_NAME);
+create index ADDRESSBOOK_OBJECT_RE_9a848f39 on ADDRESSBOOK_OBJECT_REVISIONS (
+    ADDRESSBOOK_RESOURCE_ID,
+    RESOURCE_NAME
+);
+
 -- Now update the version
 update CALENDARSERVER set VALUE = '5' where NAME = 'VERSION';
 

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_51_to_52.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_51_to_52.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_51_to_52.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -40,15 +40,18 @@
 
 -- Change columns
 alter table CALENDAR_BIND
-	drop column EXTERNAL_ID
+	drop column EXTERNAL_ID;
+alter table CALENDAR_BIND
 	add ("BIND_UID" nvarchar2(36) default null);
 
 alter table SHARED_ADDRESSBOOK_BIND
-	drop column EXTERNAL_ID
+	drop column EXTERNAL_ID;
+alter table SHARED_ADDRESSBOOK_BIND
 	add ("BIND_UID" nvarchar2(36) default null);
 
 alter table SHARED_GROUP_BIND
-	drop column EXTERNAL_ID
+	drop column EXTERNAL_ID;
+alter table SHARED_GROUP_BIND
 	add ("BIND_UID" nvarchar2(36) default null);
 
 

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_52_to_53.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_52_to_53.sql	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_52_to_53.sql	2015-03-16 03:04:19 UTC (rev 14598)
@@ -53,7 +53,7 @@
 
 -- New columns
 alter table ADDRESSBOOK_OBJECT
-  add ("TRASHED" timestamp default null),
+  add ("TRASHED" timestamp default null)
   add ("IS_IN_TRASH" integer default 0 not null);
 
 

Added: CalendarServer/trunk/txdav/common/datastore/test/test_oracle_sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/test/test_oracle_sql.py	                        (rev 0)
+++ CalendarServer/trunk/txdav/common/datastore/test/test_oracle_sql.py	2015-03-16 03:04:19 UTC (rev 14598)
@@ -0,0 +1,92 @@
+##
+# Copyright (c) 2012-2015 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+Tests for L{txdav.common.datastore.sql}.
+"""
+
+from twext.enterprise.dal.syntax import Select, Insert, Delete
+from twisted.internet.defer import inlineCallbacks
+from twisted.trial.unittest import TestCase
+from txdav.common.datastore.sql_tables import schema
+from txdav.common.datastore.test.util import CommonCommonTests
+
+
+class OracleSpecificSQLStoreTests(CommonCommonTests, TestCase):
+    """
+    Tests for shared functionality in L{txdav.common.datastore.sql}.
+    """
+
+    @inlineCallbacks
+    def setUp(self):
+        """
+        Set up two stores to migrate between.
+        """
+        yield super(OracleSpecificSQLStoreTests, self).setUp()
+        yield self.buildStoreAndDirectory()
+
+
+    @inlineCallbacks
+    def test_logging(self):
+        """
+        txn.execSQL works with all logging options on.
+        """
+
+        # Patch config to turn on logging then rebuild the store
+        self.patch(self.store, "logLabels", True)
+        self.patch(self.store, "logStats", True)
+        self.patch(self.store, "logSQL", True)
+
+        txn = self.transactionUnderTest()
+        cs = schema.CALENDARSERVER
+        version = (yield Select(
+            [cs.VALUE],
+            From=cs,
+            Where=cs.NAME == "VERSION",
+        ).on(txn))
+        self.assertNotEqual(version, None)
+        self.assertEqual(len(version), 1)
+        self.assertEqual(len(version[0]), 1)
+
+
+    @inlineCallbacks
+    def test_delete_returning(self):
+        """
+        txn.execSQL works with all logging options on.
+        """
+
+        txn = self.transactionUnderTest()
+        cs = schema.CALENDARSERVER
+        yield Insert(
+            {cs.NAME: "TEST", cs.VALUE: "Value"},
+        ).on(txn)
+        yield self.commit()
+
+        txn = self.transactionUnderTest()
+        value = yield Delete(
+            From=cs,
+            Where=(cs.NAME == "TEST"),
+            Return=cs.VALUE,
+        ).on(txn)
+        self.assertEqual(list(value), [["Value"]])
+
+        txn = self.transactionUnderTest()
+        value = yield Delete(
+            From=cs,
+            Where=(cs.NAME == "TEST"),
+            Return=cs.VALUE,
+        ).on(txn)
+        self.assertEqual(list(value), [])

Modified: CalendarServer/trunk/txdav/common/datastore/test/test_sql_dump.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/test/test_sql_dump.py	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/test/test_sql_dump.py	2015-03-16 03:04:19 UTC (rev 14598)
@@ -14,37 +14,51 @@
 # limitations under the License.
 ##
 
-from txdav.common.datastore.sql_dump import dumpSchema
-from twext.enterprise.dal.parseschema import schemaFromString
 
 """
 Tests for L{txdav.common.datastore.upgrade.sql.upgrade}.
 """
 
+from twext.enterprise.dal.parseschema import schemaFromString
+from twext.enterprise.ienterprise import POSTGRES_DIALECT
 from twisted.internet.defer import inlineCallbacks
 from twisted.trial.unittest import TestCase
-from txdav.common.datastore.test.util import theStoreBuilder, \
-    StubNotifierFactory
+from txdav.base.datastore.suboracle import cleanDatabase
+from txdav.common.datastore.sql_dump import dumpSchema
+from txdav.common.datastore.test.util import StubNotifierFactory, SQLStoreBuilder,\
+    DB_TYPE, theStoreBuilder
 
 class SQLDump(TestCase):
     """
     Tests for L{sql_dump}.
     """
 
+    def __init__(self, methodName='runTest'):
+        super(SQLDump, self).__init__(methodName)
+        if DB_TYPE[0] == POSTGRES_DIALECT:
+            self.testStoreBuilder = theStoreBuilder
+        else:
+            self.testStoreBuilder = SQLStoreBuilder(dsnUser="test_dbUpgrades", noCleanup=True)
+
+
     @inlineCallbacks
     def setUp(self):
         TestCase.setUp(self)
 
-        self.store = yield theStoreBuilder.buildStore(
+        self.store = yield self.testStoreBuilder.buildStore(
             self, {"push": StubNotifierFactory()}, enableJobProcessing=False
         )
 
 
     @inlineCallbacks
     def cleanUp(self):
-        startTxn = self.store.newTransaction("test_sql_dump")
-        yield startTxn.execSQL("set search_path to public;")
-        yield startTxn.execSQL("drop schema test_sql_dump cascade;")
+        startTxn = self.store.newTransaction("test_dbUpgrades")
+        if startTxn.dialect == POSTGRES_DIALECT:
+            yield startTxn.execSQL("set search_path to public")
+            yield startTxn.execSQL("drop schema test_dbUpgrades cascade")
+        else:
+            yield cleanDatabase(startTxn)
+
         yield startTxn.commit()
 
 
@@ -54,10 +68,11 @@
         Use the postgres schema mechanism to do tests under a separate "namespace"
         in postgres that we can quickly wipe clean afterwards.
         """
-        startTxn = self.store.newTransaction("test_sql_dump")
-        yield startTxn.execSQL("create schema test_sql_dump;")
-        yield startTxn.execSQL("set search_path to test_sql_dump;")
-        yield startTxn.execSQL(schema)
+        startTxn = self.store.newTransaction("test_dbUpgrades")
+        if startTxn.dialect == POSTGRES_DIALECT:
+            yield startTxn.execSQL("create schema test_dbUpgrades")
+            yield startTxn.execSQL("set search_path to test_dbUpgrades")
+        yield startTxn.execSQLBlock(schema)
         yield startTxn.commit()
 
         self.addCleanup(self.cleanUp)
@@ -70,7 +85,7 @@
         yield self._loadSchema(schema)
 
         txn = self.store.newTransaction("loadData")
-        dumped = yield dumpSchema(txn, "test", schemaname="test_sql_dump")
+        dumped = yield dumpSchema(txn, "test", schemaname="test_dbUpgrades")
         yield txn.commit()
 
         parsed = schemaFromString(schema)
@@ -218,3 +233,130 @@
 """
 
         yield self._schemaCheck(schema, schema_bad)
+
+
+    @inlineCallbacks
+    def test_timestamp_table(self):
+
+        schema = """
+CREATE TABLE FOO (
+    ID1 integer primary key,
+    ID2 timestamp default timezone('UTC', CURRENT_TIMESTAMP)
+);
+""" if DB_TYPE[0] == POSTGRES_DIALECT else """
+CREATE TABLE FOO (
+    ID1 integer primary key,
+    ID2 timestamp default CURRENT_TIMESTAMP at time zone 'UTC'
+);
+"""
+
+        schema_bad = """
+CREATE TABLE FOO (
+    ID1 integer primary key default 0,
+    ID2 timestamp
+);
+"""
+
+        yield self._schemaCheck(schema, schema_bad)
+
+
+    @inlineCallbacks
+    def test_references_table(self):
+
+        schema = """
+CREATE TABLE FOO (
+    ID1 integer primary key,
+    ID2 text default null
+);
+CREATE TABLE BAR (
+    ID1 integer references FOO on delete cascade,
+    ID2 integer
+);
+CREATE TABLE BAZ (
+    ID1 integer references FOO,
+    ID2 integer
+);
+""" if DB_TYPE[0] == POSTGRES_DIALECT else """
+CREATE TABLE FOO (
+    ID1 integer primary key,
+    ID2 nclob default null
+);
+CREATE TABLE BAR (
+    ID1 integer references FOO on delete cascade,
+    ID2 integer
+);
+CREATE TABLE BAZ (
+    ID1 integer references FOO,
+    ID2 integer
+);
+"""
+        schema_bad = """
+CREATE TABLE FOO (
+    ID1 integer primary key default 0,
+    ID2 timestamp
+);
+CREATE TABLE BAR (
+    ID1 integer references FOO,
+    ID2 integer
+);
+CREATE TABLE BAZ (
+    ID1 integer references FOO on delete cascade,
+    ID2 integer
+);
+"""
+
+        yield self._schemaCheck(schema, schema_bad)
+
+
+    @inlineCallbacks
+    def test_index_table(self):
+
+        schema = """
+CREATE TABLE FOO (
+    ID1 integer not null,
+    ID2 integer not null,
+
+    primary key (ID1)
+);
+
+create index FOOINDEX on FOO (ID1, ID2);
+"""
+
+        schema_bad = """
+CREATE TABLE FOO (
+    ID1 integer,
+    ID2 integer,
+
+    primary key (ID1)
+);
+create index FOOINDEX on FOO (ID2, ID1);
+"""
+
+        yield self._schemaCheck(schema, schema_bad)
+
+
+    @inlineCallbacks
+    def test_unique_index_table(self):
+
+        schema = """
+CREATE TABLE FOO (
+    ID1 integer not null,
+    ID2 integer not null,
+
+    primary key (ID1)
+);
+
+create unique index FOOINDEX on FOO(ID1, ID2);
+"""
+
+        schema_bad = """
+CREATE TABLE FOO (
+    ID1 integer,
+    ID2 integer,
+
+    primary key (ID1)
+);
+create index FOOINDEX on FOO(ID1, ID2);
+"""
+
+        yield self._schemaCheck(schema, schema_bad)

Modified: CalendarServer/trunk/txdav/common/datastore/test/util.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/test/util.py	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/test/util.py	2015-03-16 03:04:19 UTC (rev 14598)
@@ -35,7 +35,8 @@
 from twext.python.log import Logger
 from twext.python.filepath import CachingFilePath as FilePath
 from twext.enterprise.adbapi2 import ConnectionPool
-from twext.enterprise.ienterprise import AlreadyFinishedError
+from twext.enterprise.ienterprise import AlreadyFinishedError, POSTGRES_DIALECT, \
+    ORACLE_DIALECT
 from twext.enterprise.jobqueue import PeerConnectionPool, JobItem
 from twext.who.directory import DirectoryRecord
 
@@ -54,6 +55,7 @@
 
 from txdav.base.datastore.dbapiclient import DiagnosticConnectionWrapper
 from txdav.base.datastore.subpostgres import PostgresService
+from txdav.base.datastore.suboracle import OracleService
 from txdav.base.propertystore.base import PropertyName
 from txdav.caldav.icalendarstore import ComponentUpdateState
 from txdav.common.datastore.sql import CommonDataStore, current_sql_schema
@@ -70,6 +72,8 @@
 import gc
 
 
+DB_TYPE = (POSTGRES_DIALECT, "pyformat", "current.sql",)
+#DB_TYPE = (ORACLE_DIALECT, "numeric", "current-oracle-dialect.sql",)
 
 log = Logger()
 
@@ -105,7 +109,7 @@
     """
     Test-fixture-builder which can construct a PostgresStore.
     """
-    def __init__(self, count=0):
+    def __init__(self, count=0, **options):
         self.sharedService = None
         self.currentTestID = None
         self.ampPort = config.WorkQueue.ampPort + count
@@ -114,26 +118,35 @@
             os.getpid(), count
         )
 
+        self.options = options
 
+
     def createService(self, serviceFactory):
         """
         Create a L{PostgresService} to use for building a store.
         """
         dbRoot = FilePath(self.sharedDBPath)
-        return PostgresService(
-            dbRoot, serviceFactory, current_sql_schema, resetSchema=True,
-            databaseName="caldav",
-            options=[
-                "-c log_lock_waits=TRUE",
-                "-c log_statement=all",
-                "-c log_line_prefix='%p.%x '",
-                "-c fsync=FALSE",
-                "-c synchronous_commit=off",
-                "-c full_page_writes=FALSE",
-                "-c client-min-messages=warning",
-            ],
-            testMode=True
-        )
+        if DB_TYPE[0] == POSTGRES_DIALECT:
+            return PostgresService(
+                dbRoot, serviceFactory, current_sql_schema, resetSchema=True,
+                databaseName="caldav",
+                options=[
+                    "-c log_lock_waits=TRUE",
+                    "-c log_statement=all",
+                    "-c log_line_prefix='%p.%x '",
+                    "-c fsync=FALSE",
+                    "-c synchronous_commit=off",
+                    "-c full_page_writes=FALSE",
+                    "-c client-min-messages=warning",
+                ],
+                testMode=True
+            )
+        elif DB_TYPE[0] == ORACLE_DIALECT:
+            return OracleService(
+                dbRoot, serviceFactory,
+                testMode=True,
+                dsnUser=self.options.get("dsnUser"),
+            )
 
 
     def childStore(self):
@@ -146,7 +159,12 @@
         attachmentRoot = (FilePath(self.sharedDBPath).child("attachments"))
         stubsvc = self.createService(lambda cf: Service())
 
-        cp = ConnectionPool(stubsvc.produceConnection, maxConnections=1)
+        cp = ConnectionPool(
+            stubsvc.produceConnection,
+            maxConnections=1,
+            dialect=DB_TYPE[0],
+            paramstyle=DB_TYPE[1],
+        )
         # Attach the service to the running reactor.
         cp.startService()
         reactor.addSystemEventTrigger("before", "shutdown", cp.stopService)
@@ -231,7 +249,10 @@
 
         currentTestID = testCase.id()
         cp = ConnectionPool(
-            self.sharedService.produceConnection, maxConnections=4
+            self.sharedService.produceConnection,
+            maxConnections=4,
+            dialect=DB_TYPE[0],
+            paramstyle=DB_TYPE[1],
         )
         quota = deriveQuota(testCase)
         store = CommonDataStore(
@@ -250,12 +271,14 @@
 
         @inlineCallbacks
         def stopIt():
-            txn = store.newTransaction()
-            jobs = yield JobItem.all(txn)
-            yield txn.commit()
 
             if enableJobProcessing:
+                txn = store.newTransaction()
+                jobs = yield JobItem.all(txn)
+                yield txn.commit()
                 yield pool.stopService()
+            else:
+                jobs = ()
 
             # active transactions should have been shut down.
             wasBusy = len(cp._busy)
@@ -293,6 +316,9 @@
     @inlineCallbacks
     def cleanStore(self, testCase, storeToClean):
 
+        if "noCleanup" in self.options:
+            returnValue(None)
+
         cleanupTxn = storeToClean.sqlTxnFactory(
             "%s schema-cleanup" % (testCase.id(),)
         )
@@ -318,8 +344,13 @@
         # Change the starting values of sequences to random values
         for sequence in schema.model.sequences: #@UndefinedVariable
             try:
-                curval = (yield cleanupTxn.execSQL("select nextval('{}')".format(sequence.name), []))[0][0]
-                yield cleanupTxn.execSQL("select setval('{}', {})".format(sequence.name, curval + randint(1, 10000)), [])
+                if cleanupTxn.dialect == POSTGRES_DIALECT:
+                    curval = (yield cleanupTxn.execSQL("select nextval('{}')".format(sequence.name), []))[0][0]
+                    yield cleanupTxn.execSQL("select setval('{}', {})".format(sequence.name, curval + randint(1, 10000)), [])
+                elif cleanupTxn.dialect == ORACLE_DIALECT:
+                    yield cleanupTxn.execSQL("alter sequence {} increment by {}".format(sequence.name, randint(1, 10000)), [])
+                    yield cleanupTxn.execSQL("select {}.nextval from dual".format(sequence.name), [])
+                    yield cleanupTxn.execSQL("alter sequence {} increment by {}".format(sequence.name, 1), [])
             except:
                 log.failure("setval sequence '{}' failed", sequence=sequence.name)
         yield cleanupTxn.execSQL("update CALENDARSERVER set VALUE = '1' where NAME = 'MIN-VALID-REVISION'", [])

Modified: CalendarServer/trunk/txdav/common/datastore/upgrade/sql/test/test_upgrade.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/upgrade/sql/test/test_upgrade.py	2015-03-16 03:01:36 UTC (rev 14597)
+++ CalendarServer/trunk/txdav/common/datastore/upgrade/sql/test/test_upgrade.py	2015-03-16 03:04:19 UTC (rev 14598)
@@ -23,8 +23,10 @@
 from twisted.internet.defer import inlineCallbacks, returnValue
 from twisted.python.modules import getModule
 from twisted.trial.unittest import TestCase
+from txdav.base.datastore.suboracle import cleanDatabase
 from txdav.common.datastore.sql_dump import dumpSchema
-from txdav.common.datastore.test.util import theStoreBuilder, StubNotifierFactory
+from txdav.common.datastore.test.util import StubNotifierFactory, SQLStoreBuilder, \
+    DB_TYPE, theStoreBuilder
 from txdav.common.datastore.upgrade.sql.upgrade import (
     UpgradeDatabaseSchemaStep, UpgradeDatabaseAddressBookDataStep, UpgradeDatabaseCalendarDataStep, NotAllowedToUpgrade)
 import re
@@ -34,6 +36,14 @@
     Tests for L{UpgradeDatabaseSchemaStep}.
     """
 
+    def __init__(self, methodName='runTest'):
+        super(SchemaUpgradeTests, self).__init__(methodName)
+        if DB_TYPE[0] == POSTGRES_DIALECT:
+            self.testStoreBuilder = theStoreBuilder
+        else:
+            self.testStoreBuilder = SQLStoreBuilder(dsnUser="test_dbUpgrades", noCleanup=True)
+
+
     @staticmethod
     def _getRawSchemaVersion(fp, versionKey):
         schema = fp.getContent()
@@ -121,7 +131,7 @@
             upgrader = UpgradeDatabaseSchemaStep(None)
             files = upgrader.scanForUpgradeFiles(dialect)
 
-            current_version = self._getSchemaVersion(upgrader.schemaLocation.child("current.sql"), "VERSION")
+            current_version = self._getSchemaVersion(upgrader.schemaLocation.child(DB_TYPE[2]), "VERSION")
 
             for child in upgrader.schemaLocation.child("old").child(dialect).globChildren("*.sql"):
                 old_version = self._getSchemaVersion(child, "VERSION")
@@ -150,7 +160,7 @@
         postgres.
         """
 
-        store = yield theStoreBuilder.buildStore(
+        store = yield self.testStoreBuilder.buildStore(
             self, {"push": StubNotifierFactory()}, enableJobProcessing=False
         )
 
@@ -161,15 +171,16 @@
             in postgres that we can quickly wipe clean afterwards.
             """
             startTxn = store.newTransaction("test_dbUpgrades")
-            yield startTxn.execSQL("create schema test_dbUpgrades;")
-            yield startTxn.execSQL("set search_path to test_dbUpgrades;")
+            if startTxn.dialect == POSTGRES_DIALECT:
+                yield startTxn.execSQL("create schema test_dbUpgrades")
+                yield startTxn.execSQL("set search_path to test_dbUpgrades")
             yield startTxn.execSQLBlock(path.getContent())
             yield startTxn.commit()
 
         @inlineCallbacks
         def _loadVersion():
             startTxn = store.newTransaction("test_dbUpgrades")
-            new_version = yield startTxn.execSQL("select value from calendarserver where name = 'VERSION';")
+            new_version = yield startTxn.execSQL("select value from calendarserver where name = 'VERSION'")
             yield startTxn.commit()
             returnValue(int(new_version[0][0]))
 
@@ -183,21 +194,27 @@
         @inlineCallbacks
         def _unloadOldSchema():
             startTxn = store.newTransaction("test_dbUpgrades")
-            yield startTxn.execSQL("set search_path to public;")
-            yield startTxn.execSQL("drop schema test_dbUpgrades cascade;")
+            if startTxn.dialect == POSTGRES_DIALECT:
+                yield startTxn.execSQL("set search_path to public")
+                yield startTxn.execSQL("drop schema test_dbUpgrades cascade")
+            elif startTxn.dialect == ORACLE_DIALECT:
+                yield cleanDatabase(startTxn)
             yield startTxn.commit()
 
         @inlineCallbacks
         def _cleanupOldSchema():
             startTxn = store.newTransaction("test_dbUpgrades")
-            yield startTxn.execSQL("set search_path to public;")
-            yield startTxn.execSQL("drop schema if exists test_dbUpgrades cascade;")
+            if startTxn.dialect == POSTGRES_DIALECT:
+                yield startTxn.execSQL("set search_path to public")
+                yield startTxn.execSQL("drop schema if exists test_dbUpgrades cascade")
+            elif startTxn.dialect == ORACLE_DIALECT:
+                yield cleanDatabase(startTxn)
             yield startTxn.commit()
 
         self.addCleanup(_cleanupOldSchema)
 
         test_upgrader = UpgradeDatabaseSchemaStep(None)
-        expected_version = self._getSchemaVersion(test_upgrader.schemaLocation.child("current.sql"), "VERSION")
+        expected_version = self._getSchemaVersion(test_upgrader.schemaLocation.child(DB_TYPE[2]), "VERSION")
 
         # Upgrade allowed
         upgrader = UpgradeDatabaseSchemaStep(store)
@@ -207,7 +224,7 @@
 
         # Compare the upgraded schema with the expected current schema
         new_schema = yield _loadSchemaFromDatabase()
-        currentSchema = schemaFromPath(test_upgrader.schemaLocation.child("current.sql"))
+        currentSchema = schemaFromPath(test_upgrader.schemaLocation.child(DB_TYPE[2]))
         mismatched = currentSchema.compare(new_schema)
         # These are special case exceptions
         for i in (
@@ -256,7 +273,7 @@
         store.
         """
 
-        store = yield theStoreBuilder.buildStore(
+        store = yield self.testStoreBuilder.buildStore(
             self, {"push": StubNotifierFactory()}, enableJobProcessing=False
         )
 
@@ -267,41 +284,48 @@
             in postgres that we can quickly wipe clean afterwards.
             """
             startTxn = store.newTransaction("test_dbUpgrades")
-            yield startTxn.execSQL("create schema test_dbUpgrades;")
-            yield startTxn.execSQL("set search_path to test_dbUpgrades;")
+            if startTxn.dialect == POSTGRES_DIALECT:
+                yield startTxn.execSQL("create schema test_dbUpgrades")
+                yield startTxn.execSQL("set search_path to test_dbUpgrades")
             yield startTxn.execSQLBlock(path.getContent())
-            yield startTxn.execSQL("update CALENDARSERVER set VALUE = '%s' where NAME = '%s';" % (oldVersion, versionKey,))
+            yield startTxn.execSQL("update CALENDARSERVER set VALUE = '%s' where NAME = '%s'" % (oldVersion, versionKey,))
             yield startTxn.commit()
 
         @inlineCallbacks
         def _loadVersion():
             startTxn = store.newTransaction("test_dbUpgrades")
-            new_version = yield startTxn.execSQL("select value from calendarserver where name = '%s';" % (versionKey,))
+            new_version = yield startTxn.execSQL("select value from calendarserver where name = '%s'" % (versionKey,))
             yield startTxn.commit()
             returnValue(int(new_version[0][0]))
 
         @inlineCallbacks
         def _unloadOldData():
             startTxn = store.newTransaction("test_dbUpgrades")
-            yield startTxn.execSQL("set search_path to public;")
-            yield startTxn.execSQL("drop schema test_dbUpgrades cascade;")
+            if startTxn.dialect == POSTGRES_DIALECT:
+                yield startTxn.execSQL("set search_path to public")
+                yield startTxn.execSQL("drop schema test_dbUpgrades cascade")
+            elif startTxn.dialect == ORACLE_DIALECT:
+                yield cleanDatabase(startTxn)
             yield startTxn.commit()
 
         @inlineCallbacks
         def _cleanupOldData():
             startTxn = store.newTransaction("test_dbUpgrades")
-            yield startTxn.execSQL("set search_path to public;")
-            yield startTxn.execSQL("drop schema if exists test_dbUpgrades cascade;")
+            if startTxn.dialect == POSTGRES_DIALECT:
+                yield startTxn.execSQL("set search_path to public")
+                yield startTxn.execSQL("drop schema if exists test_dbUpgrades cascade")
+            elif startTxn.dialect == ORACLE_DIALECT:
+                yield cleanDatabase(startTxn)
             yield startTxn.commit()
 
         self.addCleanup(_cleanupOldData)
 
         test_upgrader = UpgradeDatabaseSchemaStep(None)
-        expected_version = self._getSchemaVersion(test_upgrader.schemaLocation.child("current.sql"), versionKey)
+        expected_version = self._getSchemaVersion(test_upgrader.schemaLocation.child(DB_TYPE[2]), versionKey)
 
         oldVersion = version
         upgrader = upgraderClass(store)
-        yield _loadOldData(test_upgrader.schemaLocation.child("current.sql"), oldVersion)
+        yield _loadOldData(test_upgrader.schemaLocation.child(DB_TYPE[2]), oldVersion)
         yield upgrader.databaseUpgrade()
         new_version = yield _loadVersion()
         yield _unloadOldData()
@@ -311,15 +335,17 @@
 
 test_upgrader = UpgradeDatabaseSchemaStep(None)
 
+DIALECT = DB_TYPE[0]
+
 # Bind test methods for each schema version
-for child in test_upgrader.schemaLocation.child("old").child(POSTGRES_DIALECT).globChildren("*.sql"):
+for child in test_upgrader.schemaLocation.child("old").child(DIALECT).globChildren("*.sql"):
     def f(self, lchild=child):
         return self._dbSchemaUpgrades(lchild)
     setattr(SchemaUpgradeTests, "test_dbSchemaUpgrades_%s" % (child.basename().split(".", 1)[0],), f)
 
 # Bind test methods for each addressbook data version
 versions = set()
-for child in test_upgrader.schemaLocation.child("old").child(POSTGRES_DIALECT).globChildren("*.sql"):
+for child in test_upgrader.schemaLocation.child("old").child(DIALECT).globChildren("*.sql"):
     version = SchemaUpgradeTests._getRawSchemaVersion(child, "ADDRESSBOOK-DATAVERSION")
     versions.add(version if version else 1)
 for version in sorted(versions):
@@ -329,7 +355,7 @@
 
 # Bind test methods for each calendar data version
 versions = set()
-for child in test_upgrader.schemaLocation.child("old").child(POSTGRES_DIALECT).globChildren("*.sql"):
+for child in test_upgrader.schemaLocation.child("old").child(DIALECT).globChildren("*.sql"):
     version = SchemaUpgradeTests._getRawSchemaVersion(child, "CALENDAR-DATAVERSION")
     versions.add(version if version else 1)
 for version in sorted(versions):
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20150315/5b28f3ce/attachment-0001.html>


More information about the calendarserver-changes mailing list