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>
24 #include <creaMessageManager.h>
27 #include <boost/filesystem.hpp>
28 #include <boost/algorithm/string/replace.hpp>
35 //=============================================================
36 SQLiteTreeHandler::SQLiteTreeHandler(const std::string& filename)
39 mDB = new CppSQLite3DB;
40 GimmickMessage(1,"SQLite version : "
41 <<std::string(mDB->SQLiteVersion())<< std::endl);
43 //=============================================================
45 //=============================================================
46 SQLiteTreeHandler::~SQLiteTreeHandler()
50 //=============================================================
53 //=============================================================
54 // void SQLiteTreeHandler::Print() const
57 std::cout << "-> '"<<GetName()<< "' - '"
58 << GetFileName()<<"'"<<std::endl;
59 ChildrenListType::const_iterator i;
60 for (i=GetChildrenList().begin(); i!=GetChildrenList().end(); i++)
66 //=============================================================
68 //=====================================================================
70 bool SQLiteTreeHandler::LocationIsValid()
76 //=====================================================================
79 //=====================================================================
80 bool SQLiteTreeHandler::Open(bool writable)
82 // std::cout << "***> SQLiteTreeHandler::Open('"<<GetFileName()<<"')"<<std::endl;
83 SetWritable(writable);
87 //=====================================================================
88 bool SQLiteTreeHandler::Create(bool writable)
90 // std::cout << "***> SQLiteTreeHandler::New('"<<GetFileName()<<"')"<<std::endl;
91 SetWritable(writable);
94 //=====================================================================
97 //=====================================================================
98 bool SQLiteTreeHandler::Close()
102 //=====================================================================
105 //=====================================================================
106 bool SQLiteTreeHandler::Destroy()
110 //=====================================================================
112 //=====================================================================
113 unsigned int SQLiteTreeHandler::GetNumberOfChildren(tree::Node* n)
117 //=====================================================================
119 //=====================================================================
120 int SQLiteTreeHandler::LoadChildren(tree::Node* parent, int maxlevel)
122 if (parent==0) parent = GetTree().GetTree();
123 return DBLoadChildren(parent,maxlevel);
125 //=====================================================================
130 //=====================================================================
131 void SQLiteTreeHandler::UnLoad(tree::Node* n)
134 //=====================================================================
137 //=====================================================================
138 int SQLiteTreeHandler::AddBranch( const AttributeMapType& attr )
140 tree::Node* parent = DBGetParent(attr);
141 DBGraftToParent(parent,attr);
142 return (parent->GetLevel()+1);
144 //=====================================================================
147 //=====================================================================
148 bool SQLiteTreeHandler::Remove(tree::Node*)
152 //=====================================================================
154 //=====================================================================
155 /// Sets an attribute of a Node
156 bool SQLiteTreeHandler::SetAttribute(tree::Node* n,
157 const std::string& key,
158 const std::string& value)
160 if (n==0) n=GetTree().GetTree();
161 return DBSetAttribute(n,key,value);
163 //=====================================================================
177 //=====================================================================
178 // SQLite DB specific methods
179 //=====================================================================
184 //=====================================================================
185 char* format_sql(const std::string& s)
187 return sqlite3_mprintf("%q",s.c_str());
189 //=====================================================================
191 // sqlite3_exec(db, zSQL, 0, 0, 0);
192 // sqlite3_free(zSQL);
193 // char* CHAIN = format_sql(QUER); \
194 // sqlite3_free(CHAIN); \
196 //=====================================================================
197 #define QUERYDB(QUER,RES) \
200 GimmickMessage(2,"SQL query: '"<<QUER<<"'"<<std::endl); \
201 RES = mDB->execQuery(QUER.c_str()); \
203 catch (CppSQLite3Exception& e) \
205 GimmickError("SQLite query '"<<QUER<<"' : " \
206 << e.errorCode() << ":" \
207 << e.errorMessage() ); \
210 //=====================================================================
212 //=====================================================================
213 #define UPDATEDB(UP) \
216 GimmickMessage(2,"SQL update: '"<<UP<<"'"<<std::endl); \
217 mDB->execDML(UP.c_str()); \
219 catch (CppSQLite3Exception& e) \
221 GimmickError("SQLite update '"<<UP<<"' Error : " \
222 << e.errorCode() << ":" \
223 << e.errorMessage() ); \
225 //=====================================================================
228 //=====================================================================
229 bool SQLiteTreeHandler::DBOpen()
231 GimmickMessage(1,"Opening SQLite database '"<<GetFileName()
232 <<"' ... "<<std::endl);
234 if (!boost::filesystem::exists(GetFileName()))
241 mDB->open(GetFileName().c_str());
243 catch (CppSQLite3Exception& e)
245 GimmickError("Opening '"<<GetFileName()<<"' : "
246 << e.errorCode() << ":"
247 << e.errorMessage());
250 // IMPORT TREE DESCRIPTION (AND TEST DB VALIDITY)
251 if (!DBImportTreeDescription())
256 GimmickMessage(1,"Opening SQLite database '"<<GetFileName()
257 <<"' ... OK"<<std::endl);
260 //=====================================================================
262 //=====================================================================
263 bool SQLiteTreeHandler::DBCreate()
265 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
266 <<"' ... "<<std::endl);
268 if (boost::filesystem::exists(GetFileName()))
270 GimmickError(GetFileName()<<"' : "
271 << "file already exists");
278 mDB->open(GetFileName().c_str());
280 catch (CppSQLite3Exception& e)
282 GimmickError(e.errorCode() << ":"
283 << e.errorMessage() <<std::endl);
291 // Create LEVELS table
292 command = "create table LEVELS\n";
293 command += "( Name text )\n";
296 // Iterate the Levels
297 for (int l=0; l<GetTree().GetNumberOfLevels(); ++l)
299 command = "INSERT INTO LEVELS (Name) VALUES ('";
300 command += GetTree().GetLevelDescriptor(l).GetName();
304 // Create table of level (for level>0, i.e. not Root)
307 command = "CREATE TABLE ";
308 command += GetTree().GetLevelDescriptor(l).GetName();
309 command += "\n(\nID INTEGER PRIMARY KEY";
312 command += ",\nPARENT_ID int not null";
314 SQLAppendAttributesDefinition(l,command);
317 command += ",\nconstraint FK_PARENT foreign key (PARENT_ID) references ";
318 command += GetTree().GetLevelDescriptor(l-1).GetName();
319 command += "(ID) on delete restrict on update restrict";
325 // Add Attribute 'ID' to Description
326 GetTree().GetLevelDescriptor(l).Add
327 (AttributeDescriptor( "ID",
328 "Database Identifier",
330 AttributeDescriptor::PRIVATE
335 // Add Attribute 'PARENT_ID' to Description
336 GetTree().GetLevelDescriptor(l).Add
337 (AttributeDescriptor( "PARENT_ID",
338 "Database Parent Identifier",
340 AttributeDescriptor::PRIVATE
346 // Create table *_ATTRIBUTES
348 command = "CREATE TABLE ";
349 command += GetTree().GetLevelDescriptor(l).GetName();
350 command += "_Attributes\n(\n";
351 command += "Key text,\n";
352 command += "Name text,\n";
353 command += "DicomGroup int,\n";
354 command += "DicomElement int,\n";
355 command += "Flags int\n";
360 // Fill the table *_ATTRIBUTES
361 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
362 for (i = GetTree().GetAttributeDescriptorList(l).begin();
363 i != GetTree().GetAttributeDescriptorList(l).end();
367 std::stringstream insert;
368 insert << "INSERT INTO "
369 << GetTree().GetLevelDescriptor(l).GetName()
370 << "_Attributes (Key,Name,DicomGroup,DicomElement,Flags) "
372 << i->GetKey() << "','"
373 << i->GetName() << "',"
374 << i->GetGroup() << ","
375 << i->GetElement() << ","
376 << i->GetFlags() << ");";
378 UPDATEDB(insert.str());
383 // Initialize the root attributes
384 GetTree().InitializeAttributeMap();
385 // Insert the root in the level 0 table
386 DBInsert(GetTree().GetTree());
389 GetTree().SetChildrenLoaded(true);
390 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
391 <<"' ... OK"<<std::endl);
394 //=====================================================================
396 //=====================================================================
397 void SQLiteTreeHandler::SQLAppendAttributesDefinition(int level,
400 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
401 for (i = GetTree().GetAttributeDescriptorList(level).begin();
402 i != GetTree().GetAttributeDescriptorList(level).end();
405 // if (i->second.flags==1) continue;
411 //=====================================================================
414 //=====================================================================
415 bool SQLiteTreeHandler::DBImportTreeDescription()
417 GimmickMessage(1,"Importing tree description from database ..."
420 // Test table 'LEVELS' existence
421 if ( ! mDB->tableExists("LEVELS") )
423 GimmickMessage(1,"!! ERROR : Table 'LEVELS' does not exist"
428 tree::Descriptor& desc = GetTree().GetDescriptor();
429 // clears the existing one
430 desc.GetLevelDescriptorList().clear();
433 std::string query = "SELECT * FROM LEVELS";
439 std::string name = q.getStringField(0);
440 GimmickMessage(2," * Importing level '"<<name<<"'"<<std::endl);
441 desc.GetLevelDescriptorList().push_back(LevelDescriptor(name));
446 for (int level = 0; level < nblevel; ++level )
448 std::string table = GetTree().GetLevelDescriptor(level).GetName();
449 table += "_Attributes";
450 // Test table 'LEVELS' existence
451 if ( ! mDB->tableExists(table.c_str()) )
453 GimmickMessage(1,"!! ERROR : Table '"<<table<<"' does not exist"
458 std::string query = "SELECT * FROM ";
463 GimmickMessage(2," * Level '"
464 <<GetTree().GetLevelDescriptor(level).GetName()
467 // Test that ID and PARENT_ID mandatory attributes exist
468 bool ID_found = false;
469 bool PARENT_ID_found = false;
470 if (level==0) ID_found = true;
471 if (level<=1) PARENT_ID_found = true;
475 std::string key(q.getStringField(0));
476 std::string name(q.getStringField(1));
477 GimmickMessage(2," - Importing attribute '"<<key<<"' '"<<name
479 desc.GetLevelDescriptor(level).Add
480 (AttributeDescriptor( key, // Key
482 q.getIntField(2), // Group
483 q.getIntField(3), // Element
484 q.getIntField(4) // Flags
490 if ( key == "PARENT_ID" )
492 PARENT_ID_found = true;
497 if ( ! (ID_found || PARENT_ID_found ) )
499 GimmickMessage(1,"!! ERROR : Table '"<<table
500 <<"' does not contain mandatory attribute ID or PARENT_ID"
508 // Create the attributes table for Root (i.e. Tree)
509 LevelDescriptor::AttributeDescriptorListType::const_iterator a;
510 for (a = GetTree().GetAttributeDescriptorList(0).begin();
511 a!= GetTree().GetAttributeDescriptorList(0).end();
516 AttributeMapType::const_iterator i = attr.find(a->GetKey());
517 if ( i != attr.end() )
522 GetTree().UnsafeSetAttribute( a->GetKey(), "" );
525 // Reading Root attributes
527 query = "SELECT * FROM ";
528 query += GetTree().GetLevelDescriptor(0).GetName();
531 for (int fld = 0; fld < q.numFields(); fld++)
533 GetTree().UnsafeSetAttribute(q.fieldName(fld),
534 q.getStringField(fld));
537 GimmickMessage(1,"Importing tree description from database ... OK"
541 //=====================================================================
559 //========================================================================
561 std::string& SQLformat(std::string& str)
563 // quote must be doubled
564 boost::algorithm::replace_all(str,"'","''");
565 // Found strange strings which contained NULL char INSIDE string
566 int i,size=str.size();
571 str = str.substr(0,i);
578 //========================================================================
580 //=====================================================================
581 void SQLiteTreeHandler::SQLAppendAttributesValues(tree::Node* n,
584 GimmickMessage(4,"SQLAppendAttributesValues"<<std::endl);
586 std::string values="";
587 tree::Node::AttributeMapType::iterator i;
588 for (i = n->GetAttributeMap().begin();
589 i != n->GetAttributeMap().end();
596 // std::cout << "("<<i->first<<","<<i->second<<")"<<std::endl;
597 atts += "'" + i->first + "'";
598 values += "'" + SQLformat(i->second) + "'";
601 GimmickMessage(4,"'"<<i->first<<"' = '"<<i->second<<"'"<<std::endl);
603 atts[atts.size()-1]=' ';
604 values[values.size()-1]=' ';
606 str = "("+atts+") VALUES ("+values+")";
607 GimmickMessage(4,"Result = '"<<str<<"'"<<std::endl);
609 //=====================================================================
611 //=====================================================================
612 tree::Node* SQLiteTreeHandler::DBGetParent( const AttributeMapType& attr)
614 Node* parent = GetTree().GetTree();
619 // Load the children of the current parent
620 DBLoadChildren(parent);
621 // Iterate the children
622 tree::Node::ChildrenListType::const_iterator i;
623 for (i = parent->GetChildrenList().begin();
624 i!= parent->GetChildrenList().end();
627 if ( (*i)->Matches( attr ) )
638 //=====================================================================
641 //=====================================================================
642 int SQLiteTreeHandler::DBLoadChildren(tree::Node* node,
645 if (node->GetLevel()+1 >= node->GetTree()->GetNumberOfLevels() )
648 GimmickMessage(2,"Loading children of '"<<node->GetLabel()
652 // If children loaded we do not have to do it but we need to recurse
653 // in order to load the children's children if necessary, and so on...
654 if (node->GetChildrenLoaded())
656 // Iterate the children
657 tree::Node::ChildrenListType::iterator i;
658 for (i = node->GetChildrenList().begin();
659 i!= node->GetChildrenList().end();
662 nbloaded += DBLoadChildren(*i,numberoflevels-1);
667 /// If children not loaded : do it and recurse
670 int level = node->GetLevel();
671 std::string query = "SELECT * FROM ";
672 query += GetTree().GetLevelDescriptor(level+1).GetName();
675 query += " WHERE PARENT_ID='" + node->UnsafeGetAttribute("ID")
684 Node* n = new Node(node);
685 for (int fld = 0; fld < q.numFields(); fld++)
687 n->UnsafeSetAttribute(q.fieldName(fld),q.getStringField(fld));
693 ti.id = n->GetFieldValue("ID");
694 mTypeIdToNodeMap[ti] = n;
697 if ( numberoflevels != 1 )
700 nbloaded += DBLoadChildren(n, numberoflevels-1);
707 node->SetChildrenLoaded(true);
712 //=====================================================================
714 //======================================================================
715 void SQLiteTreeHandler::DBInsert(tree::Node* n)
717 GimmickMessage(2,"Inserting in DB '"<<n->GetLabel()
720 SQLAppendAttributesValues(n,val);
721 std::string insert("INSERT INTO ");
722 insert += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
723 insert += " " + val + ";";
726 // Store DB id of newly created node;
727 long lastrow = mDB->lastRowId();
728 std::stringstream ri;
729 ri << mDB->lastRowId();
730 n->SetAttribute("ID",ri.str());
732 //======================================================================
734 //======================================================================
735 /// Graft the branch defined by the attributes to the parent
736 void SQLiteTreeHandler::DBGraftToParent( tree::Node* parent,
737 const AttributeMapType& attr)
739 GimmickMessage(2,"Grafting to parent '"<<parent->GetLabel()
742 for (int level = parent->GetLevel()+1;
743 level < GetTree().GetNumberOfLevels();
747 tree::Node* child = new tree::Node(parent,attr);
749 // Set PARENT_ID if necessary
750 if ( parent->GetLevel()>0 )
751 child->SetAttribute("PARENT_ID",parent->GetAttribute("ID"));
757 SQLAppendAttributesValues(child,val);
758 std::string insert("INSERT INTO ");
759 insert += GetTree().GetLevelDescriptor(child->GetLevel()).GetName();
760 insert += " " + val + ";";
763 // Store DB id of newly created node;
764 long lastrow = mDB->lastRowId();
765 std::stringstream ri;
766 ri << mDB->lastRowId();
767 child->SetAttribute("ID",ri.str());
773 // Insert in TypeId map
775 ti.type = node->GetType();
777 mTypeIdToNodeMap[ti] = node;
778 // std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl;
782 if (node->GetType()==Node::Patient) summary.added_patients++;
783 if (node->GetType()==Node::Study) summary.added_studies++;
784 if (node->GetType()==Node::Series) summary.added_series++;
785 if (node->GetType()==Node::Image) summary.added_images++;
789 //======================================================================
792 //=====================================================================
793 /// Sets an attribute of a Node
794 bool SQLiteTreeHandler::DBSetAttribute(tree::Node* n,
795 const std::string& key,
796 const std::string& value)
798 GimmickMessage(3,"Setting Attribute of '"<<n->GetLabel()<<
799 "' "<<key<<"='"<<value<<"'"<<std::endl);
801 n->SetAttribute(key,value);
802 std::string sql = "UPDATE ";
803 sql += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
808 sql += "' WHERE ID=";
809 sql += n->GetAttribute("ID");
810 // sql += " LIMIT 1";
813 //=====================================================================
816 //=====================================================================
817 bool SQLiteTreeHandler::DBInsert(Node* alien_node,
818 UpdateSummary& summary)
820 // std::cout << "SQLiteTreeHandler::Insert('"<<alien_node->GetLabel()
821 // <<"')"<<std::endl;
823 // if (!ChildrenLoaded()) DBLoadChildren(this,Node::Database);
827 std::string parent_id;
828 parent = DBGetOrCreateParent(alien_node,parent_id,summary);
831 DBRecursiveGetOrCreateNode(alien_node,parent,parent_id,summary);
834 //=====================================================================
837 //=====================================================================
838 Node* SQLiteTreeHandler::DBGetOrCreateParent(Node* alien_node,
839 std::string& parent_id,
840 UpdateSummary& summary)
842 // std::cout << "DBGetOrCreateParent '" << alien_node->GetLabel()<<"'"
844 // Load the patients if not already done
845 DBLoadChildren(this,Node::Patient);
850 // The chain of ancestors
851 std::deque<Node*> chain;
852 Node* cur = alien_node->GetParent();
853 for (int type=Node::Patient;
854 type<alien_node->GetType();++type)
856 chain.push_front(cur);
857 cur = cur->GetParent();
860 // create the nodes if do not exist
861 std::deque<Node*>::iterator i;
862 for (i=chain.begin();i!=chain.end();++i)
864 // std::cout << " cur = '"<<(*i)->GetLabel()<<"'"<<std::endl;
865 // std::string cur_id = DBGetNodeId(*i,parent_id);
866 // if (cur_id.size()==0)
868 // Node does not exist : create it
870 parent = DBGetOrCreateNode(*i,
876 DBLoadChildren(parent,parent->GetType()+1);
882 //=====================================================================
886 //=====================================================================
887 void SQLiteTreeHandler::DBRecursiveGetOrCreateNode(Node* alien_node,
889 const std::string& parent_id,
890 UpdateSummary& summary)
892 // std::cout << "SQLiteTreeHandler::RecursiveGetOrCreateNode('"
893 // <<alien_node->GetLabel()
894 // <<"','"<<parent<<"','"<<parent_id<<"')"<<std::endl;
897 // std::cout << " -- Parent = '"<<parent->GetLabel()<<"'"<<std::endl;
900 Node* new_node = DBGetOrCreateNode(alien_node,
905 Node::ChildrenListType::iterator i;
906 for (i = alien_node->GetChildrenList().begin();
907 i != alien_node->GetChildrenList().end();
910 DBRecursiveGetOrCreateNode((*i),new_node,new_id,summary);
913 //=====================================================================
916 //=====================================================================
917 Node* SQLiteTreeHandler::DBGetOrCreateNode(Node* alien_node,
918 Node* internal_parent,
919 std::string parent_id,
920 std::string& node_id,
921 UpdateSummary& summary)
923 // std::cout << "DBGetOrCreateNode('"<<alien_node->GetLabel()<<"','"
924 // << internal_parent << "','"<< parent_id<<"')"<<std::endl;
925 if (internal_parent != 0)
927 // std::cout << " -- Parent = '"<<internal_parent->GetLabel()<<"'"<<std::endl;
929 // Node Exists ? return it
930 // First try among children of internal parent
931 Node* node = GetChildrenLike(internal_parent,alien_node);
934 node_id = node->UnsafeGetFieldValue("ID");
937 // Second : try in DB
939 // Does not exist : Create new one
940 node = new Node(alien_node->GetType(),this,internal_parent);
941 node->SetChildrenLoaded(true);
942 // Copy fields values from alien
943 Node::FieldValueMapType::iterator i,j;
944 for (i = node->GetFieldValueMap().begin();
945 i != node->GetFieldValueMap().end();
948 j = alien_node->GetFieldValueMap().find(i->first);
949 if (j != alien_node->GetFieldValueMap().end() )
951 i->second = j->second;
956 if (node->GetType()!=Node::Patient)
957 node->SetFieldValue("PARENT_ID",parent_id);
961 BuildSQLFieldsValues(node,val);
962 std::string insert("INSERT INTO ");
963 insert += std::string(SQLiteTreeHandlerStructure::Table(node->GetType()))
965 // std::cout << "** SQL = '"<<insert<<"'"<<std::endl;
967 // std::cout << "** SQL OK"<<std::endl;
969 // Store DB id of newly created node;
970 long lastrow = mDB->lastRowId();
971 std::stringstream ri;
972 ri << mDB->lastRowId();
974 // std::cout << "LastRowId='"<<mDB->lastRowId()<<"' vs '"<<created_id<<"'"<<std::endl;
976 node->SetFieldValue("ID",node_id);
977 // Insert in TypeId map
979 ti.type = node->GetType();
981 mTypeIdToNodeMap[ti] = node;
982 // std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl;
986 if (node->GetType()==Node::Patient) summary.added_patients++;
987 if (node->GetType()==Node::Study) summary.added_studies++;
988 if (node->GetType()==Node::Series) summary.added_series++;
989 if (node->GetType()==Node::Image) summary.added_images++;
993 //=====================================================================
995 //=====================================================================
996 Node* SQLiteTreeHandler::GetChildrenLike(Node* parent,
999 Node::ChildrenListType::iterator i;
1000 for (i = parent->GetChildrenList().begin();
1001 i != parent->GetChildrenList().end();
1004 Node::Type type = alien_node->GetType();
1007 j<SQLiteTreeHandlerStructure::NbQueryFields(type);
1011 alien_node->GetFieldValue(SQLiteTreeHandlerStructure::
1012 QueryField(type,j).key ) !=
1013 (*i)->GetFieldValue(SQLiteTreeHandlerStructure::
1014 QueryField(type,j).key ) )
1027 //=====================================================================
1029 //=====================================================================
1030 std::string SQLiteTreeHandler::DBGetNodeId(Node* node,
1031 const std::string& parent_id)
1033 // std::cout << "SQLiteTreeHandler::DBGetNodeId('"<<node->GetLabel()
1034 // <<"','"<<parent_id<<"')"
1037 int type = node->GetType();
1039 std::string table = SQLiteTreeHandlerStructure::Table(type);
1040 std::string where = "WHERE ";
1042 if (type!=Node::Patient)
1044 where += "PARENT_ID='" + parent_id
1045 //node->GetFieldValue("PARENT_ID")
1049 for (int i=0;i<SQLiteTreeHandlerStructure::NbQueryFields(type);i++)
1051 where += SQLiteTreeHandlerStructure::QueryField(type,i).key + "='"
1052 + node->GetFieldValue(SQLiteTreeHandlerStructure::QueryField(type,i).key) + "' ";
1053 if (i<SQLiteTreeHandlerStructure::NbQueryFields(type)-1)
1057 std::string query = "SELECT ID FROM " + table + " " + where + ";";
1058 // std::cout << "** SQL = '"<<query<<"'"<<std::endl;
1065 // std::cout << " - Node exists " << std::endl;
1066 std::string id = q.getStringField(0);
1067 // std::cout << " id = '"<<id<<"'"<<std::endl;
1074 //=====================================================================
1078 //=====================================================================
1079 Node* SQLiteTreeHandler::GetNodeFromTypeId(Node::Type type,
1080 const std::string& id)
1082 // std::cout << "GetNodeFromTypeId("<<type<<","<<id<<")"<<std::endl;
1088 TypeIdToNodeMapType::iterator i = mTypeIdToNodeMap.find(ti);
1089 if (i == mTypeIdToNodeMap.end())
1092 std::cout << "Internal error : mTypeIdToNodeMap does not contain key"
1094 creaError("Internal error : mTypeIdToNodeMap does not contain key");
1098 // std::cout << " ** Node = "<<i->second<<std::endl;
1101 //=====================================================================
1103 //=====================================================================
1104 bool SQLiteTreeHandler::Remove(Node* node)
1106 DBRecursiveRemoveNode(node);
1108 // std::cout << "DELETE"<<std::endl;
1109 if (node->GetParent())
1111 node->GetParent()->RemoveChildrenFromList(node);
1114 // std::cout << "DELETE OK"<<std::endl;
1117 //========================================================================
1119 //=====================================================================
1120 void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
1122 // std::cout << "SQLiteTreeHandler::DBRecursiveRemoveNode('"
1123 // <<node->GetLabel()<<"')"<<std::endl;
1125 std::string query = "DELETE FROM ";
1126 query += SQLiteTreeHandlerStructure::Table(node->GetType());
1127 query += " WHERE ID='"+ node->GetFieldValue("ID") + "';";
1131 Node::ChildrenListType::iterator i;
1132 for (i = node->GetChildrenList().begin();
1133 i != node->GetChildrenList().end();
1136 DBRecursiveRemoveNode((*i));
1139 //=====================================================================
1141 //=====================================================================
1142 int SQLiteTreeHandler::DBQueryNumberOfChildren(Node* node)
1144 std::string query = "SELECT COUNT (ID) FROM ";
1145 query += SQLiteTreeHandlerStructure::Table(node->GetType()+1);
1146 if (node->GetType() != Node::Database)
1148 query += " WHERE PARENT_ID='"+ node->GetFieldValue("ID")+"'";
1152 // std::cout << "**SQL = "<< query << std::endl;
1157 // std::cout << "**RES = "<< q.getIntField(0) <<std::endl;
1159 return q.getIntField(0);
1161 //=====================================================================
1169 } // namespace creaImageIO