[1.1.X] Fixed a bug preventing cursor variables from being passed as bind parameters in the oracle backend. Backport of r13042 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.1.X@13043 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
5f1ecdc51a
commit
6f4563aced
|
@ -376,6 +376,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
|
||||
|
@ -384,7 +408,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
|
||||
|
||||
|
@ -439,7 +463,7 @@ class FormatStylePlaceholderCursor(object):
|
|||
return self.cursor.execute(query, self._param_generator(params))
|
||||
except 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):
|
||||
e = IntegrityError(e.args[0])
|
||||
raise e
|
||||
|
||||
|
@ -463,7 +487,7 @@ class FormatStylePlaceholderCursor(object):
|
|||
[self._param_generator(p) for p in formatted])
|
||||
except 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):
|
||||
e = IntegrityError(e.args[0])
|
||||
raise e
|
||||
|
||||
|
@ -523,6 +547,12 @@ class FormatStylePlaceholderCursor(object):
|
|||
casted.append(value)
|
||||
return tuple(casted)
|
||||
|
||||
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.DATABASE_ENGINE == '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…
Reference in New Issue