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