Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(405)

Unified Diff: venv/Lib/site-packages/django/db/backends/utils.py

Issue 554060043: testMe
Patch Set: Created 2 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: venv/Lib/site-packages/django/db/backends/utils.py
===================================================================
new file mode 100644
--- /dev/null
+++ b/venv/Lib/site-packages/django/db/backends/utils.py
@@ -0,0 +1,242 @@
+from __future__ import unicode_literals
+
+import datetime
+import decimal
+import hashlib
+import logging
+from time import time
+
+from django.conf import settings
+from django.utils.encoding import force_bytes
+from django.utils.timezone import utc
+
+logger = logging.getLogger('django.db.backends')
+
+
+class CursorWrapper(object):
+ def __init__(self, cursor, db):
+ self.cursor = cursor
+ self.db = db
+
+ WRAP_ERROR_ATTRS = frozenset(['fetchone', 'fetchmany', 'fetchall', 'nextset'])
+
+ def __getattr__(self, attr):
+ cursor_attr = getattr(self.cursor, attr)
+ if attr in CursorWrapper.WRAP_ERROR_ATTRS:
+ return self.db.wrap_database_errors(cursor_attr)
+ else:
+ return cursor_attr
+
+ def __iter__(self):
+ with self.db.wrap_database_errors:
+ for item in self.cursor:
+ yield item
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, traceback):
+ # Close instead of passing through to avoid backend-specific behavior
+ # (#17671). Catch errors liberally because errors in cleanup code
+ # aren't useful.
+ try:
+ self.close()
+ except self.db.Database.Error:
+ pass
+
+ # The following methods cannot be implemented in __getattr__, because the
+ # code must run when the method is invoked, not just when it is accessed.
+
+ def callproc(self, procname, params=None):
+ self.db.validate_no_broken_transaction()
+ with self.db.wrap_database_errors:
+ if params is None:
+ return self.cursor.callproc(procname)
+ else:
+ return self.cursor.callproc(procname, params)
+
+ def execute(self, sql, params=None):
+ self.db.validate_no_broken_transaction()
+ with self.db.wrap_database_errors:
+ if params is None:
+ return self.cursor.execute(sql)
+ else:
+ return self.cursor.execute(sql, params)
+
+ def executemany(self, sql, param_list):
+ self.db.validate_no_broken_transaction()
+ with self.db.wrap_database_errors:
+ return self.cursor.executemany(sql, param_list)
+
+
+class CursorDebugWrapper(CursorWrapper):
+
+ # XXX callproc isn't instrumented at this time.
+
+ def execute(self, sql, params=None):
+ start = time()
+ try:
+ return super(CursorDebugWrapper, self).execute(sql, params)
+ finally:
+ stop = time()
+ duration = stop - start
+ sql = self.db.ops.last_executed_query(self.cursor, sql, params)
+ self.db.queries_log.append({
+ 'sql': sql,
+ 'time': "%.3f" % duration,
+ })
+ logger.debug(
+ '(%.3f) %s; args=%s', duration, sql, params,
+ extra={'duration': duration, 'sql': sql, 'params': params}
+ )
+
+ def executemany(self, sql, param_list):
+ start = time()
+ try:
+ return super(CursorDebugWrapper, self).executemany(sql, param_list)
+ finally:
+ stop = time()
+ duration = stop - start
+ try:
+ times = len(param_list)
+ except TypeError: # param_list could be an iterator
+ times = '?'
+ self.db.queries_log.append({
+ 'sql': '%s times: %s' % (times, sql),
+ 'time': "%.3f" % duration,
+ })
+ logger.debug(
+ '(%.3f) %s; args=%s', duration, sql, param_list,
+ extra={'duration': duration, 'sql': sql, 'params': param_list}
+ )
+
+
+###############################################
+# Converters from database (string) to Python #
+###############################################
+
+def typecast_date(s):
+ return datetime.date(*map(int, s.split('-'))) if s else None # returns None if s is null
+
+
+def typecast_time(s): # does NOT store time zone information
+ if not s:
+ return None
+ hour, minutes, seconds = s.split(':')
+ if '.' in seconds: # check whether seconds have a fractional part
+ seconds, microseconds = seconds.split('.')
+ else:
+ microseconds = '0'
+ return datetime.time(int(hour), int(minutes), int(seconds), int((microseconds + '000000')[:6]))
+
+
+def typecast_timestamp(s): # does NOT store time zone information
+ # "2005-07-29 15:48:00.590358-05"
+ # "2005-07-29 09:56:00-05"
+ if not s:
+ return None
+ if ' ' not in s:
+ return typecast_date(s)
+ d, t = s.split()
+ # Extract timezone information, if it exists. Currently we just throw
+ # it away, but in the future we may make use of it.
+ if '-' in t:
+ t, tz = t.split('-', 1)
+ tz = '-' + tz
+ elif '+' in t:
+ t, tz = t.split('+', 1)
+ tz = '+' + tz
+ else:
+ tz = ''
+ dates = d.split('-')
+ times = t.split(':')
+ seconds = times[2]
+ if '.' in seconds: # check whether seconds have a fractional part
+ seconds, microseconds = seconds.split('.')
+ else:
+ microseconds = '0'
+ tzinfo = utc if settings.USE_TZ else None
+ return datetime.datetime(
+ int(dates[0]), int(dates[1]), int(dates[2]),
+ int(times[0]), int(times[1]), int(seconds),
+ int((microseconds + '000000')[:6]), tzinfo
+ )
+
+
+def typecast_decimal(s):
+ if s is None or s == '':
+ return None
+ return decimal.Decimal(s)
+
+
+###############################################
+# Converters from Python to database (string) #
+###############################################
+
+def rev_typecast_decimal(d):
+ if d is None:
+ return None
+ return str(d)
+
+
+def split_identifier(identifier):
+ """
+ Split a SQL identifier into a two element tuple of (namespace, name).
+
+ The identifier could be a table, column, or sequence name might be prefixed
+ by a namespace.
+ """
+ try:
+ namespace, name = identifier.split('"."')
+ except ValueError:
+ namespace, name = '', identifier
+ return namespace.strip('"'), name.strip('"')
+
+
+def truncate_name(identifier, length=None, hash_len=4):
+ """
+ Shorten a SQL identifier to a repeatable mangled version with the given
+ length.
+
+ If a quote stripped name contains a namespace, e.g. USERNAME"."TABLE,
+ truncate the table portion only.
+ """
+ namespace, name = split_identifier(identifier)
+
+ if length is None or len(name) <= length:
+ return identifier
+
+ digest = hashlib.md5(force_bytes(name)).hexdigest()[:hash_len]
+ return '%s%s%s' % ('%s"."' % namespace if namespace else '', name[:length - hash_len], digest)
+
+
+def format_number(value, max_digits, decimal_places):
+ """
+ Formats a number into a string with the requisite number of digits and
+ decimal places.
+ """
+ if value is None:
+ return None
+ if isinstance(value, decimal.Decimal):
+ context = decimal.getcontext().copy()
+ if max_digits is not None:
+ context.prec = max_digits
+ if decimal_places is not None:
+ value = value.quantize(decimal.Decimal(".1") ** decimal_places, context=context)
+ else:
+ context.traps[decimal.Rounded] = 1
+ value = context.create_decimal(value)
+ return "{:f}".format(value)
+ if decimal_places is not None:
+ return "%.*f" % (decimal_places, value)
+ return "{:f}".format(value)
+
+
+def strip_quotes(table_name):
+ """
+ Strip quotes off of quoted table names to make them safe for use in index
+ names, sequence names, etc. For example '"USER"."TABLE"' (an Oracle naming
+ scheme) becomes 'USER"."TABLE'.
+ """
+ has_quotes = table_name.startswith('"') and table_name.endswith('"')
+ return table_name[1:-1] if has_quotes else table_name
« no previous file with comments | « venv/Lib/site-packages/django/db/backends/signals.py ('k') | venv/Lib/site-packages/django/db/migrations/__init__.py » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b