mirror of https://github.com/django/django.git
Fixed #7637 -- Added an extra parameterisation hook to the Oracle backend.
Required for some extension modules (in particular, geo-django). Patch from Justin Bronn. git-svn-id: http://code.djangoproject.com/svn/django/trunk@8145 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
726a24c609
commit
464a9c8ca4
|
@ -257,6 +257,26 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
cursor.arraysize = 100
|
cursor.arraysize = 100
|
||||||
return cursor
|
return cursor
|
||||||
|
|
||||||
|
class OracleParam(object):
|
||||||
|
"""
|
||||||
|
Wrapper object for formatting parameters for Oracle. If the string
|
||||||
|
representation of the value is large enough (greater than 4000 characters)
|
||||||
|
the input size needs to be set as NCLOB. Alternatively, if the parameter has
|
||||||
|
an `input_size` attribute, then the value of the `input_size` attribute will
|
||||||
|
be used instead. Otherwise, no input size will be set for the parameter when
|
||||||
|
executing the query.
|
||||||
|
"""
|
||||||
|
def __init__(self, param, charset, strings_only=False):
|
||||||
|
self.smart_str = smart_str(param, charset, strings_only)
|
||||||
|
if hasattr(param, 'input_size'):
|
||||||
|
# If parameter has `input_size` attribute, use that.
|
||||||
|
self.input_size = param.input_size
|
||||||
|
elif isinstance(param, basestring) and len(param) > 4000:
|
||||||
|
# Mark any string parameter greater than 4000 characters as an NCLOB.
|
||||||
|
self.input_size = Database.NCLOB
|
||||||
|
else:
|
||||||
|
self.input_size = None
|
||||||
|
|
||||||
class FormatStylePlaceholderCursor(Database.Cursor):
|
class FormatStylePlaceholderCursor(Database.Cursor):
|
||||||
"""
|
"""
|
||||||
Django uses "format" (e.g. '%s') style placeholders, but Oracle uses ":var"
|
Django uses "format" (e.g. '%s') style placeholders, but Oracle uses ":var"
|
||||||
|
@ -271,15 +291,13 @@ class FormatStylePlaceholderCursor(Database.Cursor):
|
||||||
def _format_params(self, params):
|
def _format_params(self, params):
|
||||||
if isinstance(params, dict):
|
if isinstance(params, dict):
|
||||||
result = {}
|
result = {}
|
||||||
charset = self.charset
|
|
||||||
for key, value in params.items():
|
for key, value in params.items():
|
||||||
result[smart_str(key, charset)] = smart_str(value, charset)
|
result[smart_str(key, self.charset)] = OracleParam(param, self.charset)
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
return tuple([smart_str(p, self.charset, True) for p in params])
|
return tuple([OracleParam(p, self.charset, True) for p in params])
|
||||||
|
|
||||||
def _guess_input_sizes(self, params_list):
|
def _guess_input_sizes(self, params_list):
|
||||||
# Mark any string parameter greater than 4000 characters as an NCLOB.
|
|
||||||
if isinstance(params_list[0], dict):
|
if isinstance(params_list[0], dict):
|
||||||
sizes = {}
|
sizes = {}
|
||||||
iterators = [params.iteritems() for params in params_list]
|
iterators = [params.iteritems() for params in params_list]
|
||||||
|
@ -288,13 +306,18 @@ class FormatStylePlaceholderCursor(Database.Cursor):
|
||||||
iterators = [enumerate(params) for params in params_list]
|
iterators = [enumerate(params) for params in params_list]
|
||||||
for iterator in iterators:
|
for iterator in iterators:
|
||||||
for key, value in iterator:
|
for key, value in iterator:
|
||||||
if isinstance(value, basestring) and len(value) > 4000:
|
if value.input_size: sizes[key] = value.input_size
|
||||||
sizes[key] = Database.NCLOB
|
|
||||||
if isinstance(sizes, dict):
|
if isinstance(sizes, dict):
|
||||||
self.setinputsizes(**sizes)
|
self.setinputsizes(**sizes)
|
||||||
else:
|
else:
|
||||||
self.setinputsizes(*sizes)
|
self.setinputsizes(*sizes)
|
||||||
|
|
||||||
|
def _param_generator(self, params):
|
||||||
|
if isinstance(params, dict):
|
||||||
|
return dict([(k, p.smart_str) for k, p in params.iteritems()])
|
||||||
|
else:
|
||||||
|
return [p.smart_str for p in params]
|
||||||
|
|
||||||
def execute(self, query, params=None):
|
def execute(self, query, params=None):
|
||||||
if params is None:
|
if params is None:
|
||||||
params = []
|
params = []
|
||||||
|
@ -309,7 +332,7 @@ class FormatStylePlaceholderCursor(Database.Cursor):
|
||||||
query = query[:-1]
|
query = query[:-1]
|
||||||
query = smart_str(query, self.charset) % tuple(args)
|
query = smart_str(query, self.charset) % tuple(args)
|
||||||
self._guess_input_sizes([params])
|
self._guess_input_sizes([params])
|
||||||
return Database.Cursor.execute(self, query, params)
|
return Database.Cursor.execute(self, query, self._param_generator(params))
|
||||||
|
|
||||||
def executemany(self, query, params=None):
|
def executemany(self, query, params=None):
|
||||||
try:
|
try:
|
||||||
|
@ -324,9 +347,9 @@ class FormatStylePlaceholderCursor(Database.Cursor):
|
||||||
if query.endswith(';') or query.endswith('/'):
|
if query.endswith(';') or query.endswith('/'):
|
||||||
query = query[:-1]
|
query = query[:-1]
|
||||||
query = smart_str(query, self.charset) % tuple(args)
|
query = smart_str(query, self.charset) % tuple(args)
|
||||||
new_param_list = [self._format_params(i) for i in params]
|
formatted = [self._format_params(i) for i in params]
|
||||||
self._guess_input_sizes(new_param_list)
|
self._guess_input_sizes(formatted)
|
||||||
return Database.Cursor.executemany(self, query, new_param_list)
|
return Database.Cursor.executemany(self, query, [self._param_generator(p) for p in formatted])
|
||||||
|
|
||||||
def fetchone(self):
|
def fetchone(self):
|
||||||
row = Database.Cursor.fetchone(self)
|
row = Database.Cursor.fetchone(self)
|
||||||
|
|
Loading…
Reference in New Issue