update sqlalchemy storage for values et settings
[tiramisu.git] / tiramisu / storage / sqlalchemy / value.py
1 # -*- coding: utf-8 -*-
2 "plugin for value: set it in sqlalchemy"
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
19
20 from ..util import Cache
21 from .util import SqlAlchemyBase
22 import util
23 from ...setting import undefined
24 from sqlalchemy import Column, Integer, String, PickleType
25 from sqlalchemy import func
26 from tiramisu.setting import owners
27
28
29 #____________________________________________________________
30 #
31 # information
32 class _Vinformation(SqlAlchemyBase):
33     __tablename__ = 'vinformation'
34     id = Column(Integer, primary_key=True)
35     session_id = Column(String, index=True)
36     path = Column(String, index=True)
37     key = Column(String)
38     value = Column(PickleType)
39
40     def __init__(self, session_id, key, value):
41         self.session_id = session_id
42         self.key = key
43         self.value = value
44
45
46 class Value(SqlAlchemyBase):
47     __tablename__ = 'value'
48     id = Column(Integer, primary_key=True)
49     session_id = Column(String, index=True)
50     path = Column(String, index=True)
51     key = Column(String)
52     value = Column(PickleType)
53     owner = Column(String)
54     indx = Column(Integer, index=True)
55
56     def __init__(self, session_id, path, value, owner, index):
57         self.session_id = session_id
58         self.path = path
59         self.value = value
60         self.owner = owner
61         self.indx = index
62
63
64 class Values(Cache):
65
66     def getsession(self):
67         return util.Session()
68
69     # value
70     def setvalue(self, path, value, owner, index, session):
71         """set value for a path
72         a specified value must be associated to an owner
73         """
74         #if it's a multi
75         if isinstance(value, list):
76             value = list(value)
77         val = session.query(Value).filter_by(
78             path=path, indx=index, session_id=self._storage.session_id).first()
79         if val is None:
80             session.add(Value(self._storage.session_id, path, value,
81                                    owner, index))
82         else:
83             val.value = value
84             val.owner = owner
85         session.commit()
86
87     def getvalue(self, path, session, index=None):
88         """get value for a path
89         return: only value, not the owner
90         """
91         val = session.query(Value).filter_by(
92             path=path, indx=index, session_id=self._storage.session_id).first()
93         if not val:
94             raise KeyError('no value found')
95         return val.value
96
97     def hasvalue(self, path, session):
98         """if path has a value
99         return: boolean
100         """
101         return session.query(Value).filter_by(
102                   path=path, session_id=self._storage.session_id).first() is not None
103
104     def resetvalue(self, path, session):
105         """remove value means delete value in storage
106         """
107         vals = session.query(Value).filter_by(
108             path=path, session_id=self._storage.session_id).all()
109         if vals != []:
110             for val in vals:
111                 session.delete(val)
112             session.commit()
113
114     def get_modified_values(self):
115         """return all values in a dictionary
116         example: {'path1': (owner, 'value1'), 'path2': (owner, 'value2')}
117         """
118         session = self.getsession()
119         ret = {}
120         for val in session.query(Value).filter_by(
121                 session_id=self._storage.session_id).all():
122             value = val.value
123             if isinstance(val.value, list):
124                 value = tuple(val.value)
125             ret[val.path] = (val.owner, value)
126         del(session)
127         return ret
128
129     # owner
130     def setowner(self, path, owner, session, index=None):
131         """change owner for a path
132         """
133         val = session.query(Value).filter_by(
134             path=path, indx=index, session_id=self._storage.session_id).first()
135         if val is None:
136             raise KeyError('no value found')
137         else:
138             val.owner = owner
139         session.commit()
140
141     def get_max_length(self, path, session):
142         val = session.query(Value, func.max(Value.indx)).filter_by(
143                     path=path, session_id=self._storage.session_id).first()
144         if val[1] is None:
145             maxval = 0
146         else:
147             maxval = val[1] + 1
148         return maxval
149
150     def getowner(self, path, default, session, index=None, only_default=False):
151         #FIXME support de only_default
152         """get owner for a path
153         return: owner object
154         """
155         session.commit()
156         val = session.query(Value).filter_by(
157             path=path, session_id=self._storage.session_id,
158             indx=index).first()
159         if val is None:
160             return default
161         else:
162             owner = val.owner
163             # autocreate owners
164             try:
165                 return getattr(owners, owner)
166             except AttributeError:
167                 owners.addowner(owner)
168                 return getattr(owners, owner)
169
170     def set_information(self, key, value):
171         """updates the information's attribute
172         (which is a dictionary)
173
174         :param key: information's key (ex: "help", "doc"
175         :param value: information's value (ex: "the help string")
176         """
177         session = self.getsession()
178         val = session.query(_Vinformation).filter_by(
179             key=key, session_id=self._storage.session_id).first()
180         if val is None:
181             session.add(_Vinformation(self._storage.session_id, key,
182                                            value))
183         else:
184             val.value = value
185         session.commit()
186         del(session)
187
188     def get_information(self, key, default):
189         """retrieves one information's item
190
191         :param key: the item string (ex: "help")
192         """
193         session = self.getsession()
194         val = session.query(_Vinformation).filter_by(
195             key=key, session_id=self._storage.session_id).first()
196         del(session)
197         if not val:
198             if default is not undefined:
199                 return default
200             raise ValueError("not found")
201         return val.value
202
203     def exportation(self, session, fake=False):
204         if fake:
205             #(('path1',), (index1,), (value1,), ('owner1'))
206             paths = []
207             indexes = []
208             values = []
209             owners_ = []
210             slaves = {}
211             for val in session.query(Value).filter_by(
212                     session_id=self._storage.session_id).all():
213                 if val.indx is not None:
214                     slaves.setdefault(val.path, []).append((val.indx, val.value, getattr(owners, val.owner)))
215                 else:
216                     paths.append(val.path)
217                     indexes.append(val.indx)
218                     values.append(val.value)
219                     owners_.append(getattr(owners, val.owner))
220             for path, vals in slaves.items():
221                 paths.append(path)
222                 t_idxes = []
223                 t_vals = []
224                 t_owners = []
225                 for val in vals:
226                     t_idxes.append(val[0])
227                     t_vals.append(val[1])
228                     t_owners.append(val[2])
229                 indexes.append(tuple(t_idxes))
230                 values.append(t_vals)
231                 owners_.append(t_owners)
232             return (paths, indexes, values, owners_)
233         pass
234
235     def importation(self, value):
236         pass
237
238
239 def delete_session(session_id, session):
240     for val in session.query(_Vinformation).filter_by(session_id=session_id).all():
241         session.delete(val)
242     for val in session.query(Value).filter_by(session_id=session_id).all():
243         session.delete(val)