1 #include <creaImageIOSQLiteTreeHandler.h>
2 #include <creaImageIOSystem.h>
3 #include <creaImageIOGimmick.h>
5 #include "CppSQLite3.h"
12 #include <boost/algorithm/string.hpp>
22 //=============================================================
23 SQLiteTreeHandler::SQLiteTreeHandler(const std::string& filename)
26 mDB = new CppSQLite3DB;
28 //GimmickMessage(1,"SQLite version : " <<std::string(mDB->SQLiteVersion())<< std::endl);
30 //=============================================================
32 //=============================================================
33 SQLiteTreeHandler::~SQLiteTreeHandler()
37 //=============================================================
40 //=====================================================================
43 //=====================================================================
44 bool SQLiteTreeHandler::Open(bool writable)
47 //sqlite3_exec(mDB, "PRAGMA synchronous=OFF ", NULL, 0, &errMsg);
48 SetWritable(writable);
52 //=====================================================================
53 bool SQLiteTreeHandler::Create(bool writable)
55 // std::cout << "***> SQLiteTreeHandler::New('"<<GetFileName()<<"')"<<std::endl;
56 SetWritable(writable);
59 //=====================================================================
62 //=====================================================================
63 bool SQLiteTreeHandler::Close()
67 //=====================================================================
70 //=====================================================================
71 bool SQLiteTreeHandler::Destroy()
76 //=====================================================================
78 //=====================================================================
79 int SQLiteTreeHandler::LoadChildren(tree::Node* parent, int maxlevel)
81 //mDB->execDML("PRAGMA synchronous=ON ");
82 if (parent==0) parent = GetTree().GetTree();
83 return DBLoadChildren(parent,maxlevel);
85 //=====================================================================
90 //=====================================================================
91 void SQLiteTreeHandler::UnLoad(tree::Node* n)
94 //=====================================================================
96 //=====================================================================
97 int SQLiteTreeHandler::AddBranch( const AttributeMapType& attr )
99 tree::Node* parent = DBGetParent(attr);
100 DBGraftToParent(parent,attr);
101 return (parent->GetLevel()+1);
104 //=====================================================================
107 //=====================================================================
108 bool SQLiteTreeHandler::Remove(tree::Node* node)
110 DBRecursiveRemoveNode(node);
112 // std::cout << "DELETE"<<std::endl;
114 tree::Node* parent=node->GetParent();
117 int nC = parent->RemoveChildrenFromList(node);
118 if(nC>0 && parent->GetLevel()>0)
120 std::stringstream out;
122 SetAttribute(parent,"NumberOfChildren",out.str());
131 if(remove&&parent->GetLevel()>0)
135 // std::cout << "DELETE OK"<<std::endl;
139 //=====================================================================
141 //=====================================================================
142 /// Sets an attribute of a Node
143 bool SQLiteTreeHandler::SetAttribute(tree::Node* n,
144 const std::string& key,
145 const std::string& value)
147 if (n==0) n=GetTree().GetTree();
148 return DBSetAttribute(n,key,value);
150 //=====================================================================
151 //=====================================================================
152 /// Sets an attribute
153 void SQLiteTreeHandler::SetAttribute(const std::string& levelDescriptor,
154 const std::string& key,
155 const std::string& value,
156 const std::string& searchParam,
157 const std::string& searchVal)
159 DBSetAttribute(levelDescriptor,key,value,searchParam, searchVal);
161 //=====================================================================
163 void SQLiteTreeHandler::DeleteTuple(std::string levelDescriptor,
164 std::string key, std::string value)
166 DBDelete(levelDescriptor,key,value);
168 //=====================================================================
182 //=====================================================================
183 // SQLite DB specific methods
184 //=====================================================================
189 //=====================================================================
190 char* format_sql(const std::string& s)
192 return sqlite3_mprintf("%q",s.c_str());
194 //=====================================================================
197 //=====================================================================
198 #define QUERYDB(QUER,RES) \
201 GimmickMessage(2,"SQL query: '"<<QUER<<"'"<<std::endl); \
202 RES = mDB->execQuery(QUER.c_str()); \
204 catch (CppSQLite3Exception& e) \
206 GimmickError("SQLite query '"<<QUER<<"' : " \
207 << e.errorCode() << ":" \
208 << e.errorMessage() ); \
211 //=====================================================================
213 //=====================================================================
214 #define UPDATEDB(UP) \
217 GimmickMessage(2,"SQL update: '"<<UP<<"'"<<std::endl); \
218 mDB->execDML(UP.c_str()); \
220 catch (CppSQLite3Exception& e) \
222 GimmickError("SQLite update '"<<UP<<"' Error : " \
223 << e.errorCode() << ":" \
224 << e.errorMessage() ); \
226 //=====================================================================
229 //=====================================================================
230 bool SQLiteTreeHandler::DBOpen()
232 GimmickMessage(1,"Opening SQLite database '"<<GetFileName()
233 <<"' ... "<<std::endl);
235 if (!boost::filesystem::exists(GetFileName()))
242 mDB->open(GetFileName().c_str());
243 mDB->execDML("pragma synchronous=off;");
245 catch (CppSQLite3Exception& e)
247 GimmickError("Opening '"<<GetFileName()<<"' : "
248 << e.errorCode() << ":"
249 << e.errorMessage());
252 // IMPORT TREE DESCRIPTION (AND TEST DB VALIDITY)
253 if (!DBImportTreeDescription())
258 GimmickDebugMessage(1,"Opening SQLite database '"<<GetFileName()
259 <<"' ... OK"<<std::endl);
262 //=====================================================================
264 //=====================================================================
265 bool SQLiteTreeHandler::DBCreate()
267 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
268 <<"' ... "<<std::endl);
270 if (boost::filesystem::exists(GetFileName()))
272 GimmickError(GetFileName()<<"' : "
273 << "file already exists");
280 mDB->open(GetFileName().c_str());
282 catch (CppSQLite3Exception& e)
284 GimmickError(e.errorCode() << ":"
285 << e.errorMessage() <<std::endl);
288 mDB->execDML("pragma synchronous=off;");
293 // Create LEVELS table
294 command = "create table LEVELS\n";
295 command += "( Name text )\n";
298 // Iterate the Levels
299 for (l=0; l<GetTree().GetNumberOfLevels(); l++)
301 command = "INSERT INTO LEVELS (Name) VALUES ('";
302 command += GetTree().GetLevelDescriptor(l).GetName();
306 // Create table of level (for level>0, i.e. not Root)
309 command = "CREATE TABLE ";
310 command += GetTree().GetLevelDescriptor(l).GetName();
311 command += "\n(\nID INTEGER PRIMARY KEY";
314 command += ",\nPARENT_ID int not null";
316 SQLAppendAttributesDefinition(l,command);
319 command += ",\nconstraint FK_PARENT foreign key (PARENT_ID) references ";
320 command += GetTree().GetLevelDescriptor(l-1).GetName();
321 command += "(ID) on delete restrict on update restrict";
326 GetTree().CopyAttributeDescriptorList(l);
328 // Add Attribute 'ID' to Description
329 GetTree().GetDescriptor().Add
330 (AttributeDescriptor( "ID",
331 "Database Identifier",
333 AttributeDescriptor::PRIVATE
338 // Add Attribute 'PARENT_ID' to Description
339 GetTree().GetDescriptor().Add
340 (AttributeDescriptor( "PARENT_ID",
341 "Database Parent Identifier",
343 AttributeDescriptor::PRIVATE
349 // Create table *_ATTRIBUTES
351 command = "CREATE TABLE ";
352 command += GetTree().GetLevelDescriptor(l).GetName();
353 command += "_Attributes\n(\n";
354 command += "Key text,\n";
355 command += "Name text,\n";
356 command += "DicomGroup int,\n";
357 command += "DicomElement int,\n";
358 command += "Flags int\n";
362 // Fill the table *_ATTRIBUTES
363 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
364 for (i = GetTree().GetAttributeDescriptorList(l).begin();
365 i != GetTree().GetAttributeDescriptorList(l).end();
369 std::stringstream insert;
370 insert << "INSERT INTO "
371 << GetTree().GetLevelDescriptor(l).GetName()
372 << "_Attributes (Key,Name,DicomGroup,DicomElement,Flags) "
374 << i->GetKey() << "','"
375 << i->GetName() << "',"
376 << i->GetGroup() << ","
377 << i->GetElement() << ","
378 << i->GetFlags() << ");";
379 UPDATEDB(insert.str());
384 // Initialize the root attributes
385 GetTree().InitializeAttributeMap();
386 // Insert the root in the level 0 table
387 DBInsert(GetTree().GetTree());
390 GetTree().SetChildrenLoaded(true);
391 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
392 <<"' ... OK"<<std::endl);
395 //=====================================================================
397 //=====================================================================
398 void SQLiteTreeHandler::SQLAppendAttributesDefinition(int level,
401 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
402 for (i = GetTree().GetAttributeDescriptorList(level).begin();
403 i != GetTree().GetAttributeDescriptorList(level).end();
406 // if (i->second.flags==1) continue;
412 //=====================================================================
415 //=====================================================================
416 bool SQLiteTreeHandler::DBImportTreeDescription()
418 GimmickMessage(1,"Importing tree description for database ..."
421 // Test table 'LEVELS' existence
422 if ( ! mDB->tableExists("LEVELS") )
424 GimmickMessage(1,"!! ERROR : Table 'LEVELS' does not exist"
429 tree::Descriptor& desc = GetTree().GetDescriptor();
430 // clears the existing one
434 std::string query = "SELECT * FROM LEVELS";
440 std::string name = q.getStringField(0);
441 GimmickMessage(2," * Importing level '"<<name<<"'"<<std::endl);
442 desc.Add(LevelDescriptor(name));
447 for (int level = 0; level < nblevel; ++level )
449 std::string table = GetTree().GetLevelDescriptor(level).GetName();
450 table += "_Attributes";
451 // Test table 'LEVELS' existence
452 if ( ! mDB->tableExists(table.c_str()) )
454 GimmickMessage(1,"!! ERROR : Table '"<<table<<"' does not exist"
459 std::string query = "SELECT * FROM ";
464 GimmickMessage(2," * Level '"
465 <<GetTree().GetLevelDescriptor(level).GetName()
468 // Test that ID and PARENT_ID mandatory attributes exist
469 bool ID_found = false;
470 bool PARENT_ID_found = false;
471 if (level==0) ID_found = true;
472 if (level<=1) PARENT_ID_found = true;
476 std::string key(q.getStringField(0));
477 std::string name(q.getStringField(1));
478 GimmickMessage(2," - Importing attribute '"<<key<<"' '"<<name
481 (AttributeDescriptor( key, // Key
483 q.getIntField(2), // Group
484 q.getIntField(3), // Element
485 q.getIntField(4) // Flags
491 if ( key == "PARENT_ID" )
493 PARENT_ID_found = true;
498 if ( ! (ID_found || PARENT_ID_found ) )
500 GimmickMessage(1,"!! ERROR : Table '"<<table
501 <<"' does not contain mandatory attribute ID or PARENT_ID"
506 GetTree().CopyAttributeDescriptorList(level);
510 // Create the attributes table for Root (i.e. Tree)
511 LevelDescriptor::AttributeDescriptorListType::const_iterator a;
512 for (a = GetTree().GetAttributeDescriptorList(0).begin();
513 a!= GetTree().GetAttributeDescriptorList(0).end();
517 GetTree().UnsafeSetAttribute( a->GetKey(), "" );
520 // Reading Root attributes
522 query = "SELECT * FROM ";
523 query += GetTree().GetLevelDescriptor(0).GetName();
526 for (int fld = 0; fld < q.numFields(); fld++)
528 GetTree().UnsafeSetAttribute(q.fieldName(fld),
529 q.getStringField(fld));
532 GimmickMessage(1,"Importing tree description from database ... OK"
536 //=====================================================================
538 //========================================================================
540 void SQLformat(std::string i_str, std::string &o_str)
542 // quote must be doubled
543 boost::algorithm::replace_all(i_str,"'","''");
544 // Found strange strings which contained NULL char INSIDE string
545 int i,size=i_str.size();
550 i_str = i_str.substr(0,i);
556 //========================================================================
558 //=====================================================================
559 void SQLiteTreeHandler::SQLAppendAttributesValues(tree::Node* n,
562 GimmickMessage(4,"SQLAppendAttributesValues"<<std::endl);
564 std::string values="";
566 tree::Node::AttributeMapType::iterator i;
567 for (i = n->GetAttributeMap().begin();
568 i != n->GetAttributeMap().end();
576 atts += "'" + i->first + "'";
577 SQLformat(i->second, out);
578 values += "'" + out + "'";
581 GimmickMessage(4,"'"<<i->first<<"' = '"<<i->second<<"'"<<std::endl);
583 atts[atts.size()-1]=' ';
584 values[values.size()-1]=' ';
586 str = "("+atts+") VALUES ("+values+")";
587 GimmickMessage(4,"Result = '"<<str<<"'"<<std::endl);
589 //=====================================================================
591 //=====================================================================
592 tree::Node* SQLiteTreeHandler::DBGetParent( const AttributeMapType& attr)
594 Node* parent = GetTree().GetTree();
599 // Load the children of the current parent
600 DBLoadChildren(parent);
601 // Iterate the children
602 tree::Node::ChildrenListType::const_iterator i;
603 for (i = parent->GetChildrenList().begin();
604 i!= parent->GetChildrenList().end();
607 if ( (*i)->Matches( attr ) )
618 //=====================================================================
620 //=====================================================================
621 int SQLiteTreeHandler::DBLoadChildren(tree::Node* node,
624 if (node->GetLevel()+1 >= node->GetTree()->GetNumberOfLevels() )
627 GimmickMessage(2,"Loading children of '"<<node->GetLabel()
631 // If children loaded we do not have to do it but we need to recurse
632 // in order to load the children's children if necessary, and so on...
633 if (node->GetChildrenLoaded())
635 // Iterate the children
637 tree::Node::ChildrenListType::iterator i;
638 for (i = node->GetChildrenList().begin();
639 i!= node->GetChildrenList().end();
642 nbloaded += DBLoadChildren(*i,numberoflevels-1);
644 node->SetChildrenLoaded(true);
650 /// If children not loaded : do it and recurse
653 int level = node->GetLevel();
654 std::string query = "SELECT * FROM ";
656 query += GetTree().GetLevelDescriptor(level+1).GetName();
659 query += " WHERE PARENT_ID='" + node->GetAttribute("ID")
662 GimmickDebugMessage(1, "query : '" <<query <<std::endl);
670 // std::cout << "DBLoadCh : creating node level "<<level+1<<std::endl;
673 Node* n = new Node(node);
674 for (int fld = 0; fld < q.numFields(); fld++)
676 n->UnsafeSetAttribute(q.fieldName(fld),q.getStringField(fld));
680 if ( numberoflevels != 1 )
683 nbloaded += DBLoadChildren(n, numberoflevels-1);
690 node->SetChildrenLoaded(true);
697 //=====================================================================
699 //======================================================================
700 void SQLiteTreeHandler::DBInsert(tree::Node* n)
702 GimmickMessage(2,"Inserting in DB '"<<n->GetLabel()
705 SQLAppendAttributesValues(n,val);
706 std::string insert("INSERT INTO ");
707 insert += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
708 insert += " " + val + ";";
712 // Store DB id of newly created node;
713 long lastrow = mDB->lastRowId();
714 std::stringstream ri;
715 ri << mDB->lastRowId();
716 n->SetAttribute("ID",ri.str());
718 //======================================================================
720 //======================================================================
721 /// Graft the branch defined by the attributes to the parent
722 void SQLiteTreeHandler::DBGraftToParent( tree::Node* parent,
723 const AttributeMapType& attr)
725 // std::cout <<"Grafting to parent '"<<parent->GetLabel()
728 for (int level = parent->GetLevel()+1;
729 level < GetTree().GetNumberOfLevels();
733 tree::Node* child = new tree::Node(parent,attr);
734 child->SetChildrenLoaded(true);
737 int nc = GetNumberOfChildren(parent)+1;
739 // std::cout<<"Number of children "<<parent->GetNumberOfChildren()<<std::endl;
740 std::stringstream out;
742 SetAttribute(parent,"NumberOfChildren",out.str());
745 // Set PARENT_ID if necessary
746 if ( parent->GetLevel()>0 )
747 child->SetAttribute("PARENT_ID",parent->GetAttribute("ID"));
756 //======================================================================
759 //=====================================================================
760 /// Sets an attribute of a Node
761 bool SQLiteTreeHandler::DBSetAttribute(tree::Node* n,
762 const std::string& key,
763 const std::string& value)
765 GimmickMessage(3,"Setting Attribute of '"<<n->GetLabel()<<
766 "' "<<key<<"='"<<value<<"'"<<std::endl);
768 n->SetAttribute(key,value);
769 std::string sql = "UPDATE ";
770 sql += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
774 sql += convert(value);
775 sql += "' WHERE ID = '";
776 sql += n->GetAttribute("ID");
778 // sql += " LIMIT 1";
783 //=====================================================================
784 /// Sets an attribute of a Node
785 void SQLiteTreeHandler::DBSetAttribute(const std::string& levelDescriptor,
786 const std::string& key,
787 const std::string& value,
788 const std::string& searchParam,
789 const std::string& searchVal)
792 std::string sql = "UPDATE ";
793 sql += levelDescriptor;
803 std::cout<<sql<<std::endl;
806 //=====================================================================
807 void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
810 std::string query = "DELETE FROM ";
811 query += GetTree().GetLevelDescriptor(node->GetLevel()).GetName();
812 query += " WHERE ID='"+ node->GetAttribute("ID") + "';";
815 if(node->GetNumberOfChildren()!=0)
817 Node::ChildrenListType::iterator i;
818 for (i = node->GetChildrenList().begin();
819 i != node->GetChildrenList().end();
822 DBRecursiveRemoveNode((*i));
825 else if(node->GetLevel()<GetTree().GetNumberOfLevels()-1)
827 DBRecursiveRemoveNode(node->GetLevel()+1,node->GetAttribute("ID"));
831 //=====================================================================
832 void SQLiteTreeHandler::DBRecursiveRemoveNode(int level, std::string parentId)
834 std::stringstream out;
835 std::stringstream result;
836 out<<"SELECT ID FROM "<<GetTree().GetLevelDescriptor(level).GetName()<<" WHERE PARENT_ID='"<<parentId<<"'";
839 QUERYDB(out.str(),q);
843 for (int fld = 0; fld < q.numFields(); fld++)
845 result<<q.getStringField(fld)<<"#";
849 std::string res=result.str();
852 while(fin<res.size()-1)
854 fin=res.find('#',ini);
855 DBDelete(GetTree().GetLevelDescriptor(level).GetName(),"ID",res.substr(ini,fin-ini));
856 if(level<GetTree().GetNumberOfLevels()-1)
858 DBRecursiveRemoveNode(level+1,res.substr(ini,fin-ini));
866 //=====================================================================
867 void SQLiteTreeHandler::DBDelete(std::string levelDescriptor, std::string key, std::string value)
870 std::stringstream query;
871 query<<"DELETE FROM "<<levelDescriptor<<" WHERE "<<key<<"='"<<value<<"';";
873 UPDATEDB(query.str());
874 GimmickDebugMessage(2," Deleting: Query: "<<query.str()<<std::endl);
878 //=====================================================================
879 void SQLiteTreeHandler::GetAttribute(std::string levelDescriptor,
880 std::string searchParam,
881 std::string searchVal,
885 std::stringstream out;
886 std::stringstream results;
887 out<<"SELECT "<<key<<" FROM "<<levelDescriptor;
890 out<<" WHERE "<<searchParam<<"='"<<searchVal<<"'";
894 QUERYDB(out.str(),q);
899 for (int fld = 0; fld < q.numFields(); fld++)
901 results<<q.getStringField(fld);
909 result=results.str();
912 //=====================================================================
913 unsigned int SQLiteTreeHandler::GetNumberOfChildren(tree::Node* n)
917 int level = n->GetLevel();
919 if(level<GetTree().GetNumberOfLevels()&& level>0)
921 std::string query = "SELECT NumberOfChildren FROM ";
922 query += GetTree().GetLevelDescriptor(level).GetName();
925 query += " WHERE ID='" + n->GetAttribute("ID")
934 for (int fld = 0; fld < q.numFields(); fld++)
936 nb=q.getIntField(fld);
950 //=====================================================================
951 // get all attributes from database for a given file
952 void SQLiteTreeHandler::getAllAttributes(std::string i_filename, std::map<std::string, std::string> &i_results)
954 int level=GetTree().GetNumberOfLevels()-1;
956 std::string search = i_filename;
957 std::string param = "FullFileName";
961 std::set<std::string> pid;
962 std::vector<AttributeDescriptor> attr;
963 std::vector<AttributeDescriptor>::iterator it_attr;
964 std::vector<std::string> values;
965 std::vector<std::string>::iterator it_val;
972 attr = GetTree().GetAttributeDescriptorList(level,1);
974 name = GetTree().GetLevelDescriptor(level).GetName();
975 std::vector<std::string> values;
976 GetUpLevelNodeId(level, param,search,id);
977 GetAttributes(name, param,search,attr, values);
978 for(it_attr = attr.begin(), it_val = values.begin(); it_attr != attr.end(); it_attr++, it_val++)
980 i_results[(*it_attr).GetKey()] = (*it_val).c_str();
989 //=====================================================================
990 // get selected attributes from database for a given file
991 void SQLiteTreeHandler::GetAttributes(std::string name, std::string i_id, std::string i_value, tree::LevelDescriptor::AttributeDescriptorListType i_attr, std::vector<std::string> &i_results)
993 //SELECT t1.ArtistName,CDs.Title FROM Artists t1, CDs WHERE t1.ArtistID=CDs.ArtistID
994 std::stringstream out;
995 std::stringstream results;
997 tree::LevelDescriptor::AttributeDescriptorListType::iterator it = i_attr.begin();
998 std::string query ="";
999 for(; it != i_attr.end(); it++)
1001 query += (*it).GetKey();
1004 query = query.substr(0, query.size()-1);
1006 out << "FROM "<<name;
1007 out<<" WHERE "<<i_id <<"='"<<i_value<<"'";
1009 QUERYDB(out.str(),q);
1012 for (int fld = 0; fld < q.numFields(); fld++)
1014 i_results.push_back(q.getStringField(fld));
1020 void SQLiteTreeHandler::GetUpLevelNodeId(int level, const std::string& searchParam, const std::string& searchValue, std::string& parent_id)
1022 std::string sp=searchParam.c_str();
1023 std::string sv=searchValue.c_str();
1024 std::stringstream out;
1025 std::stringstream results;
1026 out<<"SELECT PARENT_ID FROM "<<GetTree().GetLevelDescriptor(level).GetName();
1027 out<<" WHERE "<<sp<<"='"<<sv<<"'";
1029 QUERYDB(out.str(),q);
1032 for (int fld = 0; fld < q.numFields(); fld++)
1034 results<<q.getStringField(fld);
1038 parent_id = results.str();
1043 //=====================================================================
1044 void SQLiteTreeHandler::GetTopLevelNodeId(const std::string& searchParam, const std::string& searchValue, std::string& parent_id)
1046 int level=GetTree().GetNumberOfLevels()-1;
1047 std::string sp=searchParam.c_str();
1048 std::string sv=searchValue.c_str();
1052 GetUpLevelNodeId(level, sp, sv, parent_id);
1058 // std::stringstream out;
1059 // std::stringstream results;
1060 // out<<"SELECT PARENT_ID FROM "<<GetTree().GetLevelDescriptor(level).GetName();
1061 // out<<" WHERE "<<sp<<"='"<<sv<<"'";
1062 // CppSQLite3Query q;
1063 // QUERYDB(out.str(),q);
1068 // for (int fld = 0; fld < q.numFields(); fld++)
1070 // results<<q.getStringField(fld);
1076 // sv=results.str();
1082 //=====================================================================
1083 void SQLiteTreeHandler::RemoveEntries(const std::string i_table,
1084 const std::string i_attribute,
1085 const std::string i_operand,
1086 const std::string i_val)
1088 std::stringstream query;
1089 query<<"DELETE FROM "<<i_table<<" WHERE "<<i_attribute<<" "<<i_operand<<" '"<<i_val<<"'";
1090 UPDATEDB(query.str());
1093 //=====================================================================
1094 void SQLiteTreeHandler::BeginTransaction()
1096 std::stringstream out;
1097 out<<"begin transaction;";
1098 UPDATEDB(out.str());
1101 //=====================================================================
1102 void SQLiteTreeHandler::EndTransaction()
1104 std::stringstream out;
1105 out<<"commit transaction;";
1106 UPDATEDB(out.str());
1108 const std::string SQLiteTreeHandler::convert(const std::string &i_word)
1110 std::string temp = i_word;
1111 boost::algorithm::replace_all(temp,"'","''");
1112 return temp.c_str();
1115 } // namespace creaImageIO