Commits

adamv committed 4432407

Fix for issue 37, raise IntegrityError when appropriate.

Comments (0)

Files changed (2)

source/sqlserver_ado/dbapi.py

             print 'Source: %s' % e.Source
             print 'NativeError: %s' % e.NativeError
             print 'SQL State: %s' % e.SQLState
+            
+    def _suggest_error_class(self):
+        """Introspect the current ADO Errors and determine an appropriate error class."""
+        if self.adoConn is not None:
+            for e in self.adoConn.Errors:
+                state = str(e.SQLState)
+                # 23000 are integrity errors
+                # 40002 is a transaction integrity error
+                # per SQL STATE definitions
+                # http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt
+                if state.startswith('23') or state=='40002':
+                    return IntegrityError
+            
+        return DatabaseError
 
     def __del__(self):
         try:
             _message = ""
             if hasattr(e, 'args'): _message += str(e.args)+"\n"
             _message += "Command:\n%s\nParameters:\n%s" %  (self.cmd.CommandText, format_parameters(self.cmd.Parameters, True))
-            self._raiseCursorError(DatabaseError, _message)
+            klass = self.connection._suggest_error_class()
+            self._raiseCursorError(klass, _message)
 
 
     def callproc(self, procname, parameters=None):

tests/test_main/regressiontests/models.py

 import datetime
 import decimal
-from django.db import models
+from django.db import models, IntegrityError
 from django.test import TestCase
 
 class Bug19Table(models.Model):
     
 class Bug35C2Table(Bug35CModel):
     name = models.CharField(max_length=10)
+
+
+class Bug37Table(models.Model):
+    """Inserting duplicate keys should raise an Integrity Error.
+    >>> Bug37Table(pk=1).save(force_insert=True)
+    >>> try:
+    ...     Bug37Table(pk=1).save(force_insert=True)
+    ... except Exception, e:
+    ...     if isinstance(e, IntegrityError):
+    ...         print "Pass"
+    ...     else:
+    ...         print "Fail with %s" % type(e)
+    Pass
+    """
+    pass