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
|
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):
|
class InsertIdVar(object):
|
||||||
"""
|
"""
|
||||||
A late-binding cursor variable that can be passed to Cursor.execute
|
A late-binding cursor variable that can be passed to Cursor.execute
|
||||||
|
@ -431,7 +455,7 @@ class InsertIdVar(object):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def bind_parameter(self, cursor):
|
def bind_parameter(self, cursor):
|
||||||
param = cursor.var(Database.NUMBER)
|
param = cursor.cursor.var(Database.NUMBER)
|
||||||
cursor._insert_id_var = param
|
cursor._insert_id_var = param
|
||||||
return param
|
return param
|
||||||
|
|
||||||
|
@ -488,7 +512,7 @@ class FormatStylePlaceholderCursor(object):
|
||||||
raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
|
raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
|
||||||
except Database.DatabaseError, e:
|
except Database.DatabaseError, e:
|
||||||
# cx_Oracle <= 4.4.0 wrongly raises a DatabaseError for ORA-01400.
|
# 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.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
|
||||||
raise utils.DatabaseError, utils.DatabaseError(*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]
|
raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
|
||||||
except Database.DatabaseError, e:
|
except Database.DatabaseError, e:
|
||||||
# cx_Oracle <= 4.4.0 wrongly raises a DatabaseError for ORA-01400.
|
# 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.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
|
||||||
raise utils.DatabaseError, utils.DatabaseError(*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)
|
return tuple([_rowfactory(r, self.cursor)
|
||||||
for r in self.cursor.fetchall()])
|
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):
|
def __getattr__(self, attr):
|
||||||
if attr in self.__dict__:
|
if attr in self.__dict__:
|
||||||
return self.__dict__[attr]
|
return self.__dict__[attr]
|
||||||
|
|
|
@ -22,6 +22,16 @@ class Callproc(unittest.TestCase):
|
||||||
else:
|
else:
|
||||||
return True
|
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):
|
class LongString(unittest.TestCase):
|
||||||
|
|
||||||
def test_long_string(self):
|
def test_long_string(self):
|
||||||
|
|
Loading…
Reference in New Issue