diff options
| author | Barry Warsaw | 2007-07-23 01:57:48 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2007-07-23 01:57:48 -0400 |
| commit | d07e48b456a35daed967a4b9cfb2cd4e00471d51 (patch) | |
| tree | b02e223999800b8a8d33d0a697f895dd0900f862 /Mailman/database/dbcontext.py | |
| parent | 2e4314fc178f34170b82aaa2f8ed4d0f5440f4f4 (diff) | |
| download | mailman-d07e48b456a35daed967a4b9cfb2cd4e00471d51.tar.gz mailman-d07e48b456a35daed967a4b9cfb2cd4e00471d51.tar.zst mailman-d07e48b456a35daed967a4b9cfb2cd4e00471d51.zip | |
Diffstat (limited to 'Mailman/database/dbcontext.py')
| -rw-r--r-- | Mailman/database/dbcontext.py | 174 |
1 files changed, 0 insertions, 174 deletions
diff --git a/Mailman/database/dbcontext.py b/Mailman/database/dbcontext.py deleted file mode 100644 index eaf87be93..000000000 --- a/Mailman/database/dbcontext.py +++ /dev/null @@ -1,174 +0,0 @@ -# Copyright (C) 2006-2007 by the Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -# USA. - -import os -import sys -import logging -import weakref - -from elixir import create_all, metadata, objectstore -from sqlalchemy import create_engine -from string import Template -from urlparse import urlparse - -from Mailman import Version -from Mailman.configuration import config -from Mailman.database.txnsupport import txn - - - -class MlistRef(weakref.ref): - def __init__(self, mlist, callback): - super(MlistRef, self).__init__(mlist, callback) - self.fqdn_listname = mlist.fqdn_listname - - - -class DBContext(object): - def __init__(self): - # Special transaction used only for MailList.Lock() .Save() and - # .Unlock() interface. - self._mlist_txns = {} - - def connect(self): - # Calculate the engine url - url = Template(config.SQLALCHEMY_ENGINE_URL).safe_substitute( - config.paths) - # XXX By design of SQLite, database file creation does not honor - # umask. See their ticket #1193: - # http://www.sqlite.org/cvstrac/tktview?tn=1193,31 - # - # This sucks for us because the mailman.db file /must/ be group - # writable, however even though we guarantee our umask is 002 here, it - # still gets created without the necessary g+w permission, due to - # SQLite's policy. This should only affect SQLite engines because its - # the only one that creates a little file on the local file system. - # This kludges around their bug by "touch"ing the database file before - # SQLite has any chance to create it, thus honoring the umask and - # ensuring the right permissions. We only try to do this for SQLite - # engines, and yes, we could have chmod'd the file after the fact, but - # half dozen and all... - self._touch(url) - engine = create_engine(url) - engine.echo = config.SQLALCHEMY_ECHO - metadata.connect(engine) - # Load and create the Elixir active records. This works by - # side-effect. - import Mailman.database.model - create_all() - # Validate schema version. - v = Mailman.database.model.Version.get_by(component='schema') - if not v: - # Database has not yet been initialized - v = Mailman.database.model.Version( - component='schema', - version=Version.DATABASE_SCHEMA_VERSION) - objectstore.flush() - elif v.version <> Version.DATABASE_SCHEMA_VERSION: - # XXX Update schema - raise SchemaVersionMismatchError(v.version) - - def _touch(self, url): - parts = urlparse(url) - if parts.scheme <> 'sqlite': - return - path = os.path.normpath(parts.path) - fd = os.open(path, os.O_WRONLY | os.O_NONBLOCK | os.O_CREAT, 0666) - # Ignore errors - if fd > 0: - os.close(fd) - - # Cooperative method for use with @txn decorator - def _withtxn(self, meth, *args, **kws): - try: - txn = objectstore.session.current.create_transaction() - rtn = meth(*args, **kws) - except: - txn.rollback() - raise - else: - txn.commit() - return rtn - - def _unlock_mref(self, mref): - txn = self._mlist_txns.pop(mref.fqdn_listname, None) - if txn is not None: - txn.rollback() - - # Higher level interface - def api_lock(self, mlist): - # Don't try to re-lock a list - if mlist.fqdn_listname in self._mlist_txns: - return - txn = objectstore.session.current.create_transaction() - mref = MlistRef(mlist, self._unlock_mref) - # If mlist.host_name is changed, its fqdn_listname attribute will no - # longer match, so its transaction will not get committed when the - # list is saved. To avoid this, store on the mlist object the key - # under which its transaction is stored. - txnkey = mlist._txnkey = mlist.fqdn_listname - self._mlist_txns[txnkey] = txn - - def api_unlock(self, mlist): - try: - txnkey = mlist._txnkey - except AttributeError: - return - txn = self._mlist_txns.pop(txnkey, None) - if txn is not None: - txn.rollback() - del mlist._txnkey - - def api_load(self, mlist): - # Mark the MailList object such that future attribute accesses will - # refresh from the database. - objectstore.session.current.expire(mlist) - - def api_save(self, mlist): - # When dealing with MailLists, .Save() will always be followed by - # .Unlock(). However lists can also be unlocked without saving. But - # if it's been locked it will always be unlocked. So the rollback in - # unlock will essentially be no-op'd if we've already saved the list. - try: - txnkey = mlist._txnkey - except AttributeError: - return - txn = self._mlist_txns.pop(txnkey, None) - if txn is not None: - txn.commit() - - @txn - def api_add_list(self, mlist): - objectstore.session.current.save(mlist) - - @txn - def api_remove_list(self, mlist): - objectstore.session.current.delete(mlist) - - @txn - def api_find_list(self, listname, hostname): - from Mailman.MailList import MailList - q = objectstore.session.current.query(MailList) - mlists = q.select_by(list_name=listname, host_name=hostname) - assert len(mlists) <= 1, 'Duplicate mailing lists!' - if mlists: - return mlists[0] - return None - - - -dbcontext = DBContext() |
