diff rhodecode/lib/dbmigrate/migrate/changeset/databases/oracle.py @ 833:9753e0907827 beta

added dbmigrate package, added model changes moved out upgrade db command to that package
author Marcin Kuzminski <marcin@python-works.com>
date Sat, 11 Dec 2010 01:54:12 +0100
parents
children 08d2dcd71666
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rhodecode/lib/dbmigrate/migrate/changeset/databases/oracle.py	Sat Dec 11 01:54:12 2010 +0100
@@ -0,0 +1,111 @@
+"""
+   Oracle database specific implementations of changeset classes.
+"""
+import sqlalchemy as sa
+from sqlalchemy.databases import oracle as sa_base
+
+from migrate import exceptions
+from migrate.changeset import ansisql, SQLA_06
+
+
+if not SQLA_06:
+    OracleSchemaGenerator = sa_base.OracleSchemaGenerator
+else:
+    OracleSchemaGenerator = sa_base.OracleDDLCompiler
+
+
+class OracleColumnGenerator(OracleSchemaGenerator, ansisql.ANSIColumnGenerator):
+    pass
+
+
+class OracleColumnDropper(ansisql.ANSIColumnDropper):
+    pass
+
+
+class OracleSchemaChanger(OracleSchemaGenerator, ansisql.ANSISchemaChanger):
+
+    def get_column_specification(self, column, **kwargs):
+        # Ignore the NOT NULL generated
+        override_nullable = kwargs.pop('override_nullable', None)
+        if override_nullable:
+            orig = column.nullable
+            column.nullable = True
+        ret = super(OracleSchemaChanger, self).get_column_specification(
+            column, **kwargs)
+        if override_nullable:
+            column.nullable = orig
+        return ret
+
+    def visit_column(self, delta):
+        keys = delta.keys()
+
+        if 'name' in keys:
+            self._run_subvisit(delta,
+                               self._visit_column_name,
+                               start_alter=False)
+
+        if len(set(('type', 'nullable', 'server_default')).intersection(keys)):
+            self._run_subvisit(delta,
+                               self._visit_column_change,
+                               start_alter=False)
+
+    def _visit_column_change(self, table, column, delta):
+        # Oracle cannot drop a default once created, but it can set it
+        # to null.  We'll do that if default=None
+        # http://forums.oracle.com/forums/message.jspa?messageID=1273234#1273234
+        dropdefault_hack = (column.server_default is None \
+                                and 'server_default' in delta.keys())
+        # Oracle apparently doesn't like it when we say "not null" if
+        # the column's already not null. Fudge it, so we don't need a
+        # new function
+        notnull_hack = ((not column.nullable) \
+                            and ('nullable' not in delta.keys()))
+        # We need to specify NULL if we're removing a NOT NULL
+        # constraint
+        null_hack = (column.nullable and ('nullable' in delta.keys()))
+
+        if dropdefault_hack:
+            column.server_default = sa.PassiveDefault(sa.sql.null())
+        if notnull_hack:
+            column.nullable = True
+        colspec = self.get_column_specification(column,
+            override_nullable=null_hack)
+        if null_hack:
+            colspec += ' NULL'
+        if notnull_hack:
+            column.nullable = False
+        if dropdefault_hack:
+            column.server_default = None
+
+        self.start_alter_table(table)
+        self.append("MODIFY (")
+        self.append(colspec)
+        self.append(")")
+
+
+class OracleConstraintCommon(object):
+
+    def get_constraint_name(self, cons):
+        # Oracle constraints can't guess their name like other DBs
+        if not cons.name:
+            raise exceptions.NotSupportedError(
+                "Oracle constraint names must be explicitly stated")
+        return cons.name
+
+
+class OracleConstraintGenerator(OracleConstraintCommon,
+                                ansisql.ANSIConstraintGenerator):
+    pass
+
+
+class OracleConstraintDropper(OracleConstraintCommon,
+                              ansisql.ANSIConstraintDropper):
+    pass
+
+
+class OracleDialect(ansisql.ANSIDialect):
+    columngenerator = OracleColumnGenerator
+    columndropper = OracleColumnDropper
+    schemachanger = OracleSchemaChanger
+    constraintgenerator = OracleConstraintGenerator
+    constraintdropper = OracleConstraintDropper