Commit eb9430fc authored by Claude Paroz's avatar Claude Paroz
Browse files

Implemented some SpatiaLiteOperations as cached properties

Previously, some properties weren't set unless
confirm_spatial_components_versions() was explicitely called.
parent ee26797c
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ class SpatiaLiteCreation(DatabaseCreation):

        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()
+32 −18
Original line number Diff line number Diff line
@@ -10,6 +10,8 @@ from django.core.exceptions import ImproperlyConfigured
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 @@ class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations):
        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):
        """