web/lib/django/contrib/gis/db/backends/spatialite/base.py
changeset 29 cc9b7e14412b
equal deleted inserted replaced
28:b758351d191f 29:cc9b7e14412b
       
     1 from ctypes.util import find_library
       
     2 from django.conf import settings
       
     3 
       
     4 from django.core.exceptions import ImproperlyConfigured
       
     5 from django.db.backends.sqlite3.base import *
       
     6 from django.db.backends.sqlite3.base import DatabaseWrapper as SqliteDatabaseWrapper, \
       
     7     _sqlite_extract, _sqlite_date_trunc, _sqlite_regexp
       
     8 from django.contrib.gis.db.backends.spatialite.client import SpatiaLiteClient
       
     9 from django.contrib.gis.db.backends.spatialite.creation import SpatiaLiteCreation
       
    10 from django.contrib.gis.db.backends.spatialite.introspection import SpatiaLiteIntrospection
       
    11 from django.contrib.gis.db.backends.spatialite.operations import SpatiaLiteOperations
       
    12 
       
    13 class DatabaseWrapper(SqliteDatabaseWrapper):
       
    14     def __init__(self, *args, **kwargs):
       
    15         # Before we get too far, make sure pysqlite 2.5+ is installed.
       
    16         if Database.version_info < (2, 5, 0):
       
    17             raise ImproperlyConfigured('Only versions of pysqlite 2.5+ are '
       
    18                                        'compatible with SpatiaLite and GeoDjango.')
       
    19 
       
    20         # Trying to find the location of the SpatiaLite library.
       
    21         # Here we are figuring out the path to the SpatiaLite library
       
    22         # (`libspatialite`). If it's not in the system library path (e.g., it
       
    23         # cannot be found by `ctypes.util.find_library`), then it may be set
       
    24         # manually in the settings via the `SPATIALITE_LIBRARY_PATH` setting.
       
    25         self.spatialite_lib = getattr(settings, 'SPATIALITE_LIBRARY_PATH',
       
    26                                       find_library('spatialite'))
       
    27         if not self.spatialite_lib:
       
    28             raise ImproperlyConfigured('Unable to locate the SpatiaLite library. '
       
    29                                        'Make sure it is in your library path, or set '
       
    30                                        'SPATIALITE_LIBRARY_PATH in your settings.'
       
    31                                        )
       
    32         super(DatabaseWrapper, self).__init__(*args, **kwargs)
       
    33         self.ops = SpatiaLiteOperations(self)
       
    34         self.client = SpatiaLiteClient(self)
       
    35         self.creation = SpatiaLiteCreation(self)
       
    36         self.introspection = SpatiaLiteIntrospection(self)
       
    37 
       
    38     def _cursor(self):
       
    39         if self.connection is None:
       
    40             ## The following is the same as in django.db.backends.sqlite3.base ##
       
    41             settings_dict = self.settings_dict
       
    42             if not settings_dict['NAME']:
       
    43                 raise ImproperlyConfigured("Please fill out the database NAME in the settings module before using the database.")
       
    44             kwargs = {
       
    45                 'database': settings_dict['NAME'],
       
    46                 'detect_types': Database.PARSE_DECLTYPES | Database.PARSE_COLNAMES,
       
    47             }
       
    48             kwargs.update(settings_dict['OPTIONS'])
       
    49             self.connection = Database.connect(**kwargs)
       
    50             # Register extract, date_trunc, and regexp functions.
       
    51             self.connection.create_function("django_extract", 2, _sqlite_extract)
       
    52             self.connection.create_function("django_date_trunc", 2, _sqlite_date_trunc)
       
    53             self.connection.create_function("regexp", 2, _sqlite_regexp)
       
    54             connection_created.send(sender=self.__class__)
       
    55 
       
    56             ## From here on, customized for GeoDjango ##
       
    57 
       
    58             # Enabling extension loading on the SQLite connection.
       
    59             try:
       
    60                 self.connection.enable_load_extension(True)
       
    61             except AttributeError:
       
    62                 raise ImproperlyConfigured('The pysqlite library does not support C extension loading. '
       
    63                                            'Both SQLite and pysqlite must be configured to allow '
       
    64                                            'the loading of extensions to use SpatiaLite.'
       
    65                                            )
       
    66 
       
    67             # Loading the SpatiaLite library extension on the connection, and returning
       
    68             # the created cursor.
       
    69             cur = self.connection.cursor(factory=SQLiteCursorWrapper)
       
    70             try:
       
    71                 cur.execute("SELECT load_extension(%s)", (self.spatialite_lib,))
       
    72             except Exception, msg:
       
    73                 raise ImproperlyConfigured('Unable to load the SpatiaLite library extension '
       
    74                                            '"%s" because: %s' % (self.spatialite_lib, msg))
       
    75             return cur
       
    76         else:
       
    77             return self.connection.cursor(factory=SQLiteCursorWrapper)