mirror of
				https://github.com/django/django.git
				synced 2025-11-04 05:35:37 +00:00 
			
		
		
		
	Fixed a bug preventing cursor variables from being passed as bind parameters in the oracle backend.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@13042 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		
							parent
							
								
									5926a26e92
								
							
						
					
					
						commit
						6a1cf9369f
					
				
					 2 changed files with 43 additions and 3 deletions
				
			
		| 
						 | 
				
			
			@ -423,6 +423,30 @@ class OracleParam(object):
 | 
			
		|||
            self.input_size = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VariableWrapper(object):
 | 
			
		||||
    """
 | 
			
		||||
    An adapter class for cursor variables that prevents the wrapped object
 | 
			
		||||
    from being converted into a string when used to instanciate an OracleParam.
 | 
			
		||||
    This can be used generally for any other object that should be passed into
 | 
			
		||||
    Cursor.execute as-is.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, var):
 | 
			
		||||
        self.var = var
 | 
			
		||||
 | 
			
		||||
    def bind_parameter(self, cursor):
 | 
			
		||||
        return self.var
 | 
			
		||||
 | 
			
		||||
    def __getattr__(self, key):
 | 
			
		||||
        return getattr(self.var, key)
 | 
			
		||||
 | 
			
		||||
    def __setattr__(self, key, value):
 | 
			
		||||
        if key == 'var':
 | 
			
		||||
            self.__dict__[key] = value
 | 
			
		||||
        else:
 | 
			
		||||
            setattr(self.var, key, value)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class InsertIdVar(object):
 | 
			
		||||
    """
 | 
			
		||||
    A late-binding cursor variable that can be passed to Cursor.execute
 | 
			
		||||
| 
						 | 
				
			
			@ -431,7 +455,7 @@ class InsertIdVar(object):
 | 
			
		|||
    """
 | 
			
		||||
 | 
			
		||||
    def bind_parameter(self, cursor):
 | 
			
		||||
        param = cursor.var(Database.NUMBER)
 | 
			
		||||
        param = cursor.cursor.var(Database.NUMBER)
 | 
			
		||||
        cursor._insert_id_var = param
 | 
			
		||||
        return param
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -488,7 +512,7 @@ class FormatStylePlaceholderCursor(object):
 | 
			
		|||
            raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
 | 
			
		||||
        except Database.DatabaseError, e:
 | 
			
		||||
            # cx_Oracle <= 4.4.0 wrongly raises a DatabaseError for ORA-01400.
 | 
			
		||||
            if e.args[0].code == 1400 and not isinstance(e, IntegrityError):
 | 
			
		||||
            if hasattr(e.args[0], 'code') and e.args[0].code == 1400 and not isinstance(e, IntegrityError):
 | 
			
		||||
                raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
 | 
			
		||||
            raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -514,7 +538,7 @@ class FormatStylePlaceholderCursor(object):
 | 
			
		|||
            raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
 | 
			
		||||
        except Database.DatabaseError, e:
 | 
			
		||||
            # cx_Oracle <= 4.4.0 wrongly raises a DatabaseError for ORA-01400.
 | 
			
		||||
            if e.args[0].code == 1400 and not isinstance(e, IntegrityError):
 | 
			
		||||
            if hasattr(e.args[0], 'code') and e.args[0].code == 1400 and not isinstance(e, IntegrityError):
 | 
			
		||||
                raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
 | 
			
		||||
            raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -534,6 +558,12 @@ class FormatStylePlaceholderCursor(object):
 | 
			
		|||
        return tuple([_rowfactory(r, self.cursor)
 | 
			
		||||
                      for r in self.cursor.fetchall()])
 | 
			
		||||
 | 
			
		||||
    def var(self, *args):
 | 
			
		||||
        return VariableWrapper(self.cursor.var(*args))
 | 
			
		||||
 | 
			
		||||
    def arrayvar(self, *args):
 | 
			
		||||
        return VariableWrapper(self.cursor.arrayvar(*args))
 | 
			
		||||
 | 
			
		||||
    def __getattr__(self, attr):
 | 
			
		||||
        if attr in self.__dict__:
 | 
			
		||||
            return self.__dict__[attr]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,16 @@ class Callproc(unittest.TestCase):
 | 
			
		|||
        else:
 | 
			
		||||
            return True
 | 
			
		||||
 | 
			
		||||
    def test_cursor_var(self):
 | 
			
		||||
        # If the backend is Oracle, test that we can pass cursor variables
 | 
			
		||||
        # as query parameters.
 | 
			
		||||
        if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle':
 | 
			
		||||
            cursor = connection.cursor()
 | 
			
		||||
            var = cursor.var(backend.Database.STRING)
 | 
			
		||||
            cursor.execute("BEGIN %s := 'X'; END; ", [var])
 | 
			
		||||
            self.assertEqual(var.getvalue(), 'X')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LongString(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def test_long_string(self):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue