Commit a7bfcba5 authored by Justin Bronn's avatar Justin Bronn
Browse files

[1.0.X] Fixed #10888 -- May now insert NULL `GeometryField` values on Oracle.

Backport of r10631 from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@10632 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 3b3c05df
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ class OracleSpatialField(Field):
        SDO_CS.TRANSFORM() function call.
        """
        if value is None:
            return '%s'
            return 'NULL'
        elif value.srid != self._srid:
            # Adding Transform() to the SQL placeholder.
            return '%s(SDO_GEOMETRY(%%s, %s), %s)' % (TRANSFORM, value.srid, self._srid)
+4 −0
Original line number Diff line number Diff line
from django.db.models.manager import Manager
from django.contrib.gis.db.models.query import GeoQuerySet
from django.contrib.gis.db.models.sql.subqueries import insert_query

class GeoManager(Manager):
    "Overrides Manager to return Geographic QuerySets."
@@ -80,3 +81,6 @@ class GeoManager(Manager):

    def unionagg(self, *args, **kwargs):
        return self.get_query_set().unionagg(*args, **kwargs)

    def _insert(self, values, **kwargs):
        return insert_query(self.model, values, **kwargs)
+39 −0
Original line number Diff line number Diff line
from django.contrib.gis.db.backend import SpatialBackend
from django.db.models.query import insert_query

if SpatialBackend.oracle:
    from django.db import connection
    from django.db.models.sql.subqueries import InsertQuery

    class OracleGeoInsertQuery(InsertQuery):
        def insert_values(self, insert_values, raw_values=False):
            """
            This routine is overloaded from InsertQuery so that no parameter is
            passed into cx_Oracle for NULL geometries.  The reason is that
            cx_Oracle has no way to bind Oracle object values (like
            MDSYS.SDO_GEOMETRY).
            """
            placeholders, values = [], []
            for field, val in insert_values:
                if hasattr(field, 'get_placeholder'):
                    ph = field.get_placeholder(val)
                else:
                    ph = '%s'

                placeholders.append(ph)
                self.columns.append(field.column)

                # If 'NULL' for the placeholder, omit appending None
                # to the values list (which is used for db params).
                if not ph == 'NULL':
                    values.append(val)
            if raw_values:
                self.values.extend(values)
            else:
                self.params += tuple(values)
                self.values.extend(placeholders)

    def insert_query(model, values, return_id=False, raw_values=False):
        query = OracleGeoInsertQuery(model, connection)
        query.insert_values(values, raw_values)
        return query.execute_sql(return_id)
+10 −12
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ class GeoModelTest(unittest.TestCase):
            data_dir = os.path.join(os.path.dirname(__file__), 'sql')
            def get_file(wkt_file):
                return os.path.join(data_dir, wkt_file)

            State(name='Puerto Rico', poly=None).save()
            State(name='Colorado', poly=fromfile(get_file('co.wkt'))).save()
            State(name='Kansas', poly=fromfile(get_file('ks.wkt'))).save()
            Country(name='Texas', mpoly=fromfile(get_file('tx.wkt'))).save()
@@ -36,11 +36,7 @@ class GeoModelTest(unittest.TestCase):
        # Ensuring that data was loaded from initial SQL.
        self.assertEqual(2, Country.objects.count())
        self.assertEqual(8, City.objects.count())

        # Oracle cannot handle NULL geometry values w/certain queries.
        if SpatialBackend.oracle: n_state = 2
        else: n_state = 3
        self.assertEqual(n_state, State.objects.count())
        self.assertEqual(3, State.objects.count())

    def test02_proxy(self):
        "Testing Lazy-Geometry support (using the GeometryProxy)."
@@ -308,9 +304,6 @@ class GeoModelTest(unittest.TestCase):
        m1.save()
        self.assertEqual(-1, m1.geom.srid)

    # Oracle does not support NULL geometries in its spatial index for
    # some routines (e.g., SDO_GEOM.RELATE).
    @no_oracle
    def test12_null_geometries(self):
        "Testing NULL geometry support, and the `isnull` lookup type."
        if DISABLE: return
@@ -329,9 +322,14 @@ class GeoModelTest(unittest.TestCase):
        self.assertEqual(True, 'Kansas' in state_names)

        # Saving another commonwealth w/a NULL geometry.
        if not SpatialBackend.oracle:
            # TODO: Fix saving w/NULL geometry on Oracle.
            State(name='Northern Mariana Islands', poly=None).save()
        nmi = State.objects.create(name='Northern Mariana Islands', poly=None)
        self.assertEqual(nmi.poly, None)

        # Assigning a geomery and saving -- then UPDATE back to NULL.
        nmi.poly = 'POLYGON((0 0,1 0,1 1,1 0,0 0))'
        nmi.save()
        State.objects.filter(name='Northern Mariana Islands').update(poly=None)
        self.assertEqual(None, State.objects.get(name='Northern Mariana Islands').poly)

    @no_oracle # No specific `left` or `right` operators in Oracle.
    def test13_left_right(self):