summaryrefslogtreecommitdiff
path: root/src/mailman/database
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman/database')
-rw-r--r--src/mailman/database/base.py9
-rw-r--r--src/mailman/database/transaction.py56
2 files changed, 45 insertions, 20 deletions
diff --git a/src/mailman/database/base.py b/src/mailman/database/base.py
index 34f644afa..55dee2068 100644
--- a/src/mailman/database/base.py
+++ b/src/mailman/database/base.py
@@ -15,7 +15,7 @@
# You should have received a copy of the GNU General Public License along with
# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
@@ -32,7 +32,7 @@ from lazr.config import as_boolean
from pkg_resources import resource_listdir, resource_string
from storm.cache import GenerationalCache
from storm.locals import create_database, Store
-from zope.interface import implements
+from zope.interface import implementer
from mailman.config import config
from mailman.interfaces.database import IDatabase
@@ -45,6 +45,7 @@ NL = '\n'
+@implementer(IDatabase)
class StormBaseDatabase:
"""The database base class for use with the Storm ORM.
@@ -55,8 +56,6 @@ class StormBaseDatabase:
# classes.
TAG = ''
- implements(IDatabase)
-
def __init__(self):
self.url = None
self.store = None
@@ -194,7 +193,7 @@ class StormBaseDatabase:
:param store: The Storm store to load the schema into.
:type store: storm.locals.Store`
- :param version: The schema version identifier of the form
+ :param version: The schema version identifier of the form
YYYYMMDDHHMMSS.
:type version: string
:param filename: The file name containing the schema to load. Pass
diff --git a/src/mailman/database/transaction.py b/src/mailman/database/transaction.py
index 47e58d3e2..295f3d567 100644
--- a/src/mailman/database/transaction.py
+++ b/src/mailman/database/transaction.py
@@ -17,19 +17,36 @@
"""Transactional support."""
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
- 'txn',
+ 'dbconnection',
+ 'transaction',
+ 'transactional',
]
+from contextlib import contextmanager
+
from mailman.config import config
-class txn(object):
+@contextmanager
+def transaction():
+ """Context manager for ensuring the transaction is complete."""
+ try:
+ yield
+ except:
+ config.db.abort()
+ raise
+ else:
+ config.db.commit()
+
+
+
+def transactional(function):
"""Decorator for transactional support.
When the function this decorator wraps exits cleanly, the current
@@ -38,16 +55,25 @@ class txn(object):
Either way, the current transaction is completed.
"""
- def __init__(self, function):
- self._function = function
+ def wrapper(*args, **kws):
+ try:
+ rtn = function(*args, **kws)
+ config.db.commit()
+ return rtn
+ except:
+ config.db.abort()
+ raise
+ return wrapper
- def __get__(self, obj, type=None):
- def wrapper(*args, **kws):
- try:
- rtn = self._function(obj, *args, **kws)
- config.db.commit()
- return rtn
- except:
- config.db.abort()
- raise
- return wrapper
+
+
+def dbconnection(function):
+ """Decorator for getting at the database connection.
+
+ Use this to avoid having to access the global `config.db.store`
+ attribute. This calls the function with `store` as the first argument.
+ """
+ def wrapper(*args, **kws):
+ # args[0] is self.
+ return function(args[0], config.db.store, *args[1:], **kws)
+ return wrapper