|
29
|
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) |