Implemented some SpatiaLiteOperations as cached properties

Previously, some properties weren't set unless
confirm_spatial_components_versions() was explicitely called.
This commit is contained in:
Claude Paroz 2013-01-29 19:33:43 +01:00
parent ee26797cff
commit eb9430fc4b
2 changed files with 31 additions and 18 deletions

View File

@ -30,7 +30,6 @@ class SpatiaLiteCreation(DatabaseCreation):
self.connection.close() self.connection.close()
self.connection.settings_dict["NAME"] = test_database_name self.connection.settings_dict["NAME"] = test_database_name
self.connection.ops.confirm_spatial_components_versions()
# Need to load the SpatiaLite initialization SQL before running `syncdb`. # Need to load the SpatiaLite initialization SQL before running `syncdb`.
self.load_spatialite_sql() self.load_spatialite_sql()

View File

@ -10,6 +10,8 @@ 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 from django.db.utils import DatabaseError
from django.utils import six from django.utils import six
from django.utils.functional import cached_property
class SpatiaLiteOperator(SpatialOperation): class SpatiaLiteOperator(SpatialOperation):
"For SpatiaLite operators (e.g. `&&`, `~`)." "For SpatiaLite operators (e.g. `&&`, `~`)."
@ -118,36 +120,48 @@ class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations):
gis_terms += self.geometry_functions.keys() gis_terms += self.geometry_functions.keys()
self.gis_terms = dict([(term, None) for term in gis_terms]) self.gis_terms = dict([(term, None) for term in gis_terms])
def confirm_spatial_components_versions(self): @cached_property
# Determine the version of the SpatiaLite library. def spatial_version(self):
"""Determine the version of the SpatiaLite library."""
try: try:
vtup = self.spatialite_version_tuple() version = self.spatialite_version_tuple()[1:]
version = vtup[1:]
if version < (2, 3, 0):
raise ImproperlyConfigured('GeoDjango only supports SpatiaLite versions '
'2.3.0 and above')
self.spatial_version = version
except ImproperlyConfigured:
raise
except Exception as msg: except Exception as msg:
raise ImproperlyConfigured('Cannot determine the SpatiaLite version for the "%s" ' raise ImproperlyConfigured('Cannot determine the SpatiaLite version for the "%s" '
'database (error was "%s"). Was the SpatiaLite initialization ' 'database (error was "%s"). Was the SpatiaLite initialization '
'SQL loaded on this database?' % 'SQL loaded on this database?' %
(self.connection.settings_dict['NAME'], msg)) (self.connection.settings_dict['NAME'], msg))
if version < (2, 3, 0):
raise ImproperlyConfigured('GeoDjango only supports SpatiaLite versions '
'2.3.0 and above')
return version
if version >= (2, 4, 0): @property
def _version_greater_2_4_0_rc4(self):
if self.spatial_version >= (2, 4, 1):
return True
elif self.spatial_version < (2, 4, 0):
return False
else:
# Spatialite 2.4.0-RC4 added AsGML and AsKML, however both # Spatialite 2.4.0-RC4 added AsGML and AsKML, however both
# RC2 (shipped in popular Debian/Ubuntu packages) and RC4 # RC2 (shipped in popular Debian/Ubuntu packages) and RC4
# report version as '2.4.0', so we fall back to feature detection # report version as '2.4.0', so we fall back to feature detection
try: try:
self._get_spatialite_func("AsGML(GeomFromText('POINT(1 1)'))") self._get_spatialite_func("AsGML(GeomFromText('POINT(1 1)'))")
self.gml = 'AsGML'
self.kml = 'AsKML'
except DatabaseError: except DatabaseError:
# we are using < 2.4.0-RC4 return False
pass return True
if version >= (3, 0, 0):
self.geojson = 'AsGeoJSON' @cached_property
def gml(self):
return 'AsGML' if self._version_greater_2_4_0_rc4 else None
@cached_property
def kml(self):
return 'AsKML' if self._version_greater_2_4_0_rc4 else None
@cached_property
def geojson(self):
return 'AsGeoJSON' if self.spatial_version >= (3, 0, 0) else None
def check_aggregate_support(self, aggregate): def check_aggregate_support(self, aggregate):
""" """