Salome HOME
Updated copyright comment
[modules/kernel.git] / src / SALOMESDS / SALOMESDS_Transaction.cxx
1 // Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony GEAY (EDF R&D)
20
21 #include "SALOMESDS_Transaction.hxx"
22 #include "SALOMESDS_Exception.hxx"
23 #include "SALOMESDS_PickelizedPyObjServer.hxx"
24 #include "SALOMESDS_PickelizedPyObjRdWrServer.hxx"
25 #include "SALOMESDS_PickelizedPyObjRdExtServer.hxx"
26 #include "SALOMESDS_TrustTransaction.hxx"
27
28 #include <sstream>
29
30 using namespace SALOMESDS;
31
32 void Transaction::FromByteSeqToVB(const SALOME::ByteVec& bsToBeConv, std::vector<unsigned char>& ret)
33 {
34   std::size_t sz(bsToBeConv.length());
35   ret.resize(sz);
36   unsigned char *buf(const_cast<unsigned char *>(&ret[0]));
37   for(std::size_t i=0;i<sz;i++)
38     buf[i]=bsToBeConv[(CORBA::ULong)i]; //!< TODO: size_t to CORBA::ULong
39 }
40
41 void Transaction::FromVBToByteSeq(const std::vector<unsigned char>& bsToBeConv, SALOME::ByteVec& ret)
42 {
43   std::size_t sz(bsToBeConv.size());
44   ret.length((CORBA::ULong)sz); //!< TODO: size_t to CORBA::ULong
45   for(std::size_t i=0;i<sz;i++)
46     ret[(CORBA::ULong)i]=bsToBeConv[i]; //!< TODO: size_t to CORBA::ULong
47 }
48
49 Transaction::~Transaction()
50 {
51 }
52
53 TransactionVarCreate::TransactionVarCreate(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& constValue):Transaction(dsct,varName)
54 {
55   FromByteSeqToVB(constValue,_data);
56 }
57
58 void TransactionVarCreate::prepareRollBackInCaseOfFailure()
59 {
60   checkNotAlreadyExisting();
61 }
62
63 void TransactionVarCreate::rollBack()
64 {
65   if(_dsct->existVar(_var_name.c_str()))
66     _dsct->deleteVar(_var_name.c_str());
67 }
68
69 /*!
70  * no implementation it is not a bug !
71  */
72 void TransactionVarCreate::notify()
73 {
74 }
75
76 void TransactionRdOnlyVarCreate::perform()
77 {
78   SALOME::ByteVec data2;
79   FromVBToByteSeq(_data,data2);
80   _dsct->createRdOnlyVarInternal(_var_name,data2);
81 }
82
83 void TransactionRdExtVarCreate::perform()
84 {
85   SALOME::ByteVec data2;
86   FromVBToByteSeq(_data,data2);
87   _dsct->createRdExtVarInternal(_var_name,data2);
88 }
89
90 TransactionRdExtVarFreeStyleCreate::TransactionRdExtVarFreeStyleCreate(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& constValue, const char *compareFuncContent):TransactionRdExtVarCreate(dsct,varName,constValue),_cmp_func_content(compareFuncContent),_cmp_func(nullptr)
91 {
92   constexpr char EXPECTED_COMPARE_FUNC_NAME[]="comptchev";
93   SALOME::AutoPyRef context(PyDict_New());
94   SALOME::AutoPyRef res(PyRun_String(compareFuncContent,Py_file_input,_dsct->getGlobals(),context));
95   if(res.isNull())
96     {
97       std::ostringstream oss; oss << "TransactionRdExtVarFreeStyleCreate ctor : Fail to parse and evaluate \"" << compareFuncContent << "\" as python function !";
98       throw Exception(oss.str());
99     }
100   PyObject *func(PyDict_GetItemString(context,EXPECTED_COMPARE_FUNC_NAME));//borrowed
101   if(!func)
102     {
103       std::ostringstream oss; oss << "TransactionRdExtVarFreeStyleCreate ctor : Parsing of func is OK but not func called \"" << EXPECTED_COMPARE_FUNC_NAME << "\" is the given parsed string !";
104       throw Exception(oss.str());
105     }
106   _cmp_func = func; Py_XINCREF(func);
107   if(PyDict_DelItemString(context,EXPECTED_COMPARE_FUNC_NAME)!=0)
108     {
109       std::ostringstream oss; oss << "TransactionRdExtVarFreeStyleCreate ctor : Internal error during suppression of \"" << EXPECTED_COMPARE_FUNC_NAME << "\" key that exepect to be present ! Smells bad !";
110       throw Exception(oss.str());
111     }
112 }
113
114 void TransactionRdExtVarFreeStyleCreate::prepareRollBackInCaseOfFailure()
115 {//nothing it is not a bug
116 }
117
118 void TransactionRdExtVarFreeStyleCreate::rollBack()
119 {// nothing to be done here. Fress style means I don t care. Do not remove var.
120   if(!_null_rollback)
121     TransactionRdExtVarCreate::rollBack();
122 }
123
124 void TransactionRdExtVarFreeStyleCreate::perform()
125 {
126   SALOME::ByteVec data2;
127   FromVBToByteSeq(_data,data2);
128   try
129     {
130       _dsct->createRdExtVarFreeStyleInternal(_var_name,data2,std::move(_cmp_func_content),std::move(_cmp_func));
131     }
132   catch(NotSameException& e)
133     {
134       _null_rollback = true;
135       throw e;
136     }
137 }
138
139 void TransactionRdExtInitVarCreate::perform()
140 {
141   SALOME::ByteVec data2;
142   FromVBToByteSeq(_data,data2);
143   _dsct->createRdExtInitVarInternal(_var_name,data2);
144 }
145
146 void TransactionRdWrVarCreate::perform()
147 {
148   SALOME::ByteVec data2;
149   FromVBToByteSeq(_data,data2);
150   _dsct->createRdWrVarInternal(_var_name,data2);
151 }
152
153 TransactionKillVar::TransactionKillVar(DataScopeServerTransaction *dsct, const std::string& varName):Transaction(dsct,varName)
154 {
155 }
156
157 /*!
158  * TODO
159  */
160 void TransactionKillVar::prepareRollBackInCaseOfFailure()
161 {
162   checkVarExisting();
163   //BasicDataServer *bds(_dsct->retrieveVarInternal2(_var_name);
164   //bds->clone();
165 }
166
167 void TransactionKillVar::perform()
168 {
169   _dsct->deleteVar(_var_name.c_str());
170 }
171
172 /*!
173  * TODO
174  */
175 void TransactionKillVar::rollBack()
176 {
177 }
178
179 /*!
180  * no implementation it is not a bug ! killVar is not an event.
181  */
182 void TransactionKillVar::notify()
183 {
184 }
185
186 TransactionDictModify::TransactionDictModify(DataScopeServerTransaction *dsct, const std::string& varName):Transaction(dsct,varName),_varc(0)
187 {
188   _varc=checkVarExistingAndDict();
189 }
190
191 void TransactionDictModify::prepareRollBackInCaseOfFailure()
192 {
193   _zeDataBefore.clear();
194   PyObject *zeDictPy(_varc->getPyObj());
195   Py_XINCREF(zeDictPy);
196   _zeDataBefore=_varc->pickelize(zeDictPy);
197 }
198
199 void TransactionDictModify::rollBack()
200 {
201   PyObject *obj(_varc->getPyObjFromPickled(_zeDataBefore));
202   _varc->setNewPyObj(obj);
203   _zeDataBefore.clear();
204 }
205
206 TransactionAddKeyValue::TransactionAddKeyValue(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value):TransactionDictModify(dsct,varName)
207 {
208   std::vector<unsigned char> key2,value2;
209   FromByteSeqToVB(key,key2);
210   FromByteSeqToVB(value,value2);
211   _key=PickelizedPyObjServer::GetPyObjFromPickled(key2,_dsct);
212   _value=PickelizedPyObjServer::GetPyObjFromPickled(value2,_dsct);
213 }
214
215 void TransactionAddKeyValue::prepareRollBackInCaseOfFailure()
216 {
217   TransactionDictModify::prepareRollBackInCaseOfFailure();
218   _dsct->pingKey(_key);// check that key is OK with all waiting keys
219 }
220
221 void TransactionAddKeyValue::notify()
222 {
223   _dsct->notifyKey(getVarName(),_key,_value);
224 }
225
226 TransactionAddKeyValue::~TransactionAddKeyValue()
227 {
228   Py_XDECREF(_key);
229   Py_XDECREF(_value);
230 }
231
232 TransactionAddKeyValueHard::TransactionAddKeyValueHard(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value):TransactionAddKeyValue(dsct,varName,key,value)
233 {
234 }
235
236 void TransactionAddKeyValueHard::perform()
237 {
238   _varc->addKeyValueHard(_key,_value);
239 }
240
241 TransactionAddKeyValueErrorIfAlreadyExisting::TransactionAddKeyValueErrorIfAlreadyExisting(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value):TransactionAddKeyValue(dsct,varName,key,value)
242 {
243   _varc->checkKeyNotAlreadyPresent(_key);
244 }
245
246 void TransactionAddKeyValueErrorIfAlreadyExisting::perform()
247 {
248   _varc->addKeyValueErrorIfAlreadyExisting(_key,_value);
249 }
250
251 TransactionRemoveKeyInVarErrorIfNotAlreadyExisting::TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key):TransactionDictModify(dsct,varName),_key(0)
252 {
253   std::vector<unsigned char> key2;
254   FromByteSeqToVB(key,key2);
255   _key=PickelizedPyObjServer::GetPyObjFromPickled(key2,_dsct);
256 }
257
258 void TransactionRemoveKeyInVarErrorIfNotAlreadyExisting::perform()
259 {
260   _varc->removeKeyInVarErrorIfNotAlreadyExisting(_key);
261 }
262
263 /*!
264  * no implementation it is not a bug !
265  */
266 void TransactionRemoveKeyInVarErrorIfNotAlreadyExisting::notify()
267 {
268 }
269
270 TransactionRemoveKeyInVarErrorIfNotAlreadyExisting::~TransactionRemoveKeyInVarErrorIfNotAlreadyExisting()
271 {
272   Py_XDECREF(_key);
273 }
274
275 TransactionMorphRdWrIntoRdOnly::TransactionMorphRdWrIntoRdOnly(DataScopeServerTransaction *dsct, const std::string& varName):Transaction(dsct,varName)
276 {
277 }
278
279 SALOME::PickelizedPyObjRdWrServer_ptr TransactionMorphRdWrIntoRdOnly::getVar()
280 {
281   SALOME::BasicDataServer_var obj(_dsct->retrieveVarInternal(_var_name.c_str()));
282   SALOME::PickelizedPyObjRdWrServer_ptr ret(SALOME::PickelizedPyObjRdWrServer::_narrow(obj));
283   if(CORBA::is_nil(ret))
284     {
285       std::ostringstream oss; oss << "TransactionMorphRdWrIntoRdOnly::getVar : var \"" << _var_name << "\" has not expected PickelizedPyObjRdWrServer type !";
286       throw Exception(oss.str());
287     }
288   return ret;
289 }
290
291 void TransactionMorphRdWrIntoRdOnly::prepareRollBackInCaseOfFailure()
292 {
293   BasicDataServer *var(_dsct->retrieveVarInternal2(_var_name));
294   if(!var)
295     throw Exception("TransactionMorphRdWrIntoRdOnly::prepareRollBackInCaseOfFailure : Returned var is NULL !");
296   PickelizedPyObjRdWrServer *varc(dynamic_cast<PickelizedPyObjRdWrServer *>(var));
297   if(!varc)
298     throw Exception("TransactionMorphRdWrIntoRdOnly::prepareRollBackInCaseOfFailure : Returned var has not expected type !");
299 }
300
301 void TransactionMorphRdWrIntoRdOnly::perform()
302 {
303   _dsct->moveStatusOfVarFromRdWrToRdOnly(_var_name);
304 }
305
306 void TransactionMorphRdWrIntoRdOnly::rollBack()
307 {
308   _dsct->moveStatusOfVarFromRdOnlyToRdWr(_var_name);
309 }
310
311 /*!
312  * no implementation it is not a bug !
313  */
314 void TransactionMorphRdWrIntoRdOnly::notify()
315 {
316 }
317
318 TransactionMultiKeyAddSession::TransactionMultiKeyAddSession(DataScopeServerTransaction *dsct, const std::string& varName):Transaction(dsct,varName)
319 {
320   _dsct->moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit(_var_name);
321 }
322
323 void TransactionMultiKeyAddSession::addKeyValueInVarErrorIfAlreadyExistingNow(const SALOME::ByteVec& key, const SALOME::ByteVec& value)
324 {
325   _dsct->checkVarExistingAndDict(_var_name);
326   TransactionAddKeyValueErrorIfAlreadyExisting ret(_dsct,_var_name,key,value);
327   {
328     ret.perform();
329     /*bool mustRollback(true);
330     TrustTransaction t;
331     t.setTransaction(&ret,&mustRollback);
332     t.operate();
333     mustRollback=false;//important let this line to notify t that everything was OK*/
334   }
335   ret.notify();
336 }
337
338 /*!
339  * no implementation it is not a bug !
340  */
341 void TransactionMultiKeyAddSession::prepareRollBackInCaseOfFailure()
342 {
343 }
344
345 void TransactionMultiKeyAddSession::perform()
346 {
347   _dsct->moveStatusOfVarFromRdExtOrRdExtInitToRdExt(_var_name);
348 }
349
350 /*!
351  * no implementation it is not a bug !
352  */
353 void TransactionMultiKeyAddSession::rollBack()
354 {
355 }
356
357 /*!
358  * no implementation it is not a bug !
359  */
360 void TransactionMultiKeyAddSession::notify()
361 {
362 }
363