summaryrefslogtreecommitdiff
path: root/django/contrib/gis/db/backends/mysql/operations.py
blob: c086543a2363b7e267e11f529e97a883fe8c317b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
from django.db.backends.mysql.base import DatabaseOperations

from django.contrib.gis.db.backends.adapter import WKTAdapter
from django.contrib.gis.db.backends.base import BaseSpatialOperations

class MySQLOperations(DatabaseOperations, BaseSpatialOperations):

    compiler_module = 'django.contrib.gis.db.models.sql.compiler'
    mysql = True
    name = 'mysql'
    select = 'AsText(%s)'
    from_wkb = 'GeomFromWKB'
    from_text = 'GeomFromText'

    Adapter = WKTAdapter

    geometry_functions = {
        'bbcontains' : 'MBRContains', # For consistency w/PostGIS API
        'bboverlaps' : 'MBROverlaps', # .. ..
        'contained' : 'MBRWithin',    # .. ..
        'contains' : 'MBRContains',
        'disjoint' : 'MBRDisjoint',
        'equals' : 'MBREqual',
        'exact' : 'MBREqual',
        'intersects' : 'MBRIntersects',
        'overlaps' : 'MBROverlaps',
        'same_as' : 'MBREqual',
        'touches' : 'MBRTouches',
        'within' : 'MBRWithin',
        }

    gis_terms = dict([(term, None) for term in geometry_functions.keys() + ['isnull']])

    def get_geom_placeholder(self, value, srid):
        """
        The placeholder here has to include MySQL's WKT constructor.  Because
        MySQL does not support spatial transformations, there is no need to
        modify the placeholder based on the contents of the given value.
        """
        if hasattr(value, 'expression'):
            placeholder = '%s.%s' % tuple(map(self.quote_name, value.cols[value.expression]))
        else:
            placeholder = '%s(%%s)' % self.from_text
        return placeholder

    def spatial_lookup_sql(self, lvalue, lookup_type, value, field):
        qn = self.quote_name
        alias, col, db_type = lvalue

        geo_col = '%s.%s' % (qn(alias), qn(col))

        lookup_info = self.geometry_functions.get(lookup_type, False)
        if lookup_info:
            return "%s(%s, %s)" % (lookup_info, geo_col,
                                   self.get_geom_placeholder(value, field.srid))

        # TODO: Is this really necessary? MySQL can't handle NULL geometries
        #  in its spatial indexes anyways.
        if lookup_type == 'isnull':
            return "%s IS %sNULL" % (geo_col, (not value and 'NOT ' or ''))

        raise TypeError("Got invalid lookup_type: %s" % repr(lookup_type))