]> Creatis software - creaImageIO.git/blob - src/creaImageIOSynchron.cpp
9a6af0cf3451af06ee958764a4d2dd8d9d18ce73
[creaImageIO.git] / src / creaImageIOSynchron.cpp
1 /*
2 # ---------------------------------------------------------------------
3 #
4 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image 
5 #                        pour la Santé)
6 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
9 #
10 #  This software is governed by the CeCILL-B license under French law and 
11 #  abiding by the rules of distribution of free software. You can  use, 
12 #  modify and/ or redistribute the software under the terms of the CeCILL-B 
13 #  license as circulated by CEA, CNRS and INRIA at the following URL 
14 #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
15 #  or in the file LICENSE.txt.
16 #
17 #  As a counterpart to the access to the source code and  rights to copy,
18 #  modify and redistribute granted by the license, users are provided only
19 #  with a limited warranty  and the software's author,  the holder of the
20 #  economic rights,  and the successive licensors  have only  limited
21 #  liability. 
22 #
23 #  The fact that you are presently reading this means that you have had
24 #  knowledge of the CeCILL-B license and that you accept its terms.
25 # ------------------------------------------------------------------------
26 */
27
28 #include <creaImageIOSynchron.h>
29 #include <creaImageIOSystem.h>
30 #include <boost/filesystem.hpp>
31 #include <boost/algorithm/string.hpp>
32
33
34 //namespace fs = boost::filesystem;
35
36 //=====================================================================
37  
38
39 namespace creaImageIO
40 {
41
42     //=====================================================================
43     #define QUERYSYNCDB(QUER,RES)                                       \
44     try                                                                 \
45     {                                                                   \
46         RES = mDB->execQuery(QUER.c_str());                             \
47     }                                                                   \
48     catch (CppSQLite3Exception& e)                                      \
49     {                                                                   \
50       GimmickError("SQLite query '"<<QUER<<"' Error : "                 \
51                    << e.errorCode() << ":"                              \
52                    << e.errorMessage() );                               \
53     }                                                                                                                                      
54    //=====================================================================
55     #define UPDATESYNCDB(UP)                                            \
56     try                                                                 \
57     {                                                                   \
58       mDB->execDML(UP.c_str());                                         \
59     }                                                                   \
60     catch (CppSQLite3Exception& e)                                      \
61     {                                                                   \
62       GimmickError("SQLite update '"<<UP<<"' Error : "                  \
63                    << e.errorCode() << ":"                              \
64                    << e.errorMessage() );                               \
65     }                           
66    //=====================================================================
67
68     Synchronizer::Synchronizer(const std::string& path)
69     {
70                 pathDB = path + "maintenance_database.db3";
71                 mDB = new CppSQLite3DB;
72                 Initialize();
73     }
74
75    //=====================================================================
76     Synchronizer::~Synchronizer()
77     {
78        delete mDB;
79     }
80
81         //=====================================================================
82         void Synchronizer::Initialize()
83         {    
84                 if (!boost::filesystem::exists(pathDB)) 
85                 {
86                         CreateDB();
87                 }
88     
89                 // OPENING
90                 else
91                 {
92                 try
93                 {
94                 mDB->open(pathDB.c_str());
95                 }
96                 catch (CppSQLite3Exception& e)
97                 {
98                 GimmickError("Opening '"<<pathDB<<"' : "
99                      << e.errorCode() << ":" 
100                      << e.errorMessage());
101                 }
102                 }
103                 // get the ADD operations List 
104                 //UpdateAddList(pathDB);
105         }
106
107    //=====================================================================
108     void Synchronizer::CreateDB()
109     {
110                 mDB->open(pathDB.c_str());
111         // CREATING TABLES
112         std::string command;
113         command = "CREATE TABLE ";
114         command += "ADD_OPS";
115         command += "\n(\nADD_KEY INTEGER PRIMARY KEY";
116         command += ",\nPATH text";
117         command += ",\nRECURSIVE boolean";
118         command += ",\nFILES_ADDED int";
119         command += ",\nREFERENCEDDB text";
120         command += "\n)";
121         UPDATESYNCDB(command);
122
123         command = "CREATE TABLE ";
124         command += "IGNORED_FILES";
125         command += "\n(\nID INTEGER PRIMARY KEY";
126         command += ",\nADD_KEY integer";
127         command += ",\nPATH text";
128         command += ",\nREMOVE boolean";
129         command += ",\nTIME datetext";
130         command += "\n)";
131         UPDATESYNCDB(command);
132     }
133
134         //=====================================================================
135         void Synchronizer::CleanName(std::string& str) const
136         {
137                 size_t pos;
138                 do
139                 {
140                         pos = str.find('\\');
141                         if (pos!=-1)  
142                         {
143                                 str.replace(pos, 1, "/");
144                         }
145                 }
146                 while (pos!=-1);
147         }
148
149         //=====================================================================
150     void Synchronizer::GetFileList(std::vector<AddList> & list, const std::string& refdb)
151     {
152        CleanList(refdb);
153        list=mAddList;
154     }
155
156         //=====================================================================
157    void Synchronizer::GetIgnoredFiles(const std::string& key, std::vector<std::string> &ignoreList)
158    {
159         ignoreList=GetIgnoreList(key);
160    }
161
162 //=====================================================================
163     void Synchronizer::UpdateAddList(const std::string& refdb)
164     {
165         std::string query = "SELECT * FROM ADD_OPS WHERE REFERENCEDDB = '"+refdb+"';";
166         CppSQLite3Query res;
167         QUERYSYNCDB(query, res);
168         while (!res.eof())
169         {
170             AddList temp = AddList(res);
171             mAddList.push_back(temp);
172             res.nextRow();
173         }
174     }
175
176     /////////////////////////////////////////////////////////////////////////////////////////////////
177     // remove an entry of the DB
178     //@param i_table : table where to do the remove
179     // @param i_key : the add_key reference (one entry to remove for ADD_OP table, many for IGNORED_FILES table
180     //@result : -
181     /////////////////////////////////////////////////////////////////////////////////////////////////
182     void Synchronizer::RemoveEntry(const std::string i_table, const std::string i_key)
183     {
184         std::string query = "DELETE  FROM " + i_table + " WHERE ADD_KEY = '" + i_key +"'";
185         UPDATESYNCDB(query);
186     }
187
188         /////////////////////////////////////////////////////////////////////////////////////////////////
189     // remove several entries of the DB
190     // @param i_table : table where to do the remove
191     // @param i_attribute: attribute to match
192     // @param i_operand : operand to use
193     // @param i_val : the reference
194     //@result : -
195     /////////////////////////////////////////////////////////////////////////////////////////////////
196     void Synchronizer::RemoveEntries(const std::string i_table, 
197                 const std::string i_attribute, 
198                 const std::string i_operand, 
199                 const std::string i_val)
200     {
201         std::stringstream query;
202         query<<"DELETE  FROM "<<i_table<<" WHERE "<<i_attribute<<" "<<i_operand<<" '"<<i_val<<"'";
203         UPDATESYNCDB(query.str());
204         }
205
206     /////////////////////////////////////////////////////////////////////////////////////////////////
207     // clean DataBase if an operation has no child anymore
208         // @param refdb: the database segement to clean
209     // @result : -
210     /////////////////////////////////////////////////////////////////////////////////////////////////
211     void Synchronizer::CleanList(const std::string& refdb)
212     {
213         mAddList.clear();
214         UpdateAddList(refdb);
215         std::vector<AddList>::iterator it_add = mAddList.begin();
216         for(;it_add <mAddList.end(); ++it_add)
217         {
218                 if(it_add->nbFiles == "0")
219                 {
220                         RemoveEntry("ADD_OPS", it_add->key);
221                         RemoveEntry("IGNORED_FILES", it_add->key);
222
223                 }
224         }
225                 mAddList.clear();
226                 UpdateAddList(refdb);
227     }
228
229     /////////////////////////////////////////////////////////////////////////////////////////////////
230     // Inserts a new add operation in the database
231     // @param path: the path of the directory that was added
232     // @param recursive: shows if the action was called recursively or not
233     // @param nChildren: the number of files affected by the operation
234     // @param refdb: the referenced database
235     // @result : The operation has been added
236     /////////////////////////////////////////////////////////////////////////////////////////////////
237         void Synchronizer::InsertAddOp(const std::string& path, const std::string& recursive, const std::string& nChildren, const std::string& refdb)
238         {
239                 std::string insert;
240                 std::string pat=path.c_str();
241                 CleanName(pat);
242                 insert="INSERT INTO ADD_OPS (PATH,RECURSIVE,FILES_ADDED,REFERENCEDDB) VALUES('";
243                 insert+=convert(pat)+"','";
244                 insert+=recursive+"',";
245                 insert+=nChildren+",'";
246                 insert+=refdb+"');";
247                 UPDATESYNCDB(insert);
248         }
249
250         /////////////////////////////////////////////////////////////////////////////////////////////////
251     // Inserts a new ignored file in the database
252         // @param add_key: the key of the add_op to which it corresponds
253     // @param path: the path of the directory that was added
254         // @param remove: shows if the file was removed or not
255         // @param time: the time in which the file was removed
256     // @result : The file has been inserted
257     /////////////////////////////////////////////////////////////////////////////////////////////////
258
259         void Synchronizer::InsertIgnoreFile(const std::string& addKey, const std::string& path, const std::string& remove, const std::string& time, const std::string& refdb )
260         {
261                 std::string pat=path.c_str();
262                 CleanName(pat);
263                 std::string id=GetAttribute("ID","IGNORED_FILES","PATH",pat,refdb);
264                 if(id.compare("")==0)
265                 {
266                         std::string insert;
267                         insert="INSERT INTO IGNORED_FILES (ADD_KEY,PATH,REMOVE,TIME) VALUES('";
268                         insert+=addKey+"','";
269                         insert+=convert(pat)+"','";
270                         insert+=remove+"',";
271                         insert+=time+");";
272                         UPDATESYNCDB(insert);
273                 }
274                 else
275                 {
276                         //Gets the add key
277                         std::string ak=GetAttribute("ADD_KEY","IGNORED_FILES","ID",id,refdb);
278                         //gets the parent database to check if the file has been added to the current database
279                         std::string parentDB=GetAttribute("*","ADD_OPS","ADD_KEY",ak,refdb);
280                         //If there is no such entry, add it
281                         if(parentDB.compare("")==0)
282                         {
283                                 std::string insert;
284                                 insert="INSERT INTO IGNORED_FILES (ADD_KEY,PATH,REMOVE,TIME) VALUES('";
285                                 insert+=addKey+"','";
286                                 insert+=convert(pat)+"','";
287                                 insert+=remove+"',";
288                                 insert+=time+");";
289                                 UPDATESYNCDB(insert);
290                         }
291                         else
292                         {
293                                 //Sets the new add key attribute for the file
294                                 SetAttribute("ADD_KEY","IGNORED_FILES",addKey,"ID", id,refdb);
295                                 //Sets the new remove attribute for the file
296                                 SetAttribute("REMOVE","IGNORED_FILES",remove,"ID", id,refdb);
297                                 //Sets the new time attribute for the file
298                                 SetAttribute("TIME","IGNORED_FILES",time,"ID", id,refdb);
299                         }
300                 }
301         }
302
303     /////////////////////////////////////////////////////////////////////////////////////////////////
304     // get the files name to ignore for a add operation synchronization
305     // @param : the add key
306     //@result : list (path) of ignore files
307     /////////////////////////////////////////////////////////////////////////////////////////////////
308     std::vector<std::string> Synchronizer::GetIgnoreList(const std::string &i_key)
309     {
310         mIgnoreList.clear();
311         std::vector<std::string> i_names;
312         std::string query = "SELECT * FROM IGNORED_FILES WHERE ADD_KEY = ";
313         query+=i_key;
314         CppSQLite3Query res;
315         QUERYSYNCDB(query, res);
316         while (!res.eof())
317         {
318                 RemoveList temp = RemoveList(res);
319                 if(temp.remove.compare("0")==0)
320                 {
321                    mIgnoreList.push_back(temp);
322                 }
323                 res.nextRow();
324         }
325         std::vector<RemoveList>::iterator it;
326
327         for(it = mIgnoreList.begin();it != mIgnoreList.end(); ++it)
328         {
329             i_names.push_back((*it).path);
330         }
331         return i_names;
332     }
333
334     /////////////////////////////////////////////////////////////////////////////////////////////////
335     // Gets the required attribute in the required table
336     // @param attribute: the attribute to look for
337     // @param table: the table to look in
338     // @param searchParam: the search parameter
339     // @param searchValue: the search value
340     // @result : required attribute
341     /////////////////////////////////////////////////////////////////////////////////////////////////
342     std::string Synchronizer::GetAttribute(const std::string& attribute, 
343                                         const std::string& table, 
344                                         const std::string& searchParam,
345                                         const std::string& searchValue, 
346                                         const std::string& refdb)
347     {
348         std::stringstream query;
349         std::string result;
350         std::string sVal=convert(searchValue.c_str());
351         CleanName(sVal);
352         query<<"SELECT "<<attribute<<" FROM "<<table<<" WHERE "<<searchParam<<" = '"<<sVal;
353         if(table.compare("ADD_OPS")==0)
354         {
355                 query<<"' AND REFERENCEDDB = '"<<refdb<<"';";
356         }
357         else
358         {
359                 query<<"';";
360         }
361         CppSQLite3Query res;
362         QUERYSYNCDB(query.str(), res);
363         while (!res.eof())
364         {
365                 result=res.getStringField(0);
366                 res.nextRow();
367         }
368         return result;
369     }
370
371     /////////////////////////////////////////////////////////////////////////////////////////////////
372     // Sets the attribute value in the required table and column
373     // @param attribute: the attribute to look for
374     // @param table: the table to look in
375     // @param value: the value to set
376     // @param searchParam: the search parameter
377     // @param searchValue: the search value
378     // @result : attribute value changed
379     /////////////////////////////////////////////////////////////////////////////////////////////////
380     void Synchronizer::SetAttribute(const std::string& attribute, 
381                                 const std::string& table, 
382                                 const std::string& value,
383                                 const std::string& searchParam,
384                                 const std::string& searchValue,
385                                 const std::string& refdb)
386     {
387         std::string val=value.c_str();
388         std::string sVal=convert(searchValue.c_str());
389         CleanName(val);
390         CleanName(sVal);
391         std::string sql = "UPDATE ";
392         sql+=table;
393         sql+=" SET ";
394         sql += attribute;
395         sql += " = '";
396         sql += val;
397         sql += "' WHERE ";
398         sql += searchParam;
399         sql += " = '";
400         sql += sVal;
401         if(table.compare("ADD_OPS")==0)
402         {
403                 sql += "' AND REFERENCEDDB = '";
404                 sql += refdb;
405         }
406         sql += "';";
407         UPDATESYNCDB(sql);
408     }
409
410
411
412 /////////////////////////////////////////////////////////////////////////////////////////////////
413     // get the files name to ignore for a add operation synchronization
414     // @param : the add key
415     //@result : list (path) of ignore files
416     /////////////////////////////////////////////////////////////////////////////////////////////////
417         void Synchronizer::GetList(const std::string i_db)
418     {
419                 mList.clear();
420         std::vector<std::string> i_names;
421                 std::vector<std::string> keys;
422                 CppSQLite3Query res;
423                 std::string query ="SELECT ADD_KEY, REFERENCEDDB FROM  ADD_OPS";
424                 QUERYSYNCDB(query, res);
425                 keys.clear();
426                 while (!res.eof())
427         {
428                         std::string key(res.getStringField(0));
429                         std::string db(res.getStringField(1));
430                         if (db == i_db)
431                         {
432                                 keys.push_back(key);
433                         }
434                         res.nextRow();
435                 }
436                 query = "SELECT PATH, REMOVE FROM IGNORED_FILES WHERE";
437                 if(keys.size() > 0)
438                 {
439                         for (int i=0; i < keys.size(); i++)
440                         {
441                                 query += " ADD_KEY = " + keys[i];
442                                 query += " AND";
443                         }
444                         query = query.substr(0,query.size() - 4);
445                 }
446                 else 
447                 {
448                         query += " ADD_KEY = -1";
449                 }
450         QUERYSYNCDB(query, res);
451                 while (!res.eof())
452         {
453                 std::string file(res.getStringField(0));
454                 std::string ignore(res.getStringField(1));
455                 mList[file] = ignore == "0"? true : false;
456                 res.nextRow();
457         }
458     }
459
460         bool Synchronizer::isIndexed(const std::string filename)
461         {
462                 bool valid = true;
463                 std::string name(filename);
464                 boost::algorithm::replace_all( name,"\\" , "/");
465                 std::map <std::string, bool>::iterator it_list = mList.begin();
466                 for(;it_list != mList.end(); it_list++)
467                 {
468                         if(it_list->first == name)
469                         {
470                                 valid = false;
471                                 break;
472                         }
473                 }
474                 return valid;
475         }
476           const std::string Synchronizer::convert(const std::string &i_word)
477           {
478                   std::string temp = i_word;
479                   boost::algorithm::replace_all(temp,"'","''");
480
481           return temp.c_str();
482   }
483 }
484
485