Commit 6f4563ac authored by Ian Kelly's avatar Ian Kelly
Browse files

[1.1.X] Fixed a bug preventing cursor variables from being passed as bind...

[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
parent 5f1ecdc5
Loading
Loading
Loading
Loading
+33 −3
Original line number Diff line number Diff line
@@ -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]
+10 −0
Original line number Diff line number Diff line
@@ -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):