root/galaxy-central/eggs/Beaker-1.4-py2.6.egg/beaker/ext/sqla.py

リビジョン 3, 4.3 KB (コミッタ: kohda, 14 年 前)

Install Unix tools  http://hannonlab.cshl.edu/galaxy_unix_tools/galaxy.html

行番号 
1import cPickle
2import logging
3import pickle
4from datetime import datetime
5
6from beaker.container import OpenResourceNamespaceManager, Container
7from beaker.exceptions import InvalidCacheBackendError, MissingCacheParameter
8from beaker.synchronization import file_synchronizer, null_synchronizer
9from beaker.util import verify_directory, SyncDict
10
11try:
12    import sqlalchemy as sa
13except ImportError:
14    raise InvalidCacheBackendError('SQLAlchemy, which is required by this backend, is not installed')
15
16log = logging.getLogger(__name__)
17
18class SqlaNamespaceManager(OpenResourceNamespaceManager):
19    binds = SyncDict()
20    tables = SyncDict()
21
22    def __init__(self, namespace, bind, table, data_dir=None, lock_dir=None,
23                 **kwargs):
24        """Create a namespace manager for use with a database table via
25        SQLAlchemy.
26
27        ``bind``
28            SQLAlchemy ``Engine`` or ``Connection`` object
29
30        ``table``
31            SQLAlchemy ``Table`` object in which to store namespace data.
32            This should usually be something created by ``make_cache_table``.
33        """
34        OpenResourceNamespaceManager.__init__(self, namespace)
35
36        if lock_dir:
37            self.lock_dir = lock_dir
38        elif data_dir:
39            self.lock_dir = data_dir + "/container_db_lock"
40        if self.lock_dir:
41            verify_directory(self.lock_dir)           
42
43        self.bind = self.__class__.binds.get(str(bind.url), lambda: bind)
44        self.table = self.__class__.tables.get('%s:%s' % (bind.url, table.name),
45                                               lambda: table)
46        self.hash = {}
47        self._is_new = False
48        self.loaded = False
49
50    def get_access_lock(self):
51        return null_synchronizer()
52
53    def get_creation_lock(self, key):
54        return file_synchronizer(
55            identifier ="databasecontainer/funclock/%s" % self.namespace,
56            lock_dir=self.lock_dir)
57
58    def do_open(self, flags):
59        if self.loaded:
60            self.flags = flags
61            return
62        select = sa.select([self.table.c.data],
63                           (self.table.c.namespace == self.namespace))
64        result = self.bind.execute(select).fetchone()
65        if not result:
66            self._is_new = True
67            self.hash = {}
68        else:
69            self._is_new = False
70            try:
71                self.hash = result['data']
72            except (IOError, OSError, EOFError, cPickle.PickleError,
73                    pickle.PickleError):
74                log.debug("Couln't load pickle data, creating new storage")
75                self.hash = {}
76                self._is_new = True
77        self.flags = flags
78        self.loaded = True
79
80    def do_close(self):
81        if self.flags is not None and (self.flags == 'c' or self.flags == 'w'):
82            if self._is_new:
83                insert = self.table.insert()
84                self.bind.execute(insert, namespace=self.namespace, data=self.hash,
85                                  accessed=datetime.now(), created=datetime.now())
86                self._is_new = False
87            else:
88                update = self.table.update(self.table.c.namespace == self.namespace)
89                self.bind.execute(update, data=self.hash, accessed=datetime.now())
90        self.flags = None
91
92    def do_remove(self):
93        delete = self.table.delete(self.table.c.namespace == self.namespace)
94        self.bind.execute(delete)
95        self.hash = {}
96        self._is_new = True
97
98    def __getitem__(self, key):
99        return self.hash[key]
100
101    def __contains__(self, key):
102        return self.hash.has_key(key)
103
104    def __setitem__(self, key, value):
105        self.hash[key] = value
106
107    def __delitem__(self, key):
108        del self.hash[key]
109
110    def keys(self):
111        return self.hash.keys()
112
113
114class SqlaContainer(Container):
115    namespace_manager = SqlaNamespaceManager
116
117def make_cache_table(metadata, table_name='beaker_cache'):
118    """Return a ``Table`` object suitable for storing cached values for the
119    namespace manager.  Do not create the table."""
120    return sa.Table(table_name, metadata,
121                    sa.Column('namespace', sa.String(255), primary_key=True),
122                    sa.Column('accessed', sa.DateTime, nullable=False),
123                    sa.Column('created', sa.DateTime, nullable=False),
124                    sa.Column('data', sa.PickleType, nullable=False))
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。