update sqlalchemy storage for values et settings
[tiramisu.git] / tiramisu / storage / dictionary / value.py
1 # -*- coding: utf-8 -*-
2 "default plugin for value: set it in a simple dictionary"
3 # Copyright (C) 2013-2014 Team tiramisu (see AUTHORS for all contributors)
4 #
5 # This program is free software: you can redistribute it and/or modify it
6 # under the terms of the GNU Lesser General Public License as published by the
7 # Free Software Foundation, either version 3 of the License, or (at your
8 # option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
13 # details.
14 #
15 # You should have received a copy of the GNU Lesser General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 # ____________________________________________________________
18 from ..util import Cache
19 from ...setting import undefined
20 from ...i18n import _
21
22
23 class Values(Cache):
24     __slots__ = ('_values', '_informations', '__weakref__')
25
26     def __init__(self, storage):
27         """init plugin means create values storage
28         """
29         #(('path1',), (index1,), (value1,), ('owner1'))
30         self._values = (tuple(), tuple(), tuple(), tuple())
31         self._informations = {}
32         # should init cache too
33         super(Values, self).__init__(storage)
34
35     def getsession(self):
36         pass
37
38     def delsession(self, session):
39         pass
40
41     def _setvalue_info(self, nb, idx, value, values, index, vidx):
42         lst = list(self._values[nb])
43         if idx is None:
44             if index is None or nb == 0:
45                 lst.append(value)
46             else:
47                 lst.append((value,))
48         else:
49             if index is None or nb == 0:
50                 lst[idx] = value
51             else:
52                 if nb == 1:
53                     if index in lst[idx]:
54                         vidx = lst[idx].index(index)
55                     else:
56                         vidx = None
57                 if vidx is None:
58                     tval = list(lst[idx])
59                     tval.append(value)
60                     lst[idx] = tuple(tval)
61                 elif nb != 1:
62                     tval = list(lst[idx])
63                     tval[vidx] = value
64                     lst[idx] = tuple(tval)
65                 lst[idx] = tuple(lst[idx])
66         values.append(tuple(lst))
67         return vidx
68     # value
69     def setvalue(self, path, value, owner, index, session):
70         """set value for a path
71         a specified value must be associated to an owner
72         """
73         values = []
74         vidx = None
75
76         if path in self._values[0]:
77             idx = self._values[0].index(path)
78         else:
79             idx = None
80         vidx = self._setvalue_info(0, idx, path, values, index, vidx)
81         vidx = self._setvalue_info(1, idx, index, values, index, vidx)
82         if isinstance(value, list):
83             value = tuple(value)
84         vidx = self._setvalue_info(2, idx, value, values, index, vidx)
85         if isinstance(value, list):
86             value = tuple(value)
87         self._setvalue_info(3, idx, owner, values, index, vidx)
88         self._values = tuple(values)
89
90     def getvalue(self, path, session, index=None):
91         """get value for a path
92         return: only value, not the owner
93         """
94         return self._getvalue(path, 2, index)
95
96     def hasvalue(self, path, index=None):
97         """if path has a value
98         return: boolean
99         """
100         return path in self._values[0]
101
102     def resetvalue(self, path, session):
103         """remove value means delete value in storage
104         """
105         def _resetvalue(nb):
106             lst = list(self._values[nb])
107             lst.pop(idx)
108             values.append(tuple(lst))
109         values = []
110         if path in self._values[0]:
111             idx = self._values[0].index(path)
112             _resetvalue(0)
113             _resetvalue(1)
114             _resetvalue(2)
115             _resetvalue(3)
116             self._values = tuple(values)
117
118     def get_modified_values(self):
119         """return all values in a dictionary
120         example: {'path1': (owner, 'value1'), 'path2': (owner, 'value2')}
121         """
122         values = {}
123         for idx, path in enumerate(self._values[0]):
124             indexes = self._values[1][idx]
125             value = self._values[2][idx]
126             owner = self._values[3][idx]
127             if indexes is not None:
128                 val = {}
129                 own = {}
130                 for cpt, index in enumerate(indexes):
131                     val[str(index)] = value[cpt]
132                     own[str(index)] = owner[cpt]
133                 value = val
134                 owner = own
135             values[path] = (owner, value)
136         return values
137
138     # owner
139     def setowner(self, path, owner, session, index=None):
140         """change owner for a path
141         """
142         idx = self._values[0].index(path)
143         if index is None:
144             vidx = None
145         else:
146             vidx = self._values[1][idx].index(index)
147         values = []
148         self._setvalue_info(3, idx, owner, values, index, vidx)
149         lst = list(self._values)
150         lst[3] = tuple(values[0])
151         self._values = tuple(lst)
152
153     def get_max_length(self, path, session):
154         if path in self._values[0]:
155             idx = self._values[0].index(path)
156         else:
157             return 0
158         return max(self._values[1][idx]) + 1
159
160     def getowner(self, path, default, session, index=None, only_default=False):
161         """get owner for a path
162         return: owner object
163         """
164         if index is None:
165             if only_default:
166                 if path in self._values[0]:
167                     return undefined
168                 else:
169                     return default
170             val = self._getvalue(path, 3, index)
171             if val is undefined:
172                 return default
173             return val
174         else:
175             value = self._getvalue(path, 3, index)
176             if value is undefined:
177                 return default
178             else:
179                 return value
180
181     def _getvalue(self, path, nb, index):
182         """
183         _values == ((path1, path2), ((idx1_1, idx1_2), None), ((value1_1, value1_2), value2), ((owner1_1, owner1_2), owner2))
184         """
185         if path in self._values[0]:
186             idx = self._values[0].index(path)
187             if isinstance(self._values[1][idx], tuple):
188                 if index is None:
189                     raise ValueError('index is mandatory')
190             elif index is not None:
191                 raise ValueError('index is forbidden')
192
193             if self._values[1][idx] is None:
194                 if index is None:
195                     value = self._values[nb][idx]
196                 else:
197                     value = self._values[nb][idx][index]
198             else:
199                 if index is not None:
200                     if index in self._values[1][idx]:
201                         subidx = self._values[1][idx].index(index)
202                         value = self._values[nb][idx][subidx]
203                     else:
204                         value = undefined
205                 else:
206                     value = []
207                     for i in xrange(0, max(self._values[1][idx])):
208                         if i in self._values[1][idx]:
209                             value.append(self._values[nb][idx][self._values[1][idx].index(i)])
210                         else:
211                             value.append(undefined)
212         else:
213             value = undefined
214         if isinstance(value, tuple):
215             value = list(value)
216         return value
217
218     def set_information(self, key, value):
219         """updates the information's attribute
220         (which is a dictionary)
221
222         :param key: information's key (ex: "help", "doc"
223         :param value: information's value (ex: "the help string")
224         """
225         self._informations[key] = value
226
227     def get_information(self, key, default):
228         """retrieves one information's item
229
230         :param key: the item string (ex: "help")
231         """
232         value = self._informations.get(key, default)
233         if value is undefined:
234             raise ValueError(_("information's item"
235                                " not found: {0}").format(key))
236         return value
237
238     def exportation(self, session, fake=False):
239         return self._values
240
241     def importation(self, export):
242         self._values = export
243
244 def delete_session(session_id, session):
245     raise ValueError(_('a dictionary cannot be persistent'))