Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed a bug preventing cursor variables from being passed as bind par…

…ameters in the oracle backend.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@13042 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 6a1cf9369fceba9833f7ad8702ebef80dc98291e 1 parent 5926a26
@ikelly ikelly authored
View
36 django/db/backends/oracle/base.py
@@ -423,6 +423,30 @@ def __init__(self, param, cursor, strings_only=False):
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 @@ def execute(self, query, params=None):
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 @@ def executemany(self, query, params=None):
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 @@ def fetchall(self):
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]
View
10 tests/regressiontests/backends/tests.py
@@ -22,6 +22,16 @@ def test_dbms_session(self):
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):
Please sign in to comment.
Something went wrong with that request. Please try again.