Commit f6de03b3 authored by Ramiro Morales's avatar Ramiro Morales
Browse files

[1.2.X] Fixed #14223 -- Extended unification of exception raised in presence...

[1.2.X] Fixed #14223 -- Extended unification of exception raised in presence of integrity constraint violations.

The unification had been introduced in r12352 and native backend exceptions still
slipped through in cases that end in connection.commit() call. Thanks Alex,
Jacob and Carl for reviewing.

Backport of [14320] from trunk

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@14321 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 7377e4f9
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -150,6 +150,13 @@ class DatabaseWrapper(BaseDatabaseWrapper):
            cursor.execute("SET client_encoding to 'UNICODE'")
        return UnicodeCursorWrapper(cursor, 'utf-8')

    def _commit(self):
        if self.connection is not None:
            try:
                return self.connection.commit()
            except Database.IntegrityError, e:
                raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]

def typecast_string(s):
    """
    Cast all returned strings to unicode strings.
+7 −0
Original line number Diff line number Diff line
@@ -189,3 +189,10 @@ class DatabaseWrapper(BaseDatabaseWrapper):
        finally:
            self.isolation_level = level
            self.features.uses_savepoints = bool(level)

    def _commit(self):
        if self.connection is not None:
            try:
                return self.connection.commit()
            except Database.IntegrityError, e:
                raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
+15 −1
Original line number Diff line number Diff line
from django.db import models
from django.db import connection

class Square(models.Model):
    root = models.IntegerField()
@@ -21,3 +20,18 @@ class SchoolClass(models.Model):
    last_updated = models.DateTimeField()


class Reporter(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

    def __unicode__(self):
        return u"%s %s" % (self.first_name, self.last_name)


class Article(models.Model):
    headline = models.CharField(max_length=100)
    pub_date = models.DateField()
    reporter = models.ForeignKey(Reporter)

    def __unicode__(self):
        return self.headline
+46 −4
Original line number Diff line number Diff line
# -*- coding: utf-8 -*-
# Unit and doctests for specific database backends.
import datetime
import models
import unittest
from django.db import backend, connection, DEFAULT_DB_ALIAS

from django.conf import settings
from django.db import backend, connection, DEFAULT_DB_ALIAS, IntegrityError
from django.db.backends.signals import connection_created
from django.db.backends.postgresql import version as pg_version
from django.conf import settings
from django.test import TestCase
from django.test import TestCase, TransactionTestCase

import models

class Callproc(unittest.TestCase):

@@ -141,6 +143,46 @@ class BackendTestCase(TestCase):
        cursor.executemany(query, [])
        self.assertEqual(models.Square.objects.count(), 11)


# We don't make these tests conditional because that means we would need to
# check and differentiate between:
# * MySQL+InnoDB, MySQL+MYISAM (something we currently can't do).
# * if sqlite3 (if/once we get #14204 fixed) has referential integrity turned
#   on or not, something that would be controlled by runtime support and user
#   preference.
# verify if its type is django.database.db.IntegrityError.

class FkConstraintsTests(TransactionTestCase):

    def setUp(self):
        # Create a Reporter.
        self.r = models.Reporter.objects.create(first_name='John', last_name='Smith')

    def test_integrity_checks_on_creation(self):
        """
        Try to create a model instance that violates a FK constraint. If it
        fails it should fail with IntegrityError.
        """
        a = models.Article(headline="This is a test", pub_date=datetime.datetime(2005, 7, 27), reporter_id=30)
        try:
            a.save()
        except IntegrityError:
            pass

    def test_integrity_checks_on_update(self):
        """
        Try to update a model instance introducing a FK constraint violation.
        If it fails it should fail with IntegrityError.
        """
        # Create an Article.
        models.Article.objects.create(headline="Test article", pub_date=datetime.datetime(2010, 9, 4), reporter=self.r)
        # Retrive it from the DB
        a = models.Article.objects.get(headline="Test article")
        a.reporter_id = 30
        try:
            a.save()
        except IntegrityError:
            pass
    def test_unicode_fetches(self):
        #6254: fetchone, fetchmany, fetchall return strings as unicode objects
        qn = connection.ops.quote_name