Ticket #16408: 16408.3.diff

File 16408.3.diff, 10.0 KB (added by jbronn, 4 years ago)
  • django/contrib/gis/db/backends/spatialite/base.py

    diff -r d3a1dd01e8da django/contrib/gis/db/backends/spatialite/base.py
    a b  
    22from django.conf import settings
    33
    44from django.core.exceptions import ImproperlyConfigured
    5 from django.db.backends.sqlite3.base import *
    65from django.db.backends.sqlite3.base import (
    7     _sqlite_extract, _sqlite_date_trunc, _sqlite_regexp,
    8     DatabaseWrapper as SqliteDatabaseWrapper)
     6    _sqlite_extract, _sqlite_date_trunc, _sqlite_regexp, _sqlite_format_dtdelta,
     7    connection_created, Database, DatabaseWrapper as SQLiteDatabaseWrapper,
     8    SQLiteCursorWrapper)
    99from django.contrib.gis.db.backends.spatialite.client import SpatiaLiteClient
    1010from django.contrib.gis.db.backends.spatialite.creation import SpatiaLiteCreation
    1111from django.contrib.gis.db.backends.spatialite.introspection import SpatiaLiteIntrospection
    1212from django.contrib.gis.db.backends.spatialite.operations import SpatiaLiteOperations
    1313
    14 class DatabaseWrapper(SqliteDatabaseWrapper):
     14class DatabaseWrapper(SQLiteDatabaseWrapper):
    1515    def __init__(self, *args, **kwargs):
    1616        # Before we get too far, make sure pysqlite 2.5+ is installed.
    1717        if Database.version_info < (2, 5, 0):
     
    5252            self.connection.create_function("django_extract", 2, _sqlite_extract)
    5353            self.connection.create_function("django_date_trunc", 2, _sqlite_date_trunc)
    5454            self.connection.create_function("regexp", 2, _sqlite_regexp)
     55            self.connection.create_function("django_format_dtdelta", 5, _sqlite_format_dtdelta)
    5556            connection_created.send(sender=self.__class__, connection=self)
    5657
    5758            ## From here on, customized for GeoDjango ##
  • new file django/contrib/gis/db/backends/spatialite/compiler.py

    diff -r d3a1dd01e8da django/contrib/gis/db/backends/spatialite/compiler.py
    - +  
     1from django.db.backends.util import typecast_timestamp
     2from django.db.models.sql import compiler
     3from django.db.models.sql.constants import MULTI
     4from django.contrib.gis.db.models.sql.compiler import GeoSQLCompiler as BaseGeoSQLCompiler
     5
     6SQLCompiler = compiler.SQLCompiler
     7
     8class GeoSQLCompiler(BaseGeoSQLCompiler, SQLCompiler):
     9    pass
     10
     11class SQLInsertCompiler(compiler.SQLInsertCompiler, GeoSQLCompiler):
     12    pass
     13
     14class SQLDeleteCompiler(compiler.SQLDeleteCompiler, GeoSQLCompiler):
     15    pass
     16
     17class SQLUpdateCompiler(compiler.SQLUpdateCompiler, GeoSQLCompiler):
     18    pass
     19
     20class SQLAggregateCompiler(compiler.SQLAggregateCompiler, GeoSQLCompiler):
     21    pass
     22
     23class SQLDateCompiler(compiler.SQLDateCompiler, GeoSQLCompiler):
     24    """
     25    This is overridden for GeoDjango to properly cast date columns, see #16757.
     26    """
     27    def results_iter(self):
     28        offset = len(self.query.extra_select)
     29        for rows in self.execute_sql(MULTI):
     30            for row in rows:
     31                date = typecast_timestamp(str(row[offset]))
     32                yield date
  • django/contrib/gis/db/backends/spatialite/creation.py

    diff -r d3a1dd01e8da django/contrib/gis/db/backends/spatialite/creation.py
    a b  
    33from django.core.cache import get_cache
    44from django.core.cache.backends.db import BaseDatabaseCache
    55from django.core.exceptions import ImproperlyConfigured
    6 from django.core.management import call_command
    76from django.db.backends.sqlite3.creation import DatabaseCreation
    87
    98class SpatiaLiteCreation(DatabaseCreation):
     
    1615        This method is overloaded to load up the SpatiaLite initialization
    1716        SQL prior to calling the `syncdb` command.
    1817        """
     18        # Don't import django.core.management if it isn't needed.
     19        from django.core.management import call_command
     20
     21        test_database_name = self._get_test_db_name()
     22
    1923        if verbosity >= 1:
    20             print "Creating test database '%s'..." % self.connection.alias
     24            test_db_repr = ''
     25            if verbosity >= 2:
     26                test_db_repr = " ('%s')" % test_database_name
     27            print "Creating test database for alias '%s'%s..." % (self.connection.alias, test_db_repr)
    2128
    22         test_database_name = self._create_test_db(verbosity, autoclobber)
     29        self._create_test_db(verbosity, autoclobber)
    2330
    2431        self.connection.close()
     32        self.connection.settings_dict["NAME"] = test_database_name
    2533
    26         self.connection.settings_dict["NAME"] = test_database_name
    2734        # Confirm the feature set of the test database
    2835        self.connection.features.confirm()
     36
    2937        # Need to load the SpatiaLite initialization SQL before running `syncdb`.
    3038        self.load_spatialite_sql()
    3139        call_command('syncdb', verbosity=verbosity, interactive=False, database=self.connection.alias)
    3240
     41        # Report syncdb messages at one level lower than that requested.
     42        # This ensures we don't get flooded with messages during testing
     43        # (unless you really ask to be flooded)
     44        call_command('syncdb',
     45            verbosity=max(verbosity - 1, 0),
     46            interactive=False,
     47            database=self.connection.alias,
     48            load_initial_data=False)
     49
     50        # We need to then do a flush to ensure that any data installed by
     51        # custom SQL has been removed. The only test data should come from
     52        # test fixtures, or autogenerated from post_syncdb triggers.
     53        # This has the side effect of loading initial data (which was
     54        # intentionally skipped in the syncdb).
     55        call_command('flush',
     56            verbosity=max(verbosity - 1, 0),
     57            interactive=False,
     58            database=self.connection.alias)
     59
     60        # One effect of calling syncdb followed by flush is that the id of the
     61        # default site may or may not be 1, depending on how the sequence was
     62        # reset.  If the sites app is loaded, then we coerce it.
     63        from django.db.models import get_model
     64        Site = get_model('sites', 'Site')
     65        if Site is not None and Site.objects.using(self.connection.alias).count() == 1:
     66            Site.objects.using(self.connection.alias).update(id=settings.SITE_ID)
     67
     68        from django.core.cache import get_cache
     69        from django.core.cache.backends.db import BaseDatabaseCache
    3370        for cache_alias in settings.CACHES:
    3471            cache = get_cache(cache_alias)
    3572            if isinstance(cache, BaseDatabaseCache):
    3673                from django.db import router
    3774                if router.allow_syncdb(self.connection.alias, cache.cache_model_class):
    3875                    call_command('createcachetable', cache._table, database=self.connection.alias)
     76
    3977        # Get a cursor (even though we don't need one yet). This has
    4078        # the side effect of initializing the test database.
    4179        cursor = self.connection.cursor()
  • django/contrib/gis/db/backends/spatialite/operations.py

    diff -r d3a1dd01e8da django/contrib/gis/db/backends/spatialite/operations.py
    a b  
    4848    return (SpatiaLiteDistance(operator),)
    4949
    5050class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations):
    51     compiler_module = 'django.contrib.gis.db.models.sql.compiler'
     51    compiler_module = 'django.contrib.gis.db.backends.spatialite.compiler'
    5252    name = 'spatialite'
    5353    spatialite = True
    5454    version_regex = re.compile(r'^(?P<major>\d)\.(?P<minor1>\d)\.(?P<minor2>\d+)')
  • django/contrib/gis/db/models/sql/compiler.py

    diff -r d3a1dd01e8da django/contrib/gis/db/models/sql/compiler.py
    a b  
    202202    #### Routines unique to GeoQuery ####
    203203    def get_extra_select_format(self, alias):
    204204        sel_fmt = '%s'
    205         if alias in self.query.custom_select:
     205        if hasattr(self.query, 'custom_select') and alias in self.query.custom_select:
    206206            sel_fmt = sel_fmt % self.query.custom_select[alias]
    207207        return sel_fmt
    208208
  • django/contrib/gis/tests/geoapp/models.py

    diff -r d3a1dd01e8da django/contrib/gis/tests/geoapp/models.py
    a b  
    1919# This is an inherited model from City
    2020class PennsylvaniaCity(City):
    2121    county = models.CharField(max_length=30)
     22    founded = models.DateTimeField(null=True)
    2223    objects = models.GeoManager() # TODO: This should be implicitly inherited.
    2324
    2425class State(models.Model):
  • django/contrib/gis/tests/geoapp/test_regress.py

    diff -r d3a1dd01e8da django/contrib/gis/tests/geoapp/test_regress.py
    a b  
    1 import unittest
     1from datetime import datetime
    22from django.contrib.gis.tests.utils import no_mysql, no_spatialite
    33from django.contrib.gis.shortcuts import render_to_kmz
    4 from models import City
     4from django.test import TestCase
     5from models import City, PennsylvaniaCity
    56
    6 class GeoRegressionTests(unittest.TestCase):
     7class GeoRegressionTests(TestCase):
    78
    89    def test01_update(self):
    910        "Testing GeoQuerySet.update(), see #10411."
     
    3536        extent = City.objects.filter(name='Pueblo').extent()
    3637        for ref_val, val in zip(ref_ext, extent):
    3738            self.assertAlmostEqual(ref_val, val, 4)
     39
     40    def test04_unicode_date(self):
     41        "Testing dates are converted properly, even on SpatiaLite, see #16408."
     42        founded = datetime(1857, 5, 23)
     43        mansfield = PennsylvaniaCity.objects.create(name='Mansfield', county='Tioga', point='POINT(-77.071445 41.823881)',
     44                                                    founded=founded)
     45        self.assertEqual(founded, PennsylvaniaCity.objects.dates('founded', 'day')[0])
Back to Top