|
1 from django.db.backends.mysql.base import DatabaseOperations |
|
2 |
|
3 from django.contrib.gis.db.backends.adapter import WKTAdapter |
|
4 from django.contrib.gis.db.backends.base import BaseSpatialOperations |
|
5 |
|
6 class MySQLOperations(DatabaseOperations, BaseSpatialOperations): |
|
7 |
|
8 compiler_module = 'django.contrib.gis.db.models.sql.compiler' |
|
9 mysql = True |
|
10 name = 'mysql' |
|
11 select = 'AsText(%s)' |
|
12 from_wkb = 'GeomFromWKB' |
|
13 from_text = 'GeomFromText' |
|
14 |
|
15 Adapter = WKTAdapter |
|
16 Adaptor = Adapter # Backwards-compatibility alias. |
|
17 |
|
18 geometry_functions = { |
|
19 'bbcontains' : 'MBRContains', # For consistency w/PostGIS API |
|
20 'bboverlaps' : 'MBROverlaps', # .. .. |
|
21 'contained' : 'MBRWithin', # .. .. |
|
22 'contains' : 'MBRContains', |
|
23 'disjoint' : 'MBRDisjoint', |
|
24 'equals' : 'MBREqual', |
|
25 'exact' : 'MBREqual', |
|
26 'intersects' : 'MBRIntersects', |
|
27 'overlaps' : 'MBROverlaps', |
|
28 'same_as' : 'MBREqual', |
|
29 'touches' : 'MBRTouches', |
|
30 'within' : 'MBRWithin', |
|
31 } |
|
32 |
|
33 gis_terms = dict([(term, None) for term in geometry_functions.keys() + ['isnull']]) |
|
34 |
|
35 def geo_db_type(self, f): |
|
36 return f.geom_type |
|
37 |
|
38 def get_geom_placeholder(self, value, srid): |
|
39 """ |
|
40 The placeholder here has to include MySQL's WKT constructor. Because |
|
41 MySQL does not support spatial transformations, there is no need to |
|
42 modify the placeholder based on the contents of the given value. |
|
43 """ |
|
44 if hasattr(value, 'expression'): |
|
45 placeholder = '%s.%s' % tuple(map(self.quote_name, value.cols[value.expression])) |
|
46 else: |
|
47 placeholder = '%s(%%s)' % self.from_text |
|
48 return placeholder |
|
49 |
|
50 def spatial_lookup_sql(self, lvalue, lookup_type, value, field, qn): |
|
51 alias, col, db_type = lvalue |
|
52 |
|
53 geo_col = '%s.%s' % (qn(alias), qn(col)) |
|
54 |
|
55 lookup_info = self.geometry_functions.get(lookup_type, False) |
|
56 if lookup_info: |
|
57 return "%s(%s, %s)" % (lookup_info, geo_col, |
|
58 self.get_geom_placeholder(value, field.srid)) |
|
59 |
|
60 # TODO: Is this really necessary? MySQL can't handle NULL geometries |
|
61 # in its spatial indexes anyways. |
|
62 if lookup_type == 'isnull': |
|
63 return "%s IS %sNULL" % (geo_col, (not value and 'NOT ' or '')) |
|
64 |
|
65 raise TypeError("Got invalid lookup_type: %s" % repr(lookup_type)) |