1 #include <creaImageIOTimestampDatabaseHandler.h>
2 #include <creaImageIOSystem.h>
4 #include "CppSQLite3.h"
10 #include <boost/filesystem.hpp>
11 #include <boost/algorithm/string/replace.hpp>
16 //=============================================================
17 TimestampDatabaseHandler::TimestampDatabaseHandler(const std::string& filename)
20 mDB = new CppSQLite3DB;
21 GimmickMessage(1,"SQLite version : "
22 <<std::string(mDB->SQLiteVersion())<< std::endl);
24 //=============================================================
26 //=============================================================
27 TimestampDatabaseHandler::~TimestampDatabaseHandler()
31 //=============================================================
32 //=====================================================================
33 bool TimestampDatabaseHandler::Open()
38 //=====================================================================
39 bool TimestampDatabaseHandler::Create()
43 //=====================================================================
46 //=====================================================================
47 bool TimestampDatabaseHandler::Close()
51 //=====================================================================
54 //=====================================================================
55 bool TimestampDatabaseHandler::Destroy()
65 //=====================================================================
66 // SQLite DB specific methods
67 //=====================================================================
68 //=====================================================================
69 #define QUERYTIMESTAMPDB(QUER,RES) \
72 GimmickMessage(2,"SQL query: '"<<QUER<<"'"<<std::endl); \
73 RES = mDB->execQuery(QUER.c_str()); \
75 catch (CppSQLite3Exception& e) \
77 GimmickError("SQLite query '"<<QUER<<"' : " \
78 << e.errorCode() << ":" \
79 << e.errorMessage() ); \
81 //=====================================================================
82 #define UPDATETIMESTAMPDB(UP) \
85 GimmickMessage(2,"SQL update: '"<<UP<<"'"<<std::endl); \
86 mDB->execDML(UP.c_str()); \
88 catch (CppSQLite3Exception& e) \
90 GimmickError("SQLite update '"<<UP<<"' Error : " \
91 << e.errorCode() << ":" \
92 << e.errorMessage() ); \
94 //=====================================================================
97 //=====================================================================
98 bool TimestampDatabaseHandler::DBOpen()
100 GimmickMessage(1,"Opening SQLite database '"<<GetFileName()
101 <<"' ... "<<std::endl);
103 if (!boost::filesystem::exists(GetFileName()))
110 mDB->open(GetFileName().c_str());
112 catch (CppSQLite3Exception& e)
114 GimmickError("Opening '"<<GetFileName()<<"' : "
115 << e.errorCode() << ":"
116 << e.errorMessage());
120 GimmickDebugMessage(1,"Opening SQLite database '"<<GetFileName()
121 <<"' ... OK"<<std::endl);
124 //=====================================================================
126 //=====================================================================
127 bool TimestampDatabaseHandler::DBCreate()
129 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
130 <<"' ... "<<std::endl);
132 if (boost::filesystem::exists(GetFileName()))
134 GimmickError(GetFileName()<<"' : "
135 << "file already exists");
142 mDB->open(GetFileName().c_str());
144 catch (CppSQLite3Exception& e)
146 GimmickError(e.errorCode() << ":"
147 << e.errorMessage() <<std::endl);
157 command = "CREATE TABLE ";
159 command += "\n(\nID INTEGER PRIMARY KEY";
160 command += ",\nPARENT_ID int not null";
161 command += ",\nPATH text";
162 command += ",\nLastModified datetext";
163 command += ",\nLastRead datetext";
164 command += ",\nTopLevelNodeId text";
165 command += ",\nReferencedDB text";
166 command += ",\nconstraint FK_PARENT foreign key (PARENT_ID) references ";
168 command += "(ID) on delete restrict on update restrict";
171 UPDATETIMESTAMPDB(command);
178 //=====================================================================
179 void TimestampDatabaseHandler::CleanPath(std::string& str) const
184 pos = str.find('\\');
187 str.replace(pos, 1, "/");
190 while ((int)pos!=-1);
192 //=====================================================================
194 bool TimestampDatabaseHandler::AddDirectory(const std::string& parent,
195 const std::string& path,
196 const time_t lastModif,
197 const time_t lastRead,
198 const std::string& refdb)
201 std::string par=parent.c_str();
202 std::string pat=path.c_str();
206 std::string pathId=IsIndexed(pat,refdb);
207 //Case: It is a root parent
208 if(parent.compare("")==0)
210 if(pathId.compare("")==0)
212 AddFile(pat,lastModif,lastRead,refdb);
217 valid=CheckTimestamp(pathId, lastModif, refdb);
222 std::string parentId=IsIndexed(par,refdb);
223 //Case: Parent is not in database
224 if(parentId.compare("")==0)
226 AddFile(par,lastModif,lastRead,refdb);
227 parentId=IsIndexed(par,refdb);
230 //Case path is not in database
231 if(pathId.compare("")==0)
233 AddFile(parentId,pat,lastModif,lastRead,refdb);
236 //Parent and path are in the database
239 SetAttribute("PARENT_ID",parentId,"ID", pathId);
240 valid=CheckTimestamp(pathId, lastModif, refdb);
247 //=====================================================================
249 void TimestampDatabaseHandler::AddFile(const std::string& path, const time_t lastModif, const time_t lastRead, const std::string& refdb)
251 std::stringstream out;
252 out<<"INSERT INTO FILES (PARENT_ID,PATH,LastModified,LastRead,ReferencedDB) VALUES(0,'"<<path<<"',";
253 out<<lastModif<<","<<lastRead<<",'"<<refdb<<"');";
254 UPDATETIMESTAMPDB(out.str());
258 //=====================================================================
260 void TimestampDatabaseHandler::AddFile(const std::string& parentId,
261 const std::string& path,
262 const time_t lastModif,
263 const time_t lastRead,
264 const std::string& refdb)
266 std::stringstream out;
267 out<<"INSERT INTO FILES (PARENT_ID,PATH,LastModified,LastRead,ReferencedDB) VALUES("<<parentId<<",'"<<path<<"',";
268 out<<lastModif<<","<<lastRead<<",'"<<refdb<<"');";
269 UPDATETIMESTAMPDB(out.str());
272 //=====================================================================
273 std::string TimestampDatabaseHandler::IsIndexed(const std::string& path, const std::string& refdb)
275 std::string pat=path.c_str();
277 std::stringstream out;
278 std::stringstream result;
279 out<<"SELECT ID FROM FILES WHERE PATH='"<<pat<<"' AND REFERENCEDDB='"<<refdb<<"';";
282 QUERYTIMESTAMPDB(out.str(),q);
287 for (int fld = 0; fld < q.numFields(); fld++)
289 result<<q.getStringField(fld);
297 //=====================================================================
298 void TimestampDatabaseHandler::SetAttribute(const std::string& attName,
299 const std::string& attValue,
300 const std::string& searchParam,
301 const std::string& searchValue)
303 std::string av=attValue.c_str();
304 std::string sv=searchValue.c_str();
308 std::string sql = "UPDATE FILES SET ";
317 UPDATETIMESTAMPDB(sql);
320 //=====================================================================
321 void TimestampDatabaseHandler::RemoveNode(const std::string& searchAtt, const tree::Node* node, const std::string& refdb)
323 int n=node->GetNumberOfChildren();
326 std::vector<tree::Node*> children=node->GetChildrenList();
327 std::vector<tree::Node*>::iterator it;
328 for(it=children.begin();it!=children.end();++it)
330 RemoveNode(searchAtt,(*it),refdb);
333 else if(node->GetLevel()==3)
335 RemoveFile(searchAtt,node->GetAttribute("FullFileName"),refdb);
339 DBRemove("TopLevelNodeId",node->GetAttribute("ID"),refdb);
344 //=====================================================================
345 void TimestampDatabaseHandler::RemoveFile(const std::string& searchAtt, const std::string& searchVal, const std::string& refdb )
348 std::stringstream result;
349 std::string sel="SELECT PARENT_ID FROM FILES WHERE "+searchAtt+"='"+searchVal+"' AND REFERENCEDDB='"+refdb+"';";
352 QUERYTIMESTAMPDB(sel,q);
356 for (int fld = 0; fld < q.numFields(); fld++)
358 result<<q.getStringField(fld);
362 DBRemove(searchAtt,searchVal,refdb);
365 sel="SELECT ID FROM FILES WHERE PARENT_ID='"+result.str()+"'";
367 QUERYTIMESTAMPDB(sel,q2);
375 if(!result.str().compare("0"))
377 RemoveFile("ID",result.str(),refdb);
381 DBRemove("ID",result.str(),refdb);
386 //=====================================================================
387 void TimestampDatabaseHandler::DBRemove(const std::string& searchAtt, const std::string& searchVal, const std::string& refdb)
390 std::string query = "DELETE FROM FILES WHERE "+searchAtt+"='"+ searchVal + "' AND REFERENCEDDB='"+refdb+"';";
391 UPDATETIMESTAMPDB(query);
394 //=====================================================================
395 bool TimestampDatabaseHandler::CheckTimestamp(const std::string pathId, const time_t lastModif, const std::string& refdb)
397 std::string sel="SELECT LastModified FROM FILES WHERE ID='"+pathId+"' AND REFERENCEDDB='"+refdb+"';";
399 QUERYTIMESTAMPDB(sel,q);
404 for (int fld = 0; fld < q.numFields(); fld++)
406 timestamp=q.getFloatField(fld);
412 std::stringstream lm;
414 double modif=atof((lm.str()).c_str());
417 SetAttribute("LastModified",lm.str(),"ID",pathId);
423 //=====================================================================
424 void TimestampDatabaseHandler::RemoveEntries(const std::string i_table,
425 const std::string i_attribute,
426 const std::string i_operand,
427 const std::string i_val)
429 std::stringstream query;
430 query<<"DELETE FROM "<<i_table<<" WHERE "<<i_attribute<<" "<<i_operand<<" '"<<i_val<<"'";
431 UPDATETIMESTAMPDB(query.str());
434 }// namespace creaImageIO