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

[1.0.X] Fixed various Oracle errata and test failures present in this branch...

[1.0.X] Fixed various Oracle errata and test failures present in this branch (including not going to 11).

Backport of Oracle-related changes from trunk in r10197.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@10614 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent ed5e3c3d
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -201,7 +201,7 @@ class GeoQuery(sql.Query):
        """
        if SpatialBackend.oracle:
            # Running through Oracle's first.
            value = super(GeoQuery, self).convert_values(value, field)
            value = super(GeoQuery, self).convert_values(value, field or GeomField())
        if isinstance(field, DistanceField):
            # Using the field's distance attribute, can instantiate
            # `Distance` with the right context.
@@ -325,15 +325,22 @@ class GeoQuery(sql.Query):
            return self._check_geo_field(self.model, field_name)

### Field Classes for `convert_values` ####
class AreaField(object):
class BaseField(object):
    def get_internal_type(self):
        "Overloaded method so OracleQuery.convert_values doesn't balk."
        return None

if SpatialBackend.oracle: BaseField.empty_strings_allowed = False

class AreaField(BaseField):
    def __init__(self, area_att):
        self.area_att = area_att

class DistanceField(object):
class DistanceField(BaseField):
    def __init__(self, distance_att):
        self.distance_att = distance_att

# Rather than use GeometryField (which requires a SQL query
# upon instantiation), use this lighter weight class.
class GeomField(object): 
class GeomField(BaseField): 
    pass
+3 −10
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@ def geo_suite():
    from django.contrib.gis.utils import HAS_GEOIP

    # Tests that require use of a spatial database (e.g., creation of models)
    test_models = ['geoapp',]
    test_models = ['geoapp', 'layermap', 'relatedapp']

    # Tests that do not require setting up and tearing down a spatial database.
    test_suite_names = [
@@ -21,15 +21,8 @@ def geo_suite():
        'test_measure',
        ]
    if HAS_GDAL:
        if oracle:
            # TODO: There's a problem with `select_related` and GeoQuerySet on
            # Oracle -- e.g., GeoModel.objects.distance(geom, field_name='fk__point')
            # doesn't work so we don't test `relatedapp`.
            test_models += ['distapp', 'layermap']
        elif postgis:
            test_models += ['distapp', 'layermap', 'relatedapp']
        elif mysql:
            test_models += ['relatedapp', 'layermap']
        if oracle or postgis:
            test_models.append('distapp')

        test_suite_names += [
            'test_gdal_driver',
+17 −5
Original line number Diff line number Diff line
@@ -115,8 +115,12 @@ class DistanceTest(unittest.TestCase):
        # with different projected coordinate systems.
        dist1 = SouthTexasCity.objects.distance(lagrange, field_name='point')
        dist2 = SouthTexasCity.objects.distance(lagrange)  # Using GEOSGeometry parameter
        if oracle:
            dist_qs = [dist1, dist2]
        else:
            dist3 = SouthTexasCityFt.objects.distance(lagrange.ewkt) # Using EWKT string parameter.
            dist4 = SouthTexasCityFt.objects.distance(lagrange)
            dist_qs = [dist1, dist2, dist3, dist4]

        # Original query done on PostGIS, have to adjust AlmostEqual tolerance
        # for Oracle.
@@ -124,7 +128,7 @@ class DistanceTest(unittest.TestCase):
        else: tol = 5

        # Ensuring expected distances are returned for each distance queryset.
        for qs in [dist1, dist2, dist3, dist4]:
        for qs in dist_qs:
            for i, c in enumerate(qs):
                self.assertAlmostEqual(m_distances[i], c.distance.m, tol)
                self.assertAlmostEqual(ft_distances[i], c.distance.survey_ft, tol)
@@ -194,8 +198,16 @@ class DistanceTest(unittest.TestCase):
        # (thus, Houston and Southside place will be excluded as tested in
        # the `test02_dwithin` above).
        qs1 = SouthTexasCity.objects.filter(point__distance_gte=(self.stx_pnt, D(km=7))).filter(point__distance_lte=(self.stx_pnt, D(km=20)))

        # Oracle 11 incorrectly thinks spatial reference system for the
        # SouthTexasCityFt model is not projected, so omit.
        if oracle:
            dist_qs = (qs1,)
        else:
            qs2 = SouthTexasCityFt.objects.filter(point__distance_gte=(self.stx_pnt, D(km=7))).filter(point__distance_lte=(self.stx_pnt, D(km=20)))
        for qs in qs1, qs2:
            dist_qs = (qs1, qs2)

        for qs in dist_qs:
            cities = self.get_names(qs)
            self.assertEqual(cities, ['Bellaire', 'Pearland', 'West University Place'])

+1 −1
Original line number Diff line number Diff line
@@ -150,7 +150,7 @@ class GeoModelTest(unittest.TestCase):
        if SpatialBackend.oracle:
            # No precision parameter for Oracle :-/
            import re
            gml_regex = re.compile(r'<gml:Point srsName="SDO:4326" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates decimal="\." cs="," ts=" ">-104.60925199\d+,38.25500\d+ </gml:coordinates></gml:Point>')
            gml_regex = re.compile(r'<gml:Point srsName="SDO:4326" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates decimal="\." cs="," ts=" ">-104.60925\d+,38.25500\d+ </gml:coordinates></gml:Point>')
            for ptown in [ptown1, ptown2]:
                self.assertEqual(True, bool(gml_regex.match(ptown.gml)))
        else:
+36 −14
Original line number Diff line number Diff line
import os, unittest
from django.contrib.gis.geos import *
from django.contrib.gis.tests.utils import no_mysql, postgis
from django.contrib.gis.tests.utils import no_mysql, no_oracle, oracle, postgis
from django.conf import settings
from models import City, Location, DirectoryEntry

@@ -19,6 +19,7 @@ class RelatedGeoModelTest(unittest.TestCase):
            c = City(name=name, state=state, location=loc)
            c.save()
            
    @no_oracle # There are problems w/spatial Oracle pagination and select_related()
    def test02_select_related(self):
        "Testing `select_related` on geographic models (see #7126)."
        qs1 = City.objects.all()
@@ -33,6 +34,7 @@ class RelatedGeoModelTest(unittest.TestCase):
                self.assertEqual(Point(lon, lat), c.location.point)
        
    @no_mysql
    @no_oracle # Pagination problem is implicated in this test as well.
    def test03_transform_related(self):
        "Testing the `transform` GeoQuerySet method on related geographic models."
        # All the transformations are to state plane coordinate systems using
@@ -71,22 +73,42 @@ class RelatedGeoModelTest(unittest.TestCase):
        #self.assertEqual(nqueries, len(connection.queries))

    @no_mysql
    def test04_related_aggregate(self):
        "Testing the `extent` and `unionagg` GeoQuerySet aggregates on related geographic models."
        if postgis:
    @no_oracle
    def test04a_related_extent_aggregate(self):
        "Testing the `extent` GeoQuerySet aggregates on related geographic models."
        # One for all locations, one that excludes Roswell.
        all_extent = (-104.528060913086, 33.0583305358887,-79.4607315063477, 40.1847610473633)
        txpa_extent = (-97.51611328125, 33.0583305358887,-79.4607315063477, 40.1847610473633)
        e1 = City.objects.extent(field_name='location__point')
        e2 = City.objects.exclude(name='Roswell').extent(field_name='location__point')
        tol = 9
        for ref, e in [(all_extent, e1), (txpa_extent, e2)]:
                for ref_val, e_val in zip(ref, e): self.assertAlmostEqual(ref_val, e_val)
            for ref_val, e_val in zip(ref, e): self.assertAlmostEqual(ref_val, e_val, tol)

    @no_mysql
    def test04b_related_union_aggregate(self):
        "Testing the `unionagg` GeoQuerySet aggregates on related geographic models."
        # These are the points that are components of the aggregate geographic
        # union that is returned.
        p1 = Point(-104.528056, 33.387222)
        p2 = Point(-97.516111, 33.058333)
        p3 = Point(-79.460734, 40.18476)

        # Creating the reference union geometry depending on the spatial backend,
        # as Oracle will have a different internal ordering of the component
        # geometries than PostGIS.  The second union aggregate is for a union
        # query that includes limiting information in the WHERE clause (in other
        # words a `.filter()` precedes the call to `.unionagg()`).
        if oracle:
            ref_u1 = MultiPoint(p3, p1, p2, srid=4326)
            ref_u2 = MultiPoint(p3, p2, srid=4326)
        else:
            ref_u1 = MultiPoint(p1, p2, p3, srid=4326)
            ref_u2 = MultiPoint(p2, p3, srid=4326)

        # The second union is for a query that has something in the WHERE clause.
        ref_u1 = GEOSGeometry('MULTIPOINT(-104.528056 33.387222,-97.516111 33.058333,-79.460734 40.18476)', 4326)
        ref_u2 = GEOSGeometry('MULTIPOINT(-97.516111 33.058333,-79.460734 40.18476)', 4326)
        u1 = City.objects.unionagg(field_name='location__point')
        u2 = City.objects.exclude(name='Roswell').unionagg(field_name='location__point')

        self.assertEqual(ref_u1, u1)
        self.assertEqual(ref_u2, u2)