[1.6.x] Fixed #21109 -- made db cursor error wrapping faster

Backpatch of 9400142132 from master.
This commit is contained in:
Anssi Kääriäinen 2013-09-15 10:12:16 +03:00
parent c0625a74ce
commit 5937f291c1
3 changed files with 18 additions and 12 deletions

View File

@ -120,29 +120,29 @@ class BaseDatabaseWrapper(object):
Guarantees that a connection to the database is established. Guarantees that a connection to the database is established.
""" """
if self.connection is None: if self.connection is None:
with self.wrap_database_errors(): with self.wrap_database_errors:
self.connect() self.connect()
##### Backend-specific wrappers for PEP-249 connection methods ##### ##### Backend-specific wrappers for PEP-249 connection methods #####
def _cursor(self): def _cursor(self):
self.ensure_connection() self.ensure_connection()
with self.wrap_database_errors(): with self.wrap_database_errors:
return self.create_cursor() return self.create_cursor()
def _commit(self): def _commit(self):
if self.connection is not None: if self.connection is not None:
with self.wrap_database_errors(): with self.wrap_database_errors:
return self.connection.commit() return self.connection.commit()
def _rollback(self): def _rollback(self):
if self.connection is not None: if self.connection is not None:
with self.wrap_database_errors(): with self.wrap_database_errors:
return self.connection.rollback() return self.connection.rollback()
def _close(self): def _close(self):
if self.connection is not None: if self.connection is not None:
with self.wrap_database_errors(): with self.wrap_database_errors:
return self.connection.close() return self.connection.close()
##### Generic wrappers for PEP-249 connection methods ##### ##### Generic wrappers for PEP-249 connection methods #####
@ -482,6 +482,7 @@ class BaseDatabaseWrapper(object):
##### Miscellaneous ##### ##### Miscellaneous #####
@cached_property
def wrap_database_errors(self): def wrap_database_errors(self):
""" """
Context manager and decorator that re-throws backend-specific database Context manager and decorator that re-throws backend-specific database

View File

@ -19,13 +19,17 @@ class CursorWrapper(object):
self.cursor = cursor self.cursor = cursor
self.db = db self.db = db
SET_DIRTY_ATTRS = frozenset(['execute', 'executemany', 'callproc'])
WRAP_ERROR_ATTRS = frozenset([
'callproc', 'close', 'execute', 'executemany',
'fetchone', 'fetchmany', 'fetchall', 'nextset'])
def __getattr__(self, attr): def __getattr__(self, attr):
if attr in ('execute', 'executemany', 'callproc'): if attr in CursorWrapper.SET_DIRTY_ATTRS:
self.db.set_dirty() self.db.set_dirty()
cursor_attr = getattr(self.cursor, attr) cursor_attr = getattr(self.cursor, attr)
if attr in ('callproc', 'close', 'execute', 'executemany', if attr in CursorWrapper.WRAP_ERROR_ATTRS:
'fetchone', 'fetchmany', 'fetchall', 'nextset'): return self.db.wrap_database_errors(cursor_attr)
return self.db.wrap_database_errors()(cursor_attr)
else: else:
return cursor_attr return cursor_attr
@ -39,7 +43,7 @@ class CursorDebugWrapper(CursorWrapper):
self.db.set_dirty() self.db.set_dirty()
start = time() start = time()
try: try:
with self.db.wrap_database_errors(): with self.db.wrap_database_errors:
if params is None: if params is None:
# params default might be backend specific # params default might be backend specific
return self.cursor.execute(sql) return self.cursor.execute(sql)
@ -60,7 +64,7 @@ class CursorDebugWrapper(CursorWrapper):
self.db.set_dirty() self.db.set_dirty()
start = time() start = time()
try: try:
with self.db.wrap_database_errors(): with self.db.wrap_database_errors:
return self.cursor.executemany(sql, param_list) return self.cursor.executemany(sql, param_list)
finally: finally:
stop = time() stop = time()

View File

@ -99,7 +99,8 @@ class DatabaseErrorWrapper(object):
six.reraise(dj_exc_type, dj_exc_value, traceback) six.reraise(dj_exc_type, dj_exc_value, traceback)
def __call__(self, func): def __call__(self, func):
@wraps(func) # Note that we are intentionally not using @wraps here for performance
# reasons. Refs #21109.
def inner(*args, **kwargs): def inner(*args, **kwargs):
with self: with self:
return func(*args, **kwargs) return func(*args, **kwargs)