update sqlalchemy storage for values et settings
[tiramisu.git] / tiramisu / storage / __init__.py
1 # Copyright (C) 2013-2014 Team tiramisu (see AUTHORS for all contributors)
2 #
3 # This program is free software: you can redistribute it and/or modify it
4 # under the terms of the GNU Lesser General Public License as published by the
5 # Free Software Foundation, either version 3 of the License, or (at your
6 # option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful, but WITHOUT
9 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
11 # details.
12 #
13 # You should have received a copy of the GNU Lesser General Public License
14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
15 # ____________________________________________________________
16
17 """Config's informations are, by default, volatiles. This means, all values and
18 settings changes will be lost.
19
20 The storage is the system Tiramisu uses to communicate with various DB.
21 You can specified a persistent storage.
22
23 Storage is basic components used to set Config informations in DB.
24 The primary "entry point" class is the StorageType and it's public
25 configurator ``set_storage()``.
26 """
27
28
29 from time import time
30 from random import randint
31 import os
32 from ..error import ConfigError
33 from ..i18n import _
34
35
36 MODULE_PATH = os.path.split(os.path.split(os.path.split(__file__)[0])[0])[1]
37
38
39 class StorageType(object):
40     """Object to store storage's type. If a Config is already set,
41     default storage is store as selected storage. You cannot change it
42     after.
43     """
44     default_storage = os.environ.get('TIRAMISU_STORAGE', 'dictionary')
45     storage_type = None
46     mod = None
47
48     def set(self, name):  # pragma: optional cover
49         if self.storage_type is not None:
50             if self.storage_type == name:
51                 return
52             raise ConfigError(_('storage_type is already set, cannot rebind it'))
53         self.storage_type = name
54
55     def get(self):
56         if self.storage_type is None:
57             self.storage_type = self.default_storage
58         if self.mod is None:
59             modulepath = '{0}.storage.{1}'.format(MODULE_PATH, self.storage_type)
60             try:
61                 mod = __import__(modulepath)
62             except ImportError:
63                 raise SystemError(_('cannot import the storage {0}').format(
64                     self.default_storage))
65             for token in modulepath.split(".")[1:]:
66                 mod = getattr(mod, token)
67             self.mod = mod
68         return self.mod
69
70
71 storage_type = StorageType()
72 storage_option_type = StorageType()
73 storage_validation = StorageType()
74 storage_validation.set('dictionary')
75
76
77 def set_storage(type_, name, **kwargs):  # pragma: optional cover
78     """Change storage's configuration
79
80     :params name: is the storage name. If storage is already set, cannot
81         reset storage name
82
83     Other attributes are differents according to the selected storage's name
84     """
85     if type_ == 'option':
86         storage_option_type.set(name)
87         setting = storage_option_type.get().setting
88     else:
89         storage_type.set(name)
90         setting = storage_type.get().setting
91     for option, value in kwargs.items():
92         try:
93             getattr(setting, option)
94             setattr(setting, option, value)
95         except AttributeError:
96             raise ValueError(_('option {0} not already exists in storage {1}'
97                                '').format(option, name))
98
99
100 def _impl_getstate_setting():
101     setting = storage_type.get().setting
102     state = {'name': storage_type.storage_type}
103     for var in dir(setting):
104         if not var.startswith('_'):
105             state[var] = getattr(setting, var)
106     return state
107
108
109 def get_storage(type_, session_id, persistent, test):  # pragma: optional cover
110     """all used when __setstate__ a Config
111     """
112     #FIXME ca sert ???
113     if type_ == 'option':
114         return storage_option_type.get().Storage(session_id, persistent, test)
115     elif type_ == 'config':
116         return storage_type.get().Storage(session_id, persistent, test)
117     else:
118         return storage_validation.get().Storage(session_id, persistent, test)
119
120
121 def get_storages(context, session_id, persistent):
122     def gen_id(config):
123         return str(id(config)) + str(time()) + str(randint(0, 500))
124
125     if session_id is None:
126         session_id = gen_id(context)
127     imp = storage_type.get()
128     storage = imp.Storage(session_id, persistent)
129     settings = imp.Settings(session_id, storage)
130     values = imp.Values(storage)
131     return settings, values
132
133
134 def get_storages_option(type_):
135     imp = storage_option_type.get()
136     if type_ == 'base':
137         return imp.StorageBase
138     else:
139         return imp.StorageOptionDescription
140
141
142 def get_storages_validation():
143     imp = storage_validation.get()
144     storage = imp.Storage('__validator_storage', persistent=False, test=True)
145     return imp.Values(storage)
146
147
148 def list_sessions(type_):  # pragma: optional cover
149     """List all available session (persistent or not persistent)
150     """
151     if type_ == 'option':
152         return storage_option_type.get().list_sessions()
153     else:
154         return storage_type.get().list_sessions()
155
156
157 def delete_session(type_, session_id):  # pragma: optional cover
158     """Delete a selected session, be careful, you can deleted a session
159     use by an other instance
160     :params session_id: id of session to delete
161     """
162     if type_ == 'option':
163         storage_option_type.get().delete_session(session_id)
164     else:
165         storage_module = storage_type.get()
166         session = storage_module.storage.getsession()
167         storage_module.value.delete_session(session_id, session)
168         storage_module.storage.delete_session(session_id, session)
169         session.commit()
170         del(session)
171
172
173 __all__ = (set_storage, list_sessions, delete_session)