Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[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
  • Loading branch information...
commit f110f91a0399afad8db9b2925737074d185d20bf 1 parent ed5e3c3
Justin Bronn authored April 21, 2009
15  django/contrib/gis/db/models/sql/query.py
@@ -201,7 +201,7 @@ def convert_values(self, value, field):
201 201
         """
202 202
         if SpatialBackend.oracle:
203 203
             # Running through Oracle's first.
204  
-            value = super(GeoQuery, self).convert_values(value, field)
  204
+            value = super(GeoQuery, self).convert_values(value, field or GeomField())
205 205
         if isinstance(field, DistanceField):
206 206
             # Using the field's distance attribute, can instantiate
207 207
             # `Distance` with the right context.
@@ -325,15 +325,22 @@ def _geo_field(self, field_name=None):
325 325
             return self._check_geo_field(self.model, field_name)
326 326
 
327 327
 ### Field Classes for `convert_values` ####
328  
-class AreaField(object):
  328
+class BaseField(object):
  329
+    def get_internal_type(self):
  330
+        "Overloaded method so OracleQuery.convert_values doesn't balk."
  331
+        return None
  332
+
  333
+if SpatialBackend.oracle: BaseField.empty_strings_allowed = False
  334
+
  335
+class AreaField(BaseField):
329 336
     def __init__(self, area_att):
330 337
         self.area_att = area_att
331 338
 
332  
-class DistanceField(object):
  339
+class DistanceField(BaseField):
333 340
     def __init__(self, distance_att):
334 341
         self.distance_att = distance_att
335 342
 
336 343
 # Rather than use GeometryField (which requires a SQL query
337 344
 # upon instantiation), use this lighter weight class.
338  
-class GeomField(object): 
  345
+class GeomField(BaseField): 
339 346
     pass
13  django/contrib/gis/tests/__init__.py
@@ -13,7 +13,7 @@ def geo_suite():
13 13
     from django.contrib.gis.utils import HAS_GEOIP
14 14
 
15 15
     # Tests that require use of a spatial database (e.g., creation of models)
16  
-    test_models = ['geoapp',]
  16
+    test_models = ['geoapp', 'layermap', 'relatedapp']
17 17
 
18 18
     # Tests that do not require setting up and tearing down a spatial database.
19 19
     test_suite_names = [
@@ -21,15 +21,8 @@ def geo_suite():
21 21
         'test_measure',
22 22
         ]
23 23
     if HAS_GDAL:
24  
-        if oracle:
25  
-            # TODO: There's a problem with `select_related` and GeoQuerySet on
26  
-            # Oracle -- e.g., GeoModel.objects.distance(geom, field_name='fk__point')
27  
-            # doesn't work so we don't test `relatedapp`.
28  
-            test_models += ['distapp', 'layermap']
29  
-        elif postgis:
30  
-            test_models += ['distapp', 'layermap', 'relatedapp']
31  
-        elif mysql:
32  
-            test_models += ['relatedapp', 'layermap']
  24
+        if oracle or postgis:
  25
+            test_models.append('distapp')
33 26
 
34 27
         test_suite_names += [
35 28
             'test_gdal_driver',
22  django/contrib/gis/tests/distapp/tests.py
@@ -115,8 +115,12 @@ def test03a_distance_method(self):
115 115
         # with different projected coordinate systems.
116 116
         dist1 = SouthTexasCity.objects.distance(lagrange, field_name='point')
117 117
         dist2 = SouthTexasCity.objects.distance(lagrange)  # Using GEOSGeometry parameter
118  
-        dist3 = SouthTexasCityFt.objects.distance(lagrange.ewkt) # Using EWKT string parameter.
119  
-        dist4 = SouthTexasCityFt.objects.distance(lagrange)
  118
+        if oracle:
  119
+            dist_qs = [dist1, dist2]
  120
+        else:
  121
+            dist3 = SouthTexasCityFt.objects.distance(lagrange.ewkt) # Using EWKT string parameter.
  122
+            dist4 = SouthTexasCityFt.objects.distance(lagrange)
  123
+            dist_qs = [dist1, dist2, dist3, dist4]
120 124
 
121 125
         # Original query done on PostGIS, have to adjust AlmostEqual tolerance
122 126
         # for Oracle.
@@ -124,7 +128,7 @@ def test03a_distance_method(self):
124 128
         else: tol = 5
125 129
 
126 130
         # Ensuring expected distances are returned for each distance queryset.
127  
-        for qs in [dist1, dist2, dist3, dist4]:
  131
+        for qs in dist_qs:
128 132
             for i, c in enumerate(qs):
129 133
                 self.assertAlmostEqual(m_distances[i], c.distance.m, tol)
130 134
                 self.assertAlmostEqual(ft_distances[i], c.distance.survey_ft, tol)
@@ -194,8 +198,16 @@ def test04_distance_lookups(self):
194 198
         # (thus, Houston and Southside place will be excluded as tested in
195 199
         # the `test02_dwithin` above).
196 200
         qs1 = SouthTexasCity.objects.filter(point__distance_gte=(self.stx_pnt, D(km=7))).filter(point__distance_lte=(self.stx_pnt, D(km=20)))
197  
-        qs2 = SouthTexasCityFt.objects.filter(point__distance_gte=(self.stx_pnt, D(km=7))).filter(point__distance_lte=(self.stx_pnt, D(km=20)))
198  
-        for qs in qs1, qs2:
  201
+
  202
+        # Oracle 11 incorrectly thinks spatial reference system for the
  203
+        # SouthTexasCityFt model is not projected, so omit.
  204
+        if oracle:
  205
+            dist_qs = (qs1,)
  206
+        else:
  207
+            qs2 = SouthTexasCityFt.objects.filter(point__distance_gte=(self.stx_pnt, D(km=7))).filter(point__distance_lte=(self.stx_pnt, D(km=20)))
  208
+            dist_qs = (qs1, qs2)
  209
+
  210
+        for qs in dist_qs:
199 211
             cities = self.get_names(qs)
200 212
             self.assertEqual(cities, ['Bellaire', 'Pearland', 'West University Place'])
201 213
 
2  django/contrib/gis/tests/geoapp/tests.py
@@ -150,7 +150,7 @@ def test03b_gml(self):
150 150
         if SpatialBackend.oracle:
151 151
             # No precision parameter for Oracle :-/
152 152
             import re
153  
-            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>')
  153
+            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>')
154 154
             for ptown in [ptown1, ptown2]:
155 155
                 self.assertEqual(True, bool(gml_regex.match(ptown.gml)))
156 156
         else:
50  django/contrib/gis/tests/relatedapp/tests.py
... ...
@@ -1,6 +1,6 @@
1 1
 import os, unittest
2 2
 from django.contrib.gis.geos import *
3  
-from django.contrib.gis.tests.utils import no_mysql, postgis
  3
+from django.contrib.gis.tests.utils import no_mysql, no_oracle, oracle, postgis
4 4
 from django.conf import settings
5 5
 from models import City, Location, DirectoryEntry
6 6
 
@@ -19,6 +19,7 @@ def test01_setup(self):
19 19
             c = City(name=name, state=state, location=loc)
20 20
             c.save()
21 21
             
  22
+    @no_oracle # There are problems w/spatial Oracle pagination and select_related()
22 23
     def test02_select_related(self):
23 24
         "Testing `select_related` on geographic models (see #7126)."
24 25
         qs1 = City.objects.all()
@@ -33,6 +34,7 @@ def test02_select_related(self):
33 34
                 self.assertEqual(Point(lon, lat), c.location.point)
34 35
         
35 36
     @no_mysql
  37
+    @no_oracle # Pagination problem is implicated in this test as well.
36 38
     def test03_transform_related(self):
37 39
         "Testing the `transform` GeoQuerySet method on related geographic models."
38 40
         # All the transformations are to state plane coordinate systems using
@@ -71,22 +73,42 @@ def check_pnt(ref, pnt):
71 73
         #self.assertEqual(nqueries, len(connection.queries))
72 74
 
73 75
     @no_mysql
74  
-    def test04_related_aggregate(self):
75  
-        "Testing the `extent` and `unionagg` GeoQuerySet aggregates on related geographic models."
76  
-        if postgis:
77  
-            # One for all locations, one that excludes Roswell.
78  
-            all_extent = (-104.528060913086, 33.0583305358887,-79.4607315063477, 40.1847610473633)
79  
-            txpa_extent = (-97.51611328125, 33.0583305358887,-79.4607315063477, 40.1847610473633)
80  
-            e1 = City.objects.extent(field_name='location__point')
81  
-            e2 = City.objects.exclude(name='Roswell').extent(field_name='location__point')
82  
-            for ref, e in [(all_extent, e1), (txpa_extent, e2)]:
83  
-                for ref_val, e_val in zip(ref, e): self.assertAlmostEqual(ref_val, e_val)
  76
+    @no_oracle
  77
+    def test04a_related_extent_aggregate(self):
  78
+        "Testing the `extent` GeoQuerySet aggregates on related geographic models."
  79
+        # One for all locations, one that excludes Roswell.
  80
+        all_extent = (-104.528060913086, 33.0583305358887,-79.4607315063477, 40.1847610473633)
  81
+        txpa_extent = (-97.51611328125, 33.0583305358887,-79.4607315063477, 40.1847610473633)
  82
+        e1 = City.objects.extent(field_name='location__point')
  83
+        e2 = City.objects.exclude(name='Roswell').extent(field_name='location__point')
  84
+        tol = 9
  85
+        for ref, e in [(all_extent, e1), (txpa_extent, e2)]:
  86
+            for ref_val, e_val in zip(ref, e): self.assertAlmostEqual(ref_val, e_val, tol)
  87
+
  88
+    @no_mysql
  89
+    def test04b_related_union_aggregate(self):
  90
+        "Testing the `unionagg` GeoQuerySet aggregates on related geographic models."
  91
+        # These are the points that are components of the aggregate geographic
  92
+        # union that is returned.
  93
+        p1 = Point(-104.528056, 33.387222)
  94
+        p2 = Point(-97.516111, 33.058333)
  95
+        p3 = Point(-79.460734, 40.18476)
  96
+
  97
+        # Creating the reference union geometry depending on the spatial backend,
  98
+        # as Oracle will have a different internal ordering of the component
  99
+        # geometries than PostGIS.  The second union aggregate is for a union
  100
+        # query that includes limiting information in the WHERE clause (in other
  101
+        # words a `.filter()` precedes the call to `.unionagg()`).
  102
+        if oracle:
  103
+            ref_u1 = MultiPoint(p3, p1, p2, srid=4326)
  104
+            ref_u2 = MultiPoint(p3, p2, srid=4326)
  105
+        else:
  106
+            ref_u1 = MultiPoint(p1, p2, p3, srid=4326)
  107
+            ref_u2 = MultiPoint(p2, p3, srid=4326)
84 108
 
85  
-        # The second union is for a query that has something in the WHERE clause.
86  
-        ref_u1 = GEOSGeometry('MULTIPOINT(-104.528056 33.387222,-97.516111 33.058333,-79.460734 40.18476)', 4326)
87  
-        ref_u2 = GEOSGeometry('MULTIPOINT(-97.516111 33.058333,-79.460734 40.18476)', 4326)
88 109
         u1 = City.objects.unionagg(field_name='location__point')
89 110
         u2 = City.objects.exclude(name='Roswell').unionagg(field_name='location__point')
  111
+
90 112
         self.assertEqual(ref_u1, u1)
91 113
         self.assertEqual(ref_u2, u2)
92 114
         

0 notes on commit f110f91

Please sign in to comment.
Something went wrong with that request. Please try again.