creaImageIO_lib
creaImageIOSynchron.cpp
Go to the documentation of this file.
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  //=====================================================================
77  {
78  delete mDB;
79  }
80 
81  //=====================================================================
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  //=====================================================================
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 
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 : -
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 
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 : -
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 
207  // clean DataBase if an operation has no child anymore
208  // @param refdb: the database segement to clean
209  // @result : -
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 
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
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 
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
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 
304  // get the files name to ignore for a add operation synchronization
305  // @param : the add key
306  //@result : list (path) of ignore files
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 
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
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 
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
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 
413  // get the files name to ignore for a add operation synchronization
414  // @param : the add key
415  //@result : list (path) of ignore files
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