mirror of https://github.com/django/django.git
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
|
@ -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…
Reference in New Issue