8
8
from django .contrib .gis .measure import Distance
9
9
from django .core .exceptions import ImproperlyConfigured
10
10
from django .db .backends .sqlite3 .base import DatabaseOperations
11
+ from django .db .utils import DatabaseError
11
12
12
13
class SpatiaLiteOperator (SpatialOperation ):
13
14
"For SpatiaLite operators (e.g. `&&`, `~`)."
@@ -115,9 +116,9 @@ def __init__(self, connection):
115
116
try :
116
117
vtup = self .spatialite_version_tuple ()
117
118
version = vtup [1 :]
118
- if version < (2 , 3 , 1 ):
119
+ if version < (2 , 3 , 0 ):
119
120
raise ImproperlyConfigured ('GeoDjango only supports SpatiaLite versions '
120
- '2.3.1 and above' )
121
+ '2.3.0 and above' )
121
122
self .spatial_version = version
122
123
except ImproperlyConfigured :
123
124
raise
@@ -203,12 +204,13 @@ def transform_value(value, srid):
203
204
204
205
def _get_spatialite_func (self , func ):
205
206
"""
206
- Helper routine for calling PostGIS functions and returning their result.
207
+ Helper routine for calling SpatiaLite functions and returning
208
+ their result.
207
209
"""
208
210
cursor = self .connection ._cursor ()
209
211
try :
210
212
try :
211
- cursor .execute ('SELECT %s() ' % func )
213
+ cursor .execute ('SELECT %s' % func )
212
214
row = cursor .fetchone ()
213
215
except :
214
216
# Responsibility of caller to perform error handling.
@@ -219,25 +221,39 @@ def _get_spatialite_func(self, func):
219
221
220
222
def geos_version (self ):
221
223
"Returns the version of GEOS used by SpatiaLite as a string."
222
- return self ._get_spatialite_func ('geos_version' )
224
+ return self ._get_spatialite_func ('geos_version() ' )
223
225
224
226
def proj4_version (self ):
225
227
"Returns the version of the PROJ.4 library used by SpatiaLite."
226
- return self ._get_spatialite_func ('proj4_version' )
228
+ return self ._get_spatialite_func ('proj4_version() ' )
227
229
228
230
def spatialite_version (self ):
229
231
"Returns the SpatiaLite library version as a string."
230
- return self ._get_spatialite_func ('spatialite_version' )
232
+ return self ._get_spatialite_func ('spatialite_version() ' )
231
233
232
234
def spatialite_version_tuple (self ):
233
235
"""
234
236
Returns the SpatiaLite version as a tuple (version string, major,
235
237
minor, subminor).
236
238
"""
237
- # Getting the PostGIS version
238
- version = self .spatialite_version ()
239
- m = self .version_regex .match (version )
239
+ # Getting the SpatiaLite version.
240
+ try :
241
+ version = self .spatialite_version ()
242
+ except DatabaseError :
243
+ # The `spatialite_version` function first appeared in version 2.3.1
244
+ # of SpatiaLite, so doing a fallback test for 2.3.0 (which is
245
+ # used by popular Debian/Ubuntu packages).
246
+ version = None
247
+ try :
248
+ tmp = self ._get_spatialite_func ("X(GeomFromText('POINT(1 1)'))" )
249
+ if tmp == 1.0 : version = '2.3.0'
250
+ except DatabaseError :
251
+ pass
252
+ # If no version string defined, then just re-raise the original
253
+ # exception.
254
+ if version is None : raise
240
255
256
+ m = self .version_regex .match (version )
241
257
if m :
242
258
major = int (m .group ('major' ))
243
259
minor1 = int (m .group ('minor1' ))
0 commit comments