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