Ticket #7637: orcl_custom_input_size.diff

File orcl_custom_input_size.diff, 4.0 KB (added by jbronn, 16 years ago)

Patch that allows Oracle database parameters to specify input size.

  • django/db/backends/oracle/base.py

     
    248248        cursor.arraysize = 100
    249249        return cursor
    250250
     251class OracleParam(object):
     252    """
     253    Wrapper object for formatting parameters for Oracle. If the string
     254    representation of the value is large enough (greater than 4000 characters)
     255    the input size needs to be set as NCLOB. Alternatively, if the parameter has
     256    an `input_size` attribute, then the value of the `input_size` attribute will
     257    be used instead. Otherwise, no input size will be set for the parameter when
     258    executing the query.
     259    """
     260    def __init__(self, param, charset, strings_only=False):
     261        self.smart_str = smart_str(param, charset, strings_only)
     262        if hasattr(param, 'input_size'):
     263            # If parameter has `input_size` attribute, use that.
     264            self.input_size = param.input_size
     265        elif isinstance(param, basestring) and len(param) > 4000:
     266            # Mark any string parameter greater than 4000 characters as an NCLOB.
     267            self.input_size = Database.NCLOB
     268        else:
     269            self.input_size = None
     270
    251271class FormatStylePlaceholderCursor(Database.Cursor):
    252272    """
    253273    Django uses "format" (e.g. '%s') style placeholders, but Oracle uses ":var"
     
    262282    def _format_params(self, params):
    263283        if isinstance(params, dict):
    264284            result = {}
    265             charset = self.charset
    266285            for key, value in params.items():
    267                 result[smart_str(key, charset)] = smart_str(value, charset)
     286                result[smart_str(key, self.charset)] = OracleParam(param, self.charset)
    268287            return result
    269288        else:
    270             return tuple([smart_str(p, self.charset, True) for p in params])
    271 
     289            return tuple([OracleParam(p, self.charset, True) for p in params])
     290   
    272291    def _guess_input_sizes(self, params_list):
    273         # Mark any string parameter greater than 4000 characters as an NCLOB.
    274292        if isinstance(params_list[0], dict):
    275293            sizes = {}
    276294            iterators = [params.iteritems() for params in params_list]
     
    279297            iterators = [enumerate(params) for params in params_list]
    280298        for iterator in iterators:
    281299            for key, value in iterator:
    282                 if isinstance(value, basestring) and len(value) > 4000:
    283                     sizes[key] = Database.NCLOB
     300                if value.input_size: sizes[key] = value.input_size
    284301        if isinstance(sizes, dict):
    285302            self.setinputsizes(**sizes)
    286303        else:
    287304            self.setinputsizes(*sizes)
    288305
     306    def _param_generator(self, params):
     307        if isinstance(params, dict):
     308            return dict([(k, p.smart_str) for k, p in params.iteritems()])
     309        else:
     310            return [p.smart_str for p in params]
     311       
    289312    def execute(self, query, params=None):
    290313        if params is None:
    291314            params = []
     
    300323            query = query[:-1]
    301324        query = smart_str(query, self.charset) % tuple(args)
    302325        self._guess_input_sizes([params])
    303         return Database.Cursor.execute(self, query, params)
     326        return Database.Cursor.execute(self, query, self._param_generator(params))
    304327
    305328    def executemany(self, query, params=None):
    306329        try:
     
    315338        if query.endswith(';') or query.endswith('/'):
    316339            query = query[:-1]
    317340        query = smart_str(query, self.charset) % tuple(args)
    318         new_param_list = [self._format_params(i) for i in params]
    319         self._guess_input_sizes(new_param_list)
    320         return Database.Cursor.executemany(self, query, new_param_list)
     341        formatted = [self._format_params(i) for i in params]
     342        self._guess_input_sizes(formatted)
     343        return Database.Cursor.executemany(self, query, [self._param_generator(p) for p in formatted])
    321344
    322345    def fetchone(self):
    323346        row = Database.Cursor.fetchone(self)
Back to Top