From eb9430fc4be16f2256f8ff4d8ee90577fb0a8f5a Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Tue, 29 Jan 2013 19:33:43 +0100 Subject: [PATCH] Implemented some SpatiaLiteOperations as cached properties Previously, some properties weren't set unless confirm_spatial_components_versions() was explicitely called. --- .../gis/db/backends/spatialite/creation.py | 1 - .../gis/db/backends/spatialite/operations.py | 50 ++++++++++++------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/django/contrib/gis/db/backends/spatialite/creation.py b/django/contrib/gis/db/backends/spatialite/creation.py index 27332b9b57f95..d0a5f820332ae 100644 --- a/django/contrib/gis/db/backends/spatialite/creation.py +++ b/django/contrib/gis/db/backends/spatialite/creation.py @@ -30,7 +30,6 @@ def create_test_db(self, verbosity=1, autoclobber=False): self.connection.close() 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`. self.load_spatialite_sql() diff --git a/django/contrib/gis/db/backends/spatialite/operations.py b/django/contrib/gis/db/backends/spatialite/operations.py index 5eaa77843c93c..773ac0b57d671 100644 --- a/django/contrib/gis/db/backends/spatialite/operations.py +++ b/django/contrib/gis/db/backends/spatialite/operations.py @@ -10,6 +10,8 @@ from django.db.backends.sqlite3.base import DatabaseOperations from django.db.utils import DatabaseError from django.utils import six +from django.utils.functional import cached_property + class SpatiaLiteOperator(SpatialOperation): "For SpatiaLite operators (e.g. `&&`, `~`)." @@ -118,36 +120,48 @@ def __init__(self, connection): gis_terms += self.geometry_functions.keys() self.gis_terms = dict([(term, None) for term in gis_terms]) - def confirm_spatial_components_versions(self): - # Determine the version of the SpatiaLite library. + @cached_property + def spatial_version(self): + """Determine the version of the SpatiaLite library.""" try: - vtup = self.spatialite_version_tuple() - 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 + version = self.spatialite_version_tuple()[1:] except Exception as msg: raise ImproperlyConfigured('Cannot determine the SpatiaLite version for the "%s" ' 'database (error was "%s"). Was the SpatiaLite initialization ' 'SQL loaded on this database?' % (self.connection.settings_dict['NAME'], msg)) - - if version >= (2, 4, 0): + if version < (2, 3, 0): + raise ImproperlyConfigured('GeoDjango only supports SpatiaLite versions ' + '2.3.0 and above') + return version + + @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 # RC2 (shipped in popular Debian/Ubuntu packages) and RC4 # report version as '2.4.0', so we fall back to feature detection try: self._get_spatialite_func("AsGML(GeomFromText('POINT(1 1)'))") - self.gml = 'AsGML' - self.kml = 'AsKML' except DatabaseError: - # we are using < 2.4.0-RC4 - pass - if version >= (3, 0, 0): - self.geojson = 'AsGeoJSON' + return False + return True + + @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): """