]> Creatis software - creaImageIO.git/blob - src2/creaImageIOSynchron.cpp
06785fe8e94bc32d55335409f95fea662b040920
[creaImageIO.git] / src2 / creaImageIOSynchron.cpp
1 #include <creaImageIOSynchron.h>
2 #include <creaImageIOSystem.h>
3 #include <boost/filesystem.hpp>
4 #include <boost/algorithm/string.hpp>
5 //namespace fs = boost::filesystem;
6
7
8 //=====================================================================
9  
10
11 namespace creaImageIO
12 {
13
14         //=====================================================================
15         #define QUERYSYNCDB(QUER,RES)                                   \
16     try                                                                 \
17       {                                                                 \
18         RES = mDB->execQuery(QUER.c_str());                             \
19       }                                                                 \
20     catch (CppSQLite3Exception& e)                                      \
21     {                                                                   \
22       GimmickError("SQLite query '"<<QUER<<"' Error : "                 \
23                    << e.errorCode() << ":"                              \
24                    << e.errorMessage() );                               \
25     }                                                                                                                                      
26         //=====================================================================
27         #define UPDATESYNCDB(UP)                                        \
28   try                                                                   \
29     {                                                                   \
30       mDB->execDML(UP.c_str());                                         \
31     }                                                                   \
32   catch (CppSQLite3Exception& e)                                        \
33     {                                                                   \
34       GimmickError("SQLite update '"<<UP<<"' Error : "                  \
35                    << e.errorCode() << ":"                              \
36                    << e.errorMessage() );                               \
37     }                           
38         //=====================================================================
39
40         Synchronizer::Synchronizer(const std::string& path)
41     {
42                 pathDB = path + "maintenance_database.db3";
43                 mDB = new CppSQLite3DB;
44                 Initialize();
45     }
46
47         //=====================================================================
48         Synchronizer::~Synchronizer()
49     {
50        
51     }
52
53         //=====================================================================
54         void Synchronizer::Initialize()
55         {    
56                 if (!boost::filesystem::exists(pathDB)) 
57                 {
58                         CreateDB();
59                 }
60     
61                 // OPENING
62                 else
63                 {
64                 try
65                 {
66                 mDB->open(pathDB.c_str());
67                 }
68                 catch (CppSQLite3Exception& e)
69                 {
70                 GimmickError("Opening '"<<pathDB<<"' : "
71                      << e.errorCode() << ":" 
72                      << e.errorMessage());
73                 }
74                 }
75                 // get the ADD operations List 
76                 //UpdateAddList(pathDB);
77         }
78
79         //=====================================================================
80     void Synchronizer::CreateDB()
81     {
82                 mDB->open(pathDB.c_str());
83         // CREATING TABLES
84         std::string command;
85             command = "CREATE TABLE ";
86             command += "ADD_OPS";
87             command += "\n(\nADD_KEY INTEGER PRIMARY KEY";
88             command += ",\nPATH text";
89                 command += ",\nRECURSIVE boolean";
90                 command += ",\nFILES_ADDED int";
91                 command += ",\nREFERENCEDDB text";
92             command += "\n)";
93                 UPDATESYNCDB(command);
94
95                 command = "CREATE TABLE ";
96             command += "IGNORED_FILES";
97             command += "\n(\nID INTEGER PRIMARY KEY";
98                 command += ",\nADD_KEY integer";
99             command += ",\nPATH text";
100                 command += ",\nREMOVE boolean";
101                 command += ",\nTIME datetext";
102             command += "\n)";
103                 UPDATESYNCDB(command);
104     }
105
106         //=====================================================================
107         void Synchronizer::CleanName(std::string& str) const
108         {
109                 size_t pos;
110                 do
111                 {
112                         pos = str.find('\\');
113                         if (pos!=-1)  
114                         {
115                                 str.replace(pos, 1, "/");
116                         }
117                 }
118                 while (pos!=-1);
119         }
120
121         //=====================================================================
122         void Synchronizer::GetFileList(std::vector<AddList> & list, const std::string& refdb)
123     {
124        CleanList(refdb);
125            list=mAddList;
126     }
127
128         //=====================================================================
129         void Synchronizer::GetIgnoredFiles(const std::string& key, std::vector<std::string> &ignoreList)
130         {
131         ignoreList=GetIgnoreList(key);
132         }
133
134         //=====================================================================
135         void Synchronizer::UpdateAddList(const std::string& refdb)
136     {
137         std::string query = "SELECT * FROM ADD_OPS WHERE REFERENCEDDB = '"+refdb+"';";
138         CppSQLite3Query res;
139         QUERYSYNCDB(query, res);
140                 while (!res.eof())
141         {
142                         AddList temp = AddList(res);
143             mAddList.push_back(temp);
144                         res.nextRow();
145         }
146         }
147
148     /////////////////////////////////////////////////////////////////////////////////////////////////
149     // remove an entry of the DB
150     //@param i_table : table where to do the remove
151     // @param i_key : the add_key reference (one entry to remove for ADD_OP table, many for IGNORED_FILES table
152     //@result : -
153     /////////////////////////////////////////////////////////////////////////////////////////////////
154     void Synchronizer::RemoveEntry(const std::string i_table, const std::string i_key)
155     {
156         std::string query = "DELETE  FROM " + i_table + " WHERE ADD_KEY = '" + i_key +"'";
157         UPDATESYNCDB(query);
158         }
159
160         /////////////////////////////////////////////////////////////////////////////////////////////////
161     // remove several entries of the DB
162     // @param i_table : table where to do the remove
163         // @param i_attribute: attribute to match
164         // @param i_operand : operand to use
165     // @param i_val : the reference
166     //@result : -
167     /////////////////////////////////////////////////////////////////////////////////////////////////
168     void Synchronizer::RemoveEntries(const std::string i_table, 
169                 const std::string i_attribute, 
170                 const std::string i_operand, 
171                 const std::string i_val)
172     {
173         std::stringstream query;
174                 query<<"DELETE  FROM "<<i_table<<" WHERE "<<i_attribute<<" "<<i_operand<<" '"<<i_val<<"'";
175         UPDATESYNCDB(query.str());
176         }
177
178     /////////////////////////////////////////////////////////////////////////////////////////////////
179     // clean DataBase if an operation has no child anymore
180         // @param refdb: the database segement to clean
181     // @result : -
182     /////////////////////////////////////////////////////////////////////////////////////////////////
183     void Synchronizer::CleanList(const std::string& refdb)
184     {
185                 mAddList.clear();
186                 UpdateAddList(refdb);
187         std::vector<AddList>::iterator it_add = mAddList.begin();
188         for(;it_add <mAddList.end(); ++it_add)
189         {
190                 if(it_add->nbFiles == "0")
191                 {
192                                         RemoveEntry("ADD_OPS", it_add->key);
193                                         RemoveEntry("IGNORED_FILES", it_add->key);
194                                                 
195                 }
196         }
197                 mAddList.clear();
198                 UpdateAddList(refdb);
199     }
200
201         /////////////////////////////////////////////////////////////////////////////////////////////////
202     // Inserts a new add operation in the database
203     // @param path: the path of the directory that was added
204         // @param recursive: shows if the action was called recursively or not
205         // @param nChildren: the number of files affected by the operation
206         // @param refdb: the referenced database
207     // @result : The operation has been added
208     /////////////////////////////////////////////////////////////////////////////////////////////////
209         void Synchronizer::InsertAddOp(const std::string& path, const std::string& recursive,   const std::string& nChildren, const std::string& refdb)
210         {
211                 std::string insert;
212                 std::string pat=path.c_str();
213                 CleanName(pat);
214                 insert="INSERT INTO ADD_OPS (PATH,RECURSIVE,FILES_ADDED,REFERENCEDDB) VALUES('";
215                 insert+=pat+"','";
216                 insert+=recursive+"',";
217         insert+=nChildren+",'";
218                 insert+=refdb+"');";
219                 UPDATESYNCDB(insert);
220         }
221
222         /////////////////////////////////////////////////////////////////////////////////////////////////
223     // Inserts a new ignored file in the database
224         // @param add_key: the key of the add_op to which it corresponds
225     // @param path: the path of the directory that was added
226         // @param remove: shows if the file was removed or not
227         // @param time: the time in which the file was removed
228     // @result : The file has been inserted
229     /////////////////////////////////////////////////////////////////////////////////////////////////
230
231         void Synchronizer::InsertIgnoreFile(const std::string& addKey, const std::string& path, const std::string& remove, const std::string& time, const std::string& refdb )
232         {
233                 std::string pat=path.c_str();
234                 CleanName(pat);
235                 std::string id=GetAttribute("ID","IGNORED_FILES","PATH",pat,refdb);
236                 if(id.compare("")==0)
237                 {
238                         std::string insert;
239                         insert="INSERT INTO IGNORED_FILES (ADD_KEY,PATH,REMOVE,TIME) VALUES('";
240                         insert+=addKey+"','";
241                         insert+=pat+"','";
242                         insert+=remove+"',";
243                 insert+=time+");";
244                         UPDATESYNCDB(insert);
245                 }
246                 else            
247                 {
248                         //Gets the add key
249                         std::string ak=GetAttribute("ADD_KEY","IGNORED_FILES","ID",id,refdb);
250                         //gets the parent database to check if the file has been added to the current database
251                         std::string parentDB=GetAttribute("*","ADD_OPS","ADD_KEY",ak,refdb);
252                         //If there is no such entry, add it
253                         if(parentDB.compare("")==0)
254                         {
255                                 std::string insert;
256                                 insert="INSERT INTO IGNORED_FILES (ADD_KEY,PATH,REMOVE,TIME) VALUES('";
257                                 insert+=addKey+"','";
258                                 insert+=pat+"','";
259                                 insert+=remove+"',";
260                         insert+=time+");";
261                                 UPDATESYNCDB(insert);
262                         }
263                         else
264                         {
265                                 //Sets the new add key attribute for the file
266                                 SetAttribute("ADD_KEY","IGNORED_FILES",addKey,"ID", id,refdb);
267                                 //Sets the new remove attribute for the file
268                                 SetAttribute("REMOVE","IGNORED_FILES",remove,"ID", id,refdb);
269                                 //Sets the new time attribute for the file
270                                 SetAttribute("TIME","IGNORED_FILES",time,"ID", id,refdb);
271                         }
272                 }
273         }
274
275     /////////////////////////////////////////////////////////////////////////////////////////////////
276     // get the files name to ignore for a add operation synchronization
277     // @param : the add key
278     //@result : list (path) of ignore files
279     /////////////////////////////////////////////////////////////////////////////////////////////////
280     std::vector<std::string> Synchronizer::GetIgnoreList(const std::string &i_key)
281     {
282                 mIgnoreList.clear();
283         std::vector<std::string> i_names;
284                 std::string query = "SELECT * FROM IGNORED_FILES WHERE ADD_KEY = ";
285                 query+=i_key;
286         CppSQLite3Query res;
287         QUERYSYNCDB(query, res);
288                 while (!res.eof())
289         {
290                         RemoveList temp = RemoveList(res);
291                         if(temp.remove.compare("0")==0)
292                         {
293             mIgnoreList.push_back(temp);
294                         }
295                         res.nextRow();
296         }
297         std::vector<RemoveList>::iterator it;
298
299         for(it = mIgnoreList.begin();it != mIgnoreList.end(); ++it)
300         {
301             i_names.push_back((*it).path);
302         }
303                 return i_names;
304     }
305
306         /////////////////////////////////////////////////////////////////////////////////////////////////
307     // Gets the required attribute in the required table
308     // @param attribute: the attribute to look for
309     // @param table: the table to look in
310     // @param searchParam: the search parameter
311     // @param searchValue: the search value
312     // @result : required attribute
313     /////////////////////////////////////////////////////////////////////////////////////////////////
314     std::string Synchronizer::GetAttribute(const std::string& attribute, 
315                                         const std::string& table, 
316                                         const std::string& searchParam,
317                                         const std::string& searchValue, 
318                                         const std::string& refdb)
319     {
320         std::stringstream query;
321                 std::string result;
322                 std::string sVal=searchValue.c_str();
323                 CleanName(sVal);
324                 query<<"SELECT "<<attribute<<" FROM "<<table<<" WHERE "<<searchParam<<" = '"<<sVal;
325                 if(table.compare("ADD_OPS")==0)
326                 {
327                         query<<"' AND REFERENCEDDB = '"<<refdb<<"';";
328                 }
329                 else
330                 {
331                         query<<"';";
332                 }
333         CppSQLite3Query res;
334         QUERYSYNCDB(query.str(), res);
335                 while (!res.eof())
336         {
337                         result=res.getStringField(0);
338                         res.nextRow();
339         }
340                 return result;
341     }
342
343         /////////////////////////////////////////////////////////////////////////////////////////////////
344     // Sets the attribute value in the required table and column
345     // @param attribute: the attribute to look for
346     // @param table: the table to look in
347         // @param value: the value to set
348     // @param searchParam: the search parameter
349     // @param searchValue: the search value
350     // @result : attribute value changed
351     /////////////////////////////////////////////////////////////////////////////////////////////////
352     void Synchronizer::SetAttribute(const std::string& attribute, 
353                                 const std::string& table, 
354                                 const std::string& value,
355                                 const std::string& searchParam,
356                                 const std::string& searchValue,
357                                 const std::string& refdb)
358     {
359                 std::string val=value.c_str();
360                 std::string sVal=searchValue.c_str();
361                 CleanName(val);
362                 CleanName(sVal);
363                 std::string sql = "UPDATE ";
364                 sql+=table;
365                 sql+=" SET ";
366                 sql += attribute;
367                 sql += " = '";
368                 sql += val;
369                 sql += "' WHERE ";
370                 sql += searchParam;
371                 sql += " = '";
372                 sql += sVal;
373                 if(table.compare("ADD_OPS")==0)
374                 {
375                         sql += "' AND REFERENCEDDB = '";
376                         sql += refdb;
377                 }
378                 sql += "';";
379                 UPDATESYNCDB(sql);
380     }
381
382
383
384 /////////////////////////////////////////////////////////////////////////////////////////////////
385     // get the files name to ignore for a add operation synchronization
386     // @param : the add key
387     //@result : list (path) of ignore files
388     /////////////////////////////////////////////////////////////////////////////////////////////////
389     void Synchronizer::GetList()
390     {
391                 mList.clear();
392         std::vector<std::string> i_names;
393                 std::string query = "SELECT PATH, REMOVE FROM IGNORED_FILES";
394                 CppSQLite3Query res;
395         QUERYSYNCDB(query, res);
396                 while (!res.eof())
397         {
398                         std::string file(res.getStringField(0));
399                         std::string ignore(res.getStringField(1));
400                         mList[file] = ignore == "0"? true : false;
401                         res.nextRow();
402         }
403                 
404     }
405
406         bool Synchronizer::isIndexed(const std::string filename)
407         {
408                 bool valid = true;
409                 std::string name(filename);
410                 boost::algorithm::replace_all( name,"\\" , "/");
411                 std::map <std::string, bool>::iterator it_list = mList.begin();
412                 for(;it_list != mList.end(); it_list++)
413                 {
414                         if(it_list->first == name)
415                         {
416                                 valid = false;
417                                 break;
418                         }
419                 }
420                 return valid;
421         }
422 }