]> Creatis software - creaImageIO.git/blob - src2/creaImageIOSynchron.cpp
\ No newline at end of file
[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         bool Synchronizer::isIndexed(const std::string filename)
406         {
407                 bool valid = true;
408                 std::string name(filename);
409                 boost::algorithm::replace_all( name,"\\" , "/");
410                 std::map <std::string, bool>::iterator it_list = mList.begin();
411                 for(;it_list != mList.end(); it_list++)
412                 {
413                         if(it_list->first == name)
414                         {
415                                 valid = false;
416                                 break;
417                         }
418                 }
419                 return valid;
420         }
421 }
422
423