1 #include <creaImageIOSQLiteTreeHandler.h>
2 #include <creaImageIOSystem.h>
4 #include "CppSQLite3.h"
8 //#include <creaImageIOSQLiteTreeHandlerStructure.h>
10 //#include <creaImageIOUtilities.h>
12 //#include <icons/database.xpm>
18 #include <wx/filename.h>
21 //#include <icons/close.xpm>
26 #include <boost/filesystem.hpp>
27 #include <boost/algorithm/string/replace.hpp>
34 //=============================================================
35 SQLiteTreeHandler::SQLiteTreeHandler(const std::string& filename)
38 mDB = new CppSQLite3DB;
39 GimmickMessage(1,"SQLite version : "
40 <<std::string(mDB->SQLiteVersion())<< std::endl);
42 //=============================================================
44 //=============================================================
45 SQLiteTreeHandler::~SQLiteTreeHandler()
49 //=============================================================
52 //=============================================================
53 // void SQLiteTreeHandler::Print() const
56 std::cout << "-> '"<<GetName()<< "' - '"
57 << GetFileName()<<"'"<<std::endl;
58 ChildrenListType::const_iterator i;
59 for (i=GetChildrenList().begin(); i!=GetChildrenList().end(); i++)
65 //=============================================================
67 //=====================================================================
69 bool SQLiteTreeHandler::LocationIsValid()
75 //=====================================================================
78 //=====================================================================
79 bool SQLiteTreeHandler::Open(bool writable)
81 // std::cout << "***> SQLiteTreeHandler::Open('"<<GetFileName()<<"')"<<std::endl;
82 SetWritable(writable);
86 //=====================================================================
87 bool SQLiteTreeHandler::Create(bool writable)
89 // std::cout << "***> SQLiteTreeHandler::New('"<<GetFileName()<<"')"<<std::endl;
90 SetWritable(writable);
93 //=====================================================================
96 //=====================================================================
97 bool SQLiteTreeHandler::Close()
101 //=====================================================================
104 //=====================================================================
105 bool SQLiteTreeHandler::Destroy()
109 //=====================================================================
111 //=====================================================================
112 unsigned int SQLiteTreeHandler::GetNumberOfChildren(tree::Node* n)
116 //=====================================================================
118 //=====================================================================
119 int SQLiteTreeHandler::LoadChildren(tree::Node* parent, int maxlevel)
121 if (parent==0) parent = GetTree().GetTree();
122 return DBLoadChildren(parent,maxlevel);
124 //=====================================================================
129 //=====================================================================
130 void SQLiteTreeHandler::UnLoad(tree::Node* n)
133 //=====================================================================
136 //=====================================================================
137 int SQLiteTreeHandler::AddBranch( const AttributeMapType& attr )
139 tree::Node* parent = DBGetParent(attr);
140 DBGraftToParent(parent,attr);
141 return (parent->GetLevel()+1);
143 //=====================================================================
146 //=====================================================================
147 bool SQLiteTreeHandler::Remove(tree::Node*)
151 //=====================================================================
153 //=====================================================================
154 /// Sets an attribute of a Node
155 bool SQLiteTreeHandler::SetAttribute(tree::Node* n,
156 const std::string& key,
157 const std::string& value)
159 if (n==0) n=GetTree().GetTree();
160 return DBSetAttribute(n,key,value);
162 //=====================================================================
176 //=====================================================================
177 // SQLite DB specific methods
178 //=====================================================================
183 //=====================================================================
184 char* format_sql(const std::string& s)
186 return sqlite3_mprintf("%q",s.c_str());
188 //=====================================================================
190 // sqlite3_exec(db, zSQL, 0, 0, 0);
191 // sqlite3_free(zSQL);
192 // char* CHAIN = format_sql(QUER); \
193 // sqlite3_free(CHAIN); \
195 //=====================================================================
196 #define QUERYDB(QUER,RES) \
199 GimmickMessage(2,"SQL query: '"<<QUER<<"'"<<std::endl); \
200 RES = mDB->execQuery(QUER.c_str()); \
202 catch (CppSQLite3Exception& e) \
204 GimmickError("SQLite query '"<<QUER<<"' : " \
205 << e.errorCode() << ":" \
206 << e.errorMessage() ); \
209 //=====================================================================
211 //=====================================================================
212 #define UPDATEDB(UP) \
215 GimmickMessage(2,"SQL update: '"<<UP<<"'"<<std::endl); \
216 mDB->execDML(UP.c_str()); \
218 catch (CppSQLite3Exception& e) \
220 GimmickError("SQLite update '"<<UP<<"' Error : " \
221 << e.errorCode() << ":" \
222 << e.errorMessage() ); \
224 //=====================================================================
227 //=====================================================================
228 bool SQLiteTreeHandler::DBOpen()
230 GimmickMessage(1,"Opening SQLite database '"<<GetFileName()
231 <<"' ... "<<std::endl);
233 if (!boost::filesystem::exists(GetFileName()))
240 mDB->open(GetFileName().c_str());
242 catch (CppSQLite3Exception& e)
244 GimmickError("Opening '"<<GetFileName()<<"' : "
245 << e.errorCode() << ":"
246 << e.errorMessage());
249 // IMPORT TREE DESCRIPTION (AND TEST DB VALIDITY)
250 if (!DBImportTreeDescription())
255 GimmickDebugMessage(1,"Opening SQLite database '"<<GetFileName()
256 <<"' ... OK"<<std::endl);
259 //=====================================================================
261 //=====================================================================
262 bool SQLiteTreeHandler::DBCreate()
264 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
265 <<"' ... "<<std::endl);
267 if (boost::filesystem::exists(GetFileName()))
269 GimmickError(GetFileName()<<"' : "
270 << "file already exists");
277 mDB->open(GetFileName().c_str());
279 catch (CppSQLite3Exception& e)
281 GimmickError(e.errorCode() << ":"
282 << e.errorMessage() <<std::endl);
290 // Create LEVELS table
291 command = "create table LEVELS\n";
292 command += "( Name text )\n";
295 // Iterate the Levels
296 for (int l=0; l<GetTree().GetNumberOfLevels(); ++l)
298 command = "INSERT INTO LEVELS (Name) VALUES ('";
299 command += GetTree().GetLevelDescriptor(l).GetName();
303 // Create table of level (for level>0, i.e. not Root)
306 command = "CREATE TABLE ";
307 command += GetTree().GetLevelDescriptor(l).GetName();
308 command += "\n(\nID INTEGER PRIMARY KEY";
311 command += ",\nPARENT_ID int not null";
313 SQLAppendAttributesDefinition(l,command);
316 command += ",\nconstraint FK_PARENT foreign key (PARENT_ID) references ";
317 command += GetTree().GetLevelDescriptor(l-1).GetName();
318 command += "(ID) on delete restrict on update restrict";
324 // Add Attribute 'ID' to Description
325 GetTree().GetLevelDescriptor(l).Add
326 (AttributeDescriptor( "ID",
327 "Database Identifier",
329 AttributeDescriptor::PRIVATE
334 // Add Attribute 'PARENT_ID' to Description
335 GetTree().GetLevelDescriptor(l).Add
336 (AttributeDescriptor( "PARENT_ID",
337 "Database Parent Identifier",
339 AttributeDescriptor::PRIVATE
345 // Create table *_ATTRIBUTES
347 command = "CREATE TABLE ";
348 command += GetTree().GetLevelDescriptor(l).GetName();
349 command += "_Attributes\n(\n";
350 command += "Key text,\n";
351 command += "Name text,\n";
352 command += "DicomGroup int,\n";
353 command += "DicomElement int,\n";
354 command += "Flags int\n";
359 // Fill the table *_ATTRIBUTES
360 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
361 for (i = GetTree().GetAttributeDescriptorList(l).begin();
362 i != GetTree().GetAttributeDescriptorList(l).end();
366 std::stringstream insert;
367 insert << "INSERT INTO "
368 << GetTree().GetLevelDescriptor(l).GetName()
369 << "_Attributes (Key,Name,DicomGroup,DicomElement,Flags) "
371 << i->GetKey() << "','"
372 << i->GetName() << "',"
373 << i->GetGroup() << ","
374 << i->GetElement() << ","
375 << i->GetFlags() << ");";
377 UPDATEDB(insert.str());
382 // Initialize the root attributes
383 GetTree().InitializeAttributeMap();
384 // Insert the root in the level 0 table
385 DBInsert(GetTree().GetTree());
388 GetTree().SetChildrenLoaded(true);
389 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
390 <<"' ... OK"<<std::endl);
393 //=====================================================================
395 //=====================================================================
396 void SQLiteTreeHandler::SQLAppendAttributesDefinition(int level,
399 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
400 for (i = GetTree().GetAttributeDescriptorList(level).begin();
401 i != GetTree().GetAttributeDescriptorList(level).end();
404 // if (i->second.flags==1) continue;
410 //=====================================================================
413 //=====================================================================
414 bool SQLiteTreeHandler::DBImportTreeDescription()
416 GimmickMessage(1,"Importing tree description from database ..."
419 // Test table 'LEVELS' existence
420 if ( ! mDB->tableExists("LEVELS") )
422 GimmickMessage(1,"!! ERROR : Table 'LEVELS' does not exist"
427 tree::Descriptor& desc = GetTree().GetDescriptor();
428 // clears the existing one
429 desc.GetLevelDescriptorList().clear();
432 std::string query = "SELECT * FROM LEVELS";
438 std::string name = q.getStringField(0);
439 GimmickMessage(2," * Importing level '"<<name<<"'"<<std::endl);
440 desc.GetLevelDescriptorList().push_back(LevelDescriptor(name));
445 for (int level = 0; level < nblevel; ++level )
447 std::string table = GetTree().GetLevelDescriptor(level).GetName();
448 table += "_Attributes";
449 // Test table 'LEVELS' existence
450 if ( ! mDB->tableExists(table.c_str()) )
452 GimmickMessage(1,"!! ERROR : Table '"<<table<<"' does not exist"
457 std::string query = "SELECT * FROM ";
462 GimmickMessage(2," * Level '"
463 <<GetTree().GetLevelDescriptor(level).GetName()
466 // Test that ID and PARENT_ID mandatory attributes exist
467 bool ID_found = false;
468 bool PARENT_ID_found = false;
469 if (level==0) ID_found = true;
470 if (level<=1) PARENT_ID_found = true;
474 std::string key(q.getStringField(0));
475 std::string name(q.getStringField(1));
476 GimmickMessage(2," - Importing attribute '"<<key<<"' '"<<name
478 desc.GetLevelDescriptor(level).Add
479 (AttributeDescriptor( key, // Key
481 q.getIntField(2), // Group
482 q.getIntField(3), // Element
483 q.getIntField(4) // Flags
489 if ( key == "PARENT_ID" )
491 PARENT_ID_found = true;
496 if ( ! (ID_found || PARENT_ID_found ) )
498 GimmickMessage(1,"!! ERROR : Table '"<<table
499 <<"' does not contain mandatory attribute ID or PARENT_ID"
507 // Create the attributes table for Root (i.e. Tree)
508 LevelDescriptor::AttributeDescriptorListType::const_iterator a;
509 for (a = GetTree().GetAttributeDescriptorList(0).begin();
510 a!= GetTree().GetAttributeDescriptorList(0).end();
515 AttributeMapType::const_iterator i = attr.find(a->GetKey());
516 if ( i != attr.end() )
521 GetTree().UnsafeSetAttribute( a->GetKey(), "" );
524 // Reading Root attributes
526 query = "SELECT * FROM ";
527 query += GetTree().GetLevelDescriptor(0).GetName();
530 for (int fld = 0; fld < q.numFields(); fld++)
532 GetTree().UnsafeSetAttribute(q.fieldName(fld),
533 q.getStringField(fld));
536 GimmickMessage(1,"Importing tree description from database ... OK"
540 //=====================================================================
558 //========================================================================
560 std::string& SQLformat(std::string& str)
562 // quote must be doubled
563 boost::algorithm::replace_all(str,"'","''");
564 // Found strange strings which contained NULL char INSIDE string
565 int i,size=str.size();
570 str = str.substr(0,i);
577 //========================================================================
579 //=====================================================================
580 void SQLiteTreeHandler::SQLAppendAttributesValues(tree::Node* n,
583 GimmickMessage(4,"SQLAppendAttributesValues"<<std::endl);
585 std::string values="";
586 tree::Node::AttributeMapType::iterator i;
587 for (i = n->GetAttributeMap().begin();
588 i != n->GetAttributeMap().end();
595 // std::cout << "("<<i->first<<","<<i->second<<")"<<std::endl;
596 atts += "'" + i->first + "'";
597 values += "'" + SQLformat(i->second) + "'";
600 GimmickMessage(4,"'"<<i->first<<"' = '"<<i->second<<"'"<<std::endl);
602 atts[atts.size()-1]=' ';
603 values[values.size()-1]=' ';
605 str = "("+atts+") VALUES ("+values+")";
606 GimmickMessage(4,"Result = '"<<str<<"'"<<std::endl);
608 //=====================================================================
610 //=====================================================================
611 tree::Node* SQLiteTreeHandler::DBGetParent( const AttributeMapType& attr)
613 Node* parent = GetTree().GetTree();
618 // Load the children of the current parent
619 DBLoadChildren(parent);
620 // Iterate the children
621 tree::Node::ChildrenListType::const_iterator i;
622 for (i = parent->GetChildrenList().begin();
623 i!= parent->GetChildrenList().end();
626 if ( (*i)->Matches( attr ) )
637 //=====================================================================
640 //=====================================================================
641 int SQLiteTreeHandler::DBLoadChildren(tree::Node* node,
644 if (node->GetLevel()+1 >= node->GetTree()->GetNumberOfLevels() )
647 GimmickMessage(2,"Loading children of '"<<node->GetLabel()
651 // If children loaded we do not have to do it but we need to recurse
652 // in order to load the children's children if necessary, and so on...
653 if (node->GetChildrenLoaded())
655 // Iterate the children
656 tree::Node::ChildrenListType::iterator i;
657 for (i = node->GetChildrenList().begin();
658 i!= node->GetChildrenList().end();
661 nbloaded += DBLoadChildren(*i,numberoflevels-1);
666 /// If children not loaded : do it and recurse
669 int level = node->GetLevel();
670 std::string query = "SELECT * FROM ";
671 query += GetTree().GetLevelDescriptor(level+1).GetName();
674 query += " WHERE PARENT_ID='" + node->UnsafeGetAttribute("ID")
683 Node* n = new Node(node);
684 for (int fld = 0; fld < q.numFields(); fld++)
686 n->UnsafeSetAttribute(q.fieldName(fld),q.getStringField(fld));
692 ti.id = n->GetFieldValue("ID");
693 mTypeIdToNodeMap[ti] = n;
696 if ( numberoflevels != 1 )
699 nbloaded += DBLoadChildren(n, numberoflevels-1);
706 node->SetChildrenLoaded(true);
711 //=====================================================================
713 //======================================================================
714 void SQLiteTreeHandler::DBInsert(tree::Node* n)
716 GimmickMessage(2,"Inserting in DB '"<<n->GetLabel()
719 SQLAppendAttributesValues(n,val);
720 std::string insert("INSERT INTO ");
721 insert += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
722 insert += " " + val + ";";
725 // Store DB id of newly created node;
726 long lastrow = mDB->lastRowId();
727 std::stringstream ri;
728 ri << mDB->lastRowId();
729 n->SetAttribute("ID",ri.str());
731 //======================================================================
733 //======================================================================
734 /// Graft the branch defined by the attributes to the parent
735 void SQLiteTreeHandler::DBGraftToParent( tree::Node* parent,
736 const AttributeMapType& attr)
738 GimmickMessage(2,"Grafting to parent '"<<parent->GetLabel()
741 for (int level = parent->GetLevel()+1;
742 level < GetTree().GetNumberOfLevels();
746 tree::Node* child = new tree::Node(parent,attr);
748 // Set PARENT_ID if necessary
749 if ( parent->GetLevel()>0 )
750 child->SetAttribute("PARENT_ID",parent->GetAttribute("ID"));
756 SQLAppendAttributesValues(child,val);
757 std::string insert("INSERT INTO ");
758 insert += GetTree().GetLevelDescriptor(child->GetLevel()).GetName();
759 insert += " " + val + ";";
762 // Store DB id of newly created node;
763 long lastrow = mDB->lastRowId();
764 std::stringstream ri;
765 ri << mDB->lastRowId();
766 child->SetAttribute("ID",ri.str());
772 // Insert in TypeId map
774 ti.type = node->GetType();
776 mTypeIdToNodeMap[ti] = node;
777 // std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl;
781 if (node->GetType()==Node::Patient) summary.added_patients++;
782 if (node->GetType()==Node::Study) summary.added_studies++;
783 if (node->GetType()==Node::Series) summary.added_series++;
784 if (node->GetType()==Node::Image) summary.added_images++;
788 //======================================================================
791 //=====================================================================
792 /// Sets an attribute of a Node
793 bool SQLiteTreeHandler::DBSetAttribute(tree::Node* n,
794 const std::string& key,
795 const std::string& value)
797 GimmickMessage(3,"Setting Attribute of '"<<n->GetLabel()<<
798 "' "<<key<<"='"<<value<<"'"<<std::endl);
800 n->SetAttribute(key,value);
801 std::string sql = "UPDATE ";
802 sql += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
807 sql += "' WHERE ID=";
808 sql += n->GetAttribute("ID");
809 // sql += " LIMIT 1";
812 //=====================================================================
815 //=====================================================================
816 bool SQLiteTreeHandler::DBInsert(Node* alien_node,
817 UpdateSummary& summary)
819 // std::cout << "SQLiteTreeHandler::Insert('"<<alien_node->GetLabel()
820 // <<"')"<<std::endl;
822 // if (!ChildrenLoaded()) DBLoadChildren(this,Node::Database);
826 std::string parent_id;
827 parent = DBGetOrCreateParent(alien_node,parent_id,summary);
830 DBRecursiveGetOrCreateNode(alien_node,parent,parent_id,summary);
833 //=====================================================================
836 //=====================================================================
837 Node* SQLiteTreeHandler::DBGetOrCreateParent(Node* alien_node,
838 std::string& parent_id,
839 UpdateSummary& summary)
841 // std::cout << "DBGetOrCreateParent '" << alien_node->GetLabel()<<"'"
843 // Load the patients if not already done
844 DBLoadChildren(this,Node::Patient);
849 // The chain of ancestors
850 std::deque<Node*> chain;
851 Node* cur = alien_node->GetParent();
852 for (int type=Node::Patient;
853 type<alien_node->GetType();++type)
855 chain.push_front(cur);
856 cur = cur->GetParent();
859 // create the nodes if do not exist
860 std::deque<Node*>::iterator i;
861 for (i=chain.begin();i!=chain.end();++i)
863 // std::cout << " cur = '"<<(*i)->GetLabel()<<"'"<<std::endl;
864 // std::string cur_id = DBGetNodeId(*i,parent_id);
865 // if (cur_id.size()==0)
867 // Node does not exist : create it
869 parent = DBGetOrCreateNode(*i,
875 DBLoadChildren(parent,parent->GetType()+1);
881 //=====================================================================
885 //=====================================================================
886 void SQLiteTreeHandler::DBRecursiveGetOrCreateNode(Node* alien_node,
888 const std::string& parent_id,
889 UpdateSummary& summary)
891 // std::cout << "SQLiteTreeHandler::RecursiveGetOrCreateNode('"
892 // <<alien_node->GetLabel()
893 // <<"','"<<parent<<"','"<<parent_id<<"')"<<std::endl;
896 // std::cout << " -- Parent = '"<<parent->GetLabel()<<"'"<<std::endl;
899 Node* new_node = DBGetOrCreateNode(alien_node,
904 Node::ChildrenListType::iterator i;
905 for (i = alien_node->GetChildrenList().begin();
906 i != alien_node->GetChildrenList().end();
909 DBRecursiveGetOrCreateNode((*i),new_node,new_id,summary);
912 //=====================================================================
915 //=====================================================================
916 Node* SQLiteTreeHandler::DBGetOrCreateNode(Node* alien_node,
917 Node* internal_parent,
918 std::string parent_id,
919 std::string& node_id,
920 UpdateSummary& summary)
922 // std::cout << "DBGetOrCreateNode('"<<alien_node->GetLabel()<<"','"
923 // << internal_parent << "','"<< parent_id<<"')"<<std::endl;
924 if (internal_parent != 0)
926 // std::cout << " -- Parent = '"<<internal_parent->GetLabel()<<"'"<<std::endl;
928 // Node Exists ? return it
929 // First try among children of internal parent
930 Node* node = GetChildrenLike(internal_parent,alien_node);
933 node_id = node->UnsafeGetFieldValue("ID");
936 // Second : try in DB
938 // Does not exist : Create new one
939 node = new Node(alien_node->GetType(),this,internal_parent);
940 node->SetChildrenLoaded(true);
941 // Copy fields values from alien
942 Node::FieldValueMapType::iterator i,j;
943 for (i = node->GetFieldValueMap().begin();
944 i != node->GetFieldValueMap().end();
947 j = alien_node->GetFieldValueMap().find(i->first);
948 if (j != alien_node->GetFieldValueMap().end() )
950 i->second = j->second;
955 if (node->GetType()!=Node::Patient)
956 node->SetFieldValue("PARENT_ID",parent_id);
960 BuildSQLFieldsValues(node,val);
961 std::string insert("INSERT INTO ");
962 insert += std::string(SQLiteTreeHandlerStructure::Table(node->GetType()))
964 // std::cout << "** SQL = '"<<insert<<"'"<<std::endl;
966 // std::cout << "** SQL OK"<<std::endl;
968 // Store DB id of newly created node;
969 long lastrow = mDB->lastRowId();
970 std::stringstream ri;
971 ri << mDB->lastRowId();
973 // std::cout << "LastRowId='"<<mDB->lastRowId()<<"' vs '"<<created_id<<"'"<<std::endl;
975 node->SetFieldValue("ID",node_id);
976 // Insert in TypeId map
978 ti.type = node->GetType();
980 mTypeIdToNodeMap[ti] = node;
981 // std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl;
985 if (node->GetType()==Node::Patient) summary.added_patients++;
986 if (node->GetType()==Node::Study) summary.added_studies++;
987 if (node->GetType()==Node::Series) summary.added_series++;
988 if (node->GetType()==Node::Image) summary.added_images++;
992 //=====================================================================
994 //=====================================================================
995 Node* SQLiteTreeHandler::GetChildrenLike(Node* parent,
998 Node::ChildrenListType::iterator i;
999 for (i = parent->GetChildrenList().begin();
1000 i != parent->GetChildrenList().end();
1003 Node::Type type = alien_node->GetType();
1006 j<SQLiteTreeHandlerStructure::NbQueryFields(type);
1010 alien_node->GetFieldValue(SQLiteTreeHandlerStructure::
1011 QueryField(type,j).key ) !=
1012 (*i)->GetFieldValue(SQLiteTreeHandlerStructure::
1013 QueryField(type,j).key ) )
1026 //=====================================================================
1028 //=====================================================================
1029 std::string SQLiteTreeHandler::DBGetNodeId(Node* node,
1030 const std::string& parent_id)
1032 // std::cout << "SQLiteTreeHandler::DBGetNodeId('"<<node->GetLabel()
1033 // <<"','"<<parent_id<<"')"
1036 int type = node->GetType();
1038 std::string table = SQLiteTreeHandlerStructure::Table(type);
1039 std::string where = "WHERE ";
1041 if (type!=Node::Patient)
1043 where += "PARENT_ID='" + parent_id
1044 //node->GetFieldValue("PARENT_ID")
1048 for (int i=0;i<SQLiteTreeHandlerStructure::NbQueryFields(type);i++)
1050 where += SQLiteTreeHandlerStructure::QueryField(type,i).key + "='"
1051 + node->GetFieldValue(SQLiteTreeHandlerStructure::QueryField(type,i).key) + "' ";
1052 if (i<SQLiteTreeHandlerStructure::NbQueryFields(type)-1)
1056 std::string query = "SELECT ID FROM " + table + " " + where + ";";
1057 // std::cout << "** SQL = '"<<query<<"'"<<std::endl;
1064 // std::cout << " - Node exists " << std::endl;
1065 std::string id = q.getStringField(0);
1066 // std::cout << " id = '"<<id<<"'"<<std::endl;
1073 //=====================================================================
1077 //=====================================================================
1078 Node* SQLiteTreeHandler::GetNodeFromTypeId(Node::Type type,
1079 const std::string& id)
1081 // std::cout << "GetNodeFromTypeId("<<type<<","<<id<<")"<<std::endl;
1087 TypeIdToNodeMapType::iterator i = mTypeIdToNodeMap.find(ti);
1088 if (i == mTypeIdToNodeMap.end())
1091 std::cout << "Internal error : mTypeIdToNodeMap does not contain key"
1093 creaError("Internal error : mTypeIdToNodeMap does not contain key");
1097 // std::cout << " ** Node = "<<i->second<<std::endl;
1100 //=====================================================================
1102 //=====================================================================
1103 bool SQLiteTreeHandler::Remove(Node* node)
1105 DBRecursiveRemoveNode(node);
1107 // std::cout << "DELETE"<<std::endl;
1108 if (node->GetParent())
1110 node->GetParent()->RemoveChildrenFromList(node);
1113 // std::cout << "DELETE OK"<<std::endl;
1116 //========================================================================
1118 //=====================================================================
1119 void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
1121 // std::cout << "SQLiteTreeHandler::DBRecursiveRemoveNode('"
1122 // <<node->GetLabel()<<"')"<<std::endl;
1124 std::string query = "DELETE FROM ";
1125 query += SQLiteTreeHandlerStructure::Table(node->GetType());
1126 query += " WHERE ID='"+ node->GetFieldValue("ID") + "';";
1130 Node::ChildrenListType::iterator i;
1131 for (i = node->GetChildrenList().begin();
1132 i != node->GetChildrenList().end();
1135 DBRecursiveRemoveNode((*i));
1138 //=====================================================================
1140 //=====================================================================
1141 int SQLiteTreeHandler::DBQueryNumberOfChildren(Node* node)
1143 std::string query = "SELECT COUNT (ID) FROM ";
1144 query += SQLiteTreeHandlerStructure::Table(node->GetType()+1);
1145 if (node->GetType() != Node::Database)
1147 query += " WHERE PARENT_ID='"+ node->GetFieldValue("ID")+"'";
1151 // std::cout << "**SQL = "<< query << std::endl;
1156 // std::cout << "**RES = "<< q.getIntField(0) <<std::endl;
1158 return q.getIntField(0);
1160 //=====================================================================
1168 } // namespace creaImageIO