Fixed #13070 -- Introduced fallback code to detect SpatiaLite 2.3.0 versions (which do not have `spatialite_version` function).

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12882 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2010-03-29 19:40:59 +00:00
parent 85e13681b0
commit 85fa7d8894
1 changed files with 26 additions and 10 deletions

View File

@ -8,6 +8,7 @@ from django.contrib.gis.geometry.backend import Geometry
from django.contrib.gis.measure import Distance from django.contrib.gis.measure import Distance
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.db.backends.sqlite3.base import DatabaseOperations from django.db.backends.sqlite3.base import DatabaseOperations
from django.db.utils import DatabaseError
class SpatiaLiteOperator(SpatialOperation): class SpatiaLiteOperator(SpatialOperation):
"For SpatiaLite operators (e.g. `&&`, `~`)." "For SpatiaLite operators (e.g. `&&`, `~`)."
@ -115,9 +116,9 @@ class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations):
try: try:
vtup = self.spatialite_version_tuple() vtup = self.spatialite_version_tuple()
version = vtup[1:] version = vtup[1:]
if version < (2, 3, 1): if version < (2, 3, 0):
raise ImproperlyConfigured('GeoDjango only supports SpatiaLite versions ' raise ImproperlyConfigured('GeoDjango only supports SpatiaLite versions '
'2.3.1 and above') '2.3.0 and above')
self.spatial_version = version self.spatial_version = version
except ImproperlyConfigured: except ImproperlyConfigured:
raise raise
@ -203,12 +204,13 @@ class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations):
def _get_spatialite_func(self, func): def _get_spatialite_func(self, func):
""" """
Helper routine for calling PostGIS functions and returning their result. Helper routine for calling SpatiaLite functions and returning
their result.
""" """
cursor = self.connection._cursor() cursor = self.connection._cursor()
try: try:
try: try:
cursor.execute('SELECT %s()' % func) cursor.execute('SELECT %s' % func)
row = cursor.fetchone() row = cursor.fetchone()
except: except:
# Responsibility of caller to perform error handling. # Responsibility of caller to perform error handling.
@ -219,25 +221,39 @@ class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations):
def geos_version(self): def geos_version(self):
"Returns the version of GEOS used by SpatiaLite as a string." "Returns the version of GEOS used by SpatiaLite as a string."
return self._get_spatialite_func('geos_version') return self._get_spatialite_func('geos_version()')
def proj4_version(self): def proj4_version(self):
"Returns the version of the PROJ.4 library used by SpatiaLite." "Returns the version of the PROJ.4 library used by SpatiaLite."
return self._get_spatialite_func('proj4_version') return self._get_spatialite_func('proj4_version()')
def spatialite_version(self): def spatialite_version(self):
"Returns the SpatiaLite library version as a string." "Returns the SpatiaLite library version as a string."
return self._get_spatialite_func('spatialite_version') return self._get_spatialite_func('spatialite_version()')
def spatialite_version_tuple(self): def spatialite_version_tuple(self):
""" """
Returns the SpatiaLite version as a tuple (version string, major, Returns the SpatiaLite version as a tuple (version string, major,
minor, subminor). minor, subminor).
""" """
# Getting the PostGIS version # Getting the SpatiaLite version.
version = self.spatialite_version() try:
m = self.version_regex.match(version) version = self.spatialite_version()
except DatabaseError:
# The `spatialite_version` function first appeared in version 2.3.1
# of SpatiaLite, so doing a fallback test for 2.3.0 (which is
# used by popular Debian/Ubuntu packages).
version = None
try:
tmp = self._get_spatialite_func("X(GeomFromText('POINT(1 1)'))")
if tmp == 1.0: version = '2.3.0'
except DatabaseError:
pass
# If no version string defined, then just re-raise the original
# exception.
if version is None: raise
m = self.version_regex.match(version)
if m: if m:
major = int(m.group('major')) major = int(m.group('major'))
minor1 = int(m.group('minor1')) minor1 = int(m.group('minor1'))