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;
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()
111 //=====================================================================
113 //=====================================================================
114 int SQLiteTreeHandler::LoadChildren(tree::Node* parent, int maxlevel)
116 if (parent==0) parent = GetTree().GetTree();
117 return DBLoadChildren(parent,maxlevel);
119 //=====================================================================
124 //=====================================================================
125 void SQLiteTreeHandler::UnLoad(tree::Node* n)
128 //=====================================================================
130 //=====================================================================
131 int SQLiteTreeHandler::AddBranch( const AttributeMapType& attr )
134 tree::Node* parent = DBGetParent(attr);
135 DBGraftToParent(parent,attr);
137 return (parent->GetLevel()+1);
140 //=====================================================================
143 //=====================================================================
144 bool SQLiteTreeHandler::Remove(tree::Node* node)
146 DBRecursiveRemoveNode(node);
148 // std::cout << "DELETE"<<std::endl;
149 if (node->GetParent())
151 node->GetParent()->RemoveChildrenFromList(node);
154 // std::cout << "DELETE OK"<<std::endl;
158 //========================================================================
162 //=====================================================================
164 //=====================================================================
165 /// Sets an attribute of a Node
166 bool SQLiteTreeHandler::SetAttribute(tree::Node* n,
167 const std::string& key,
168 const std::string& value)
170 if (n==0) n=GetTree().GetTree();
171 return DBSetAttribute(n,key,value);
173 //=====================================================================
187 //=====================================================================
188 // SQLite DB specific methods
189 //=====================================================================
194 //=====================================================================
195 char* format_sql(const std::string& s)
197 return sqlite3_mprintf("%q",s.c_str());
199 //=====================================================================
201 // sqlite3_exec(db, zSQL, 0, 0, 0);
202 // sqlite3_free(zSQL);
203 // char* CHAIN = format_sql(QUER); \
204 // sqlite3_free(CHAIN); \
206 //=====================================================================
207 #define QUERYDB(QUER,RES) \
210 GimmickMessage(2,"SQL query: '"<<QUER<<"'"<<std::endl); \
211 RES = mDB->execQuery(QUER.c_str()); \
213 catch (CppSQLite3Exception& e) \
215 GimmickError("SQLite query '"<<QUER<<"' : " \
216 << e.errorCode() << ":" \
217 << e.errorMessage() ); \
220 //=====================================================================
222 //=====================================================================
223 #define UPDATEDB(UP) \
226 GimmickMessage(2,"SQL update: '"<<UP<<"'"<<std::endl); \
227 mDB->execDML(UP.c_str()); \
229 catch (CppSQLite3Exception& e) \
231 GimmickError("SQLite update '"<<UP<<"' Error : " \
232 << e.errorCode() << ":" \
233 << e.errorMessage() ); \
235 //=====================================================================
238 //=====================================================================
239 bool SQLiteTreeHandler::DBOpen()
241 GimmickMessage(1,"Opening SQLite database '"<<GetFileName()
242 <<"' ... "<<std::endl);
244 if (!boost::filesystem::exists(GetFileName()))
251 mDB->open(GetFileName().c_str());
253 catch (CppSQLite3Exception& e)
255 GimmickError("Opening '"<<GetFileName()<<"' : "
256 << e.errorCode() << ":"
257 << e.errorMessage());
260 // IMPORT TREE DESCRIPTION (AND TEST DB VALIDITY)
261 if (!DBImportTreeDescription())
266 GimmickDebugMessage(1,"Opening SQLite database '"<<GetFileName()
267 <<"' ... OK"<<std::endl);
270 //=====================================================================
272 //=====================================================================
273 bool SQLiteTreeHandler::DBCreate()
275 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
276 <<"' ... "<<std::endl);
278 if (boost::filesystem::exists(GetFileName()))
280 GimmickError(GetFileName()<<"' : "
281 << "file already exists");
288 mDB->open(GetFileName().c_str());
290 catch (CppSQLite3Exception& e)
292 GimmickError(e.errorCode() << ":"
293 << e.errorMessage() <<std::endl);
301 // Create LEVELS table
302 command = "create table LEVELS\n";
303 command += "( Name text )\n";
306 // Iterate the Levels
307 for (int l=0; l<GetTree().GetNumberOfLevels(); ++l)
309 command = "INSERT INTO LEVELS (Name) VALUES ('";
310 command += GetTree().GetLevelDescriptor(l).GetName();
314 // Create table of level (for level>0, i.e. not Root)
317 command = "CREATE TABLE ";
318 command += GetTree().GetLevelDescriptor(l).GetName();
319 command += "\n(\nID INTEGER PRIMARY KEY";
322 command += ",\nPARENT_ID int not null";
324 SQLAppendAttributesDefinition(l,command);
327 command += ",\nconstraint FK_PARENT foreign key (PARENT_ID) references ";
328 command += GetTree().GetLevelDescriptor(l-1).GetName();
329 command += "(ID) on delete restrict on update restrict";
335 // Add Attribute 'ID' to Description
336 GetTree().GetDescriptor().Add
337 (AttributeDescriptor( "ID",
338 "Database Identifier",
340 AttributeDescriptor::PRIVATE
345 // Add Attribute 'PARENT_ID' to Description
346 GetTree().GetDescriptor().Add
347 (AttributeDescriptor( "PARENT_ID",
348 "Database Parent Identifier",
350 AttributeDescriptor::PRIVATE
356 // Create table *_ATTRIBUTES
358 command = "CREATE TABLE ";
359 command += GetTree().GetLevelDescriptor(l).GetName();
360 command += "_Attributes\n(\n";
361 command += "Key text,\n";
362 command += "Name text,\n";
363 command += "DicomGroup int,\n";
364 command += "DicomElement int,\n";
365 command += "Flags int\n";
370 // Fill the table *_ATTRIBUTES
371 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
372 for (i = GetTree().GetAttributeDescriptorList(l).begin();
373 i != GetTree().GetAttributeDescriptorList(l).end();
377 std::stringstream insert;
378 insert << "INSERT INTO "
379 << GetTree().GetLevelDescriptor(l).GetName()
380 << "_Attributes (Key,Name,DicomGroup,DicomElement,Flags) "
382 << i->GetKey() << "','"
383 << i->GetName() << "',"
384 << i->GetGroup() << ","
385 << i->GetElement() << ","
386 << i->GetFlags() << ");";
387 UPDATEDB(insert.str());
392 // Initialize the root attributes
393 GetTree().InitializeAttributeMap();
394 // Insert the root in the level 0 table
395 DBInsert(GetTree().GetTree());
398 GetTree().SetChildrenLoaded(true);
399 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
400 <<"' ... OK"<<std::endl);
403 //=====================================================================
405 //=====================================================================
406 void SQLiteTreeHandler::SQLAppendAttributesDefinition(int level,
409 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
410 for (i = GetTree().GetAttributeDescriptorList(level).begin();
411 i != GetTree().GetAttributeDescriptorList(level).end();
414 // if (i->second.flags==1) continue;
420 //=====================================================================
423 //=====================================================================
424 bool SQLiteTreeHandler::DBImportTreeDescription()
426 GimmickMessage(1,"Importing tree description from database ..."
429 // Test table 'LEVELS' existence
430 if ( ! mDB->tableExists("LEVELS") )
432 GimmickMessage(1,"!! ERROR : Table 'LEVELS' does not exist"
437 tree::Descriptor& desc = GetTree().GetDescriptor();
438 // clears the existing one
442 std::string query = "SELECT * FROM LEVELS";
448 std::string name = q.getStringField(0);
449 GimmickMessage(2," * Importing level '"<<name<<"'"<<std::endl);
450 desc.Add(LevelDescriptor(name));
455 for (int level = 0; level < nblevel; ++level )
457 std::string table = GetTree().GetLevelDescriptor(level).GetName();
458 table += "_Attributes";
459 // Test table 'LEVELS' existence
460 if ( ! mDB->tableExists(table.c_str()) )
462 GimmickMessage(1,"!! ERROR : Table '"<<table<<"' does not exist"
467 std::string query = "SELECT * FROM ";
472 GimmickMessage(2," * Level '"
473 <<GetTree().GetLevelDescriptor(level).GetName()
476 // Test that ID and PARENT_ID mandatory attributes exist
477 bool ID_found = false;
478 bool PARENT_ID_found = false;
479 if (level==0) ID_found = true;
480 if (level<=1) PARENT_ID_found = true;
484 std::string key(q.getStringField(0));
485 std::string name(q.getStringField(1));
486 GimmickMessage(2," - Importing attribute '"<<key<<"' '"<<name
489 (AttributeDescriptor( key, // Key
491 q.getIntField(2), // Group
492 q.getIntField(3), // Element
493 q.getIntField(4) // Flags
499 if ( key == "PARENT_ID" )
501 PARENT_ID_found = true;
506 if ( ! (ID_found || PARENT_ID_found ) )
508 GimmickMessage(1,"!! ERROR : Table '"<<table
509 <<"' does not contain mandatory attribute ID or PARENT_ID"
517 // Create the attributes table for Root (i.e. Tree)
518 LevelDescriptor::AttributeDescriptorListType::const_iterator a;
519 for (a = GetTree().GetAttributeDescriptorList(0).begin();
520 a!= GetTree().GetAttributeDescriptorList(0).end();
525 AttributeMapType::const_iterator i = attr.find(a->GetKey());
526 if ( i != attr.end() )
531 GetTree().UnsafeSetAttribute( a->GetKey(), "" );
534 // Reading Root attributes
536 query = "SELECT * FROM ";
537 query += GetTree().GetLevelDescriptor(0).GetName();
540 for (int fld = 0; fld < q.numFields(); fld++)
542 GetTree().UnsafeSetAttribute(q.fieldName(fld),
543 q.getStringField(fld));
546 GimmickMessage(1,"Importing tree description from database ... OK"
550 //=====================================================================
568 //========================================================================
570 std::string& SQLformat(std::string& str)
572 // quote must be doubled
573 boost::algorithm::replace_all(str,"'","''");
574 // Found strange strings which contained NULL char INSIDE string
575 int i,size=str.size();
580 str = str.substr(0,i);
587 //========================================================================
589 //=====================================================================
590 void SQLiteTreeHandler::SQLAppendAttributesValues(tree::Node* n,
593 GimmickMessage(4,"SQLAppendAttributesValues"<<std::endl);
595 std::string values="";
596 tree::Node::AttributeMapType::iterator i;
597 for (i = n->GetAttributeMap().begin();
598 i != n->GetAttributeMap().end();
605 // std::cout << "("<<i->first<<","<<i->second<<")"<<std::endl;
606 atts += "'" + i->first + "'";
607 values += "'" + SQLformat(i->second) + "'";
610 GimmickMessage(4,"'"<<i->first<<"' = '"<<i->second<<"'"<<std::endl);
612 atts[atts.size()-1]=' ';
613 values[values.size()-1]=' ';
615 str = "("+atts+") VALUES ("+values+")";
616 GimmickMessage(4,"Result = '"<<str<<"'"<<std::endl);
618 //=====================================================================
620 //=====================================================================
621 tree::Node* SQLiteTreeHandler::DBGetParent( const AttributeMapType& attr)
623 Node* parent = GetTree().GetTree();
628 // Load the children of the current parent
629 DBLoadChildren(parent);
630 // Iterate the children
631 tree::Node::ChildrenListType::const_iterator i;
632 for (i = parent->GetChildrenList().begin();
633 i!= parent->GetChildrenList().end();
636 if ( (*i)->Matches( attr ) )
647 //=====================================================================
650 //=====================================================================
651 int SQLiteTreeHandler::DBLoadChildren(tree::Node* node,
654 if (node->GetLevel()+1 >= node->GetTree()->GetNumberOfLevels() )
657 GimmickMessage(2,"Loading children of '"<<node->GetLabel()
661 // If children loaded we do not have to do it but we need to recurse
662 // in order to load the children's children if necessary, and so on...
663 if (node->GetChildrenLoaded()||mIsAdding)
665 // Iterate the children
667 /*tree::Node::ChildrenListType::iterator i;
668 for (i = node->GetChildrenList().begin();
669 i!= node->GetChildrenList().end();
672 nbloaded += DBLoadChildren(*i,numberoflevels-1);
680 /// If children not loaded : do it and recurse
681 std::cout<<"Children are not loaded for node:"<<node->GetLabel()<<std::endl;
682 std::cout<<"Children are not loaded for node (pointer):"<<node<<std::endl;
685 int level = node->GetLevel();
686 std::string query = "SELECT * FROM ";
688 query += GetTree().GetLevelDescriptor(level+1).GetName();
691 query += " WHERE PARENT_ID='" + node->UnsafeGetAttribute("ID")
701 Node* n = new Node(node);
702 for (int fld = 0; fld < q.numFields(); fld++)
704 n->UnsafeSetAttribute(q.fieldName(fld),q.getStringField(fld));
710 ti.id = n->GetFieldValue("ID");
711 mTypeIdToNodeMap[ti] = n;
714 if ( numberoflevels != 1 )
717 nbloaded += DBLoadChildren(n, numberoflevels-1);
724 node->SetChildrenLoaded(true);
731 //=====================================================================
733 //======================================================================
734 void SQLiteTreeHandler::DBInsert(tree::Node* n)
736 GimmickMessage(2,"Inserting in DB '"<<n->GetLabel()
739 SQLAppendAttributesValues(n,val);
740 std::string insert("INSERT INTO ");
741 insert += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
742 insert += " " + val + ";";
746 // Store DB id of newly created node;
747 long lastrow = mDB->lastRowId();
748 std::stringstream ri;
749 ri << mDB->lastRowId();
750 n->SetAttribute("ID",ri.str());
752 //======================================================================
754 //======================================================================
755 /// Graft the branch defined by the attributes to the parent
756 void SQLiteTreeHandler::DBGraftToParent( tree::Node* parent,
757 const AttributeMapType& attr)
759 GimmickMessage(2,"Grafting to parent '"<<parent->GetLabel()
762 for (int level = parent->GetLevel()+1;
763 level < GetTree().GetNumberOfLevels();
767 tree::Node* child = new tree::Node(parent,attr);
768 std::cout<<"Number of children "<<parent->GetNumberOfChildren()<<std::endl;
769 // Set PARENT_ID if necessary
770 if ( parent->GetLevel()>0 )
771 child->SetAttribute("PARENT_ID",parent->GetAttribute("ID"));
777 SQLAppendAttributesValues(child,val);
778 std::string insert("INSERT INTO ");
779 insert += GetTree().GetLevelDescriptor(child->GetLevel()).GetName();
780 insert += " " + val + ";";
783 // Store DB id of newly created node;
784 long lastrow = mDB->lastRowId();
785 std::stringstream ri;
786 ri << mDB->lastRowId();
787 child->SetAttribute("ID",ri.str());
793 // Insert in TypeId map
795 ti.type = node->GetType();
797 mTypeIdToNodeMap[ti] = node;
798 // std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl;
802 if (node->GetType()==Node::Patient) summary.added_patients++;
803 if (node->GetType()==Node::Study) summary.added_studies++;
804 if (node->GetType()==Node::Series) summary.added_series++;
805 if (node->GetType()==Node::Image) summary.added_images++;
809 //======================================================================
812 //=====================================================================
813 /// Sets an attribute of a Node
814 bool SQLiteTreeHandler::DBSetAttribute(tree::Node* n,
815 const std::string& key,
816 const std::string& value)
818 GimmickMessage(3,"Setting Attribute of '"<<n->GetLabel()<<
819 "' "<<key<<"='"<<value<<"'"<<std::endl);
821 n->SetAttribute(key,value);
822 std::string sql = "UPDATE ";
823 sql += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
828 sql += "' WHERE ID=";
829 sql += n->GetAttribute("ID");
830 // sql += " LIMIT 1";
833 //=====================================================================
836 //=====================================================================
837 void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
840 std::string query = "DELETE FROM ";
842 query += GetTree().GetLevelDescriptor(node->GetLevel()).GetName();
843 query += " WHERE ID='"+ node->GetAttribute("ID") + "';";
846 GimmickDebugMessage(2,
848 <<node->GetLabel()<<"' with ID '"
849 <<node->GetAttribute("ID")
850 <<"' in level "<< GetTree().GetLevelDescriptor(node->GetLevel()).GetName()
853 Node::ChildrenListType::iterator i;
854 for (i = node->GetChildrenList().begin();
855 i != node->GetChildrenList().end();
858 DBRecursiveRemoveNode((*i));
862 //=====================================================================
863 unsigned int SQLiteTreeHandler::GetNumberOfChildren(tree::Node* n)
867 int level = n->GetLevel();
868 if(GetTree().GetNumberOfLevels()!=(level+1))
870 std::string query = "SELECT * FROM ";
871 query += GetTree().GetLevelDescriptor(level+1).GetName();
874 query += " WHERE PARENT_ID='" + n->UnsafeGetAttribute("ID")
892 //=====================================================================
893 bool SQLiteTreeHandler::DBInsert(Node* alien_node,
894 UpdateSummary& summary)
896 // std::cout << "SQLiteTreeHandler::Insert('"<<alien_node->GetLabel()
897 // <<"')"<<std::endl;
899 // if (!ChildrenLoaded()) DBLoadChildren(this,Node::Database);
903 std::string parent_id;
904 parent = DBGetOrCreateParent(alien_node,parent_id,summary);
907 DBRecursiveGetOrCreateNode(alien_node,parent,parent_id,summary);
910 //=====================================================================
913 //=====================================================================
914 Node* SQLiteTreeHandler::DBGetOrCreateParent(Node* alien_node,
915 std::string& parent_id,
916 UpdateSummary& summary)
918 // std::cout << "DBGetOrCreateParent '" << alien_node->GetLabel()<<"'"
920 // Load the patients if not already done
921 DBLoadChildren(this,Node::Patient);
926 // The chain of ancestors
927 std::deque<Node*> chain;
928 Node* cur = alien_node->GetParent();
929 for (int type=Node::Patient;
930 type<alien_node->GetType();++type)
932 chain.push_front(cur);
933 cur = cur->GetParent();
936 // create the nodes if do not exist
937 std::deque<Node*>::iterator i;
938 for (i=chain.begin();i!=chain.end();++i)
940 // std::cout << " cur = '"<<(*i)->GetLabel()<<"'"<<std::endl;
941 // std::string cur_id = DBGetNodeId(*i,parent_id);
942 // if (cur_id.size()==0)
944 // Node does not exist : create it
946 parent = DBGetOrCreateNode(*i,
952 DBLoadChildren(parent,parent->GetType()+1);
958 //=====================================================================
962 //=====================================================================
963 void SQLiteTreeHandler::DBRecursiveGetOrCreateNode(Node* alien_node,
965 const std::string& parent_id,
966 UpdateSummary& summary)
968 // std::cout << "SQLiteTreeHandler::RecursiveGetOrCreateNode('"
969 // <<alien_node->GetLabel()
970 // <<"','"<<parent<<"','"<<parent_id<<"')"<<std::endl;
973 // std::cout << " -- Parent = '"<<parent->GetLabel()<<"'"<<std::endl;
976 Node* new_node = DBGetOrCreateNode(alien_node,
981 Node::ChildrenListType::iterator i;
982 for (i = alien_node->GetChildrenList().begin();
983 i != alien_node->GetChildrenList().end();
986 DBRecursiveGetOrCreateNode((*i),new_node,new_id,summary);
989 //=====================================================================
992 //=====================================================================
993 Node* SQLiteTreeHandler::DBGetOrCreateNode(Node* alien_node,
994 Node* internal_parent,
995 std::string parent_id,
996 std::string& node_id,
997 UpdateSummary& summary)
999 // std::cout << "DBGetOrCreateNode('"<<alien_node->GetLabel()<<"','"
1000 // << internal_parent << "','"<< parent_id<<"')"<<std::endl;
1001 if (internal_parent != 0)
1003 // std::cout << " -- Parent = '"<<internal_parent->GetLabel()<<"'"<<std::endl;
1005 // Node Exists ? return it
1006 // First try among children of internal parent
1007 Node* node = GetChildrenLike(internal_parent,alien_node);
1010 node_id = node->UnsafeGetFieldValue("ID");
1013 // Second : try in DB
1015 // Does not exist : Create new one
1016 node = new Node(alien_node->GetType(),this,internal_parent);
1017 node->SetChildrenLoaded(true);
1018 // Copy fields values from alien
1019 Node::FieldValueMapType::iterator i,j;
1020 for (i = node->GetFieldValueMap().begin();
1021 i != node->GetFieldValueMap().end();
1024 j = alien_node->GetFieldValueMap().find(i->first);
1025 if (j != alien_node->GetFieldValueMap().end() )
1027 i->second = j->second;
1032 if (node->GetType()!=Node::Patient)
1033 node->SetFieldValue("PARENT_ID",parent_id);
1037 BuildSQLFieldsValues(node,val);
1038 std::string insert("INSERT INTO ");
1039 insert += std::string(SQLiteTreeHandlerStructure::Table(node->GetType()))
1041 // std::cout << "** SQL = '"<<insert<<"'"<<std::endl;
1043 // std::cout << "** SQL OK"<<std::endl;
1045 // Store DB id of newly created node;
1046 long lastrow = mDB->lastRowId();
1047 std::stringstream ri;
1048 ri << mDB->lastRowId();
1050 // std::cout << "LastRowId='"<<mDB->lastRowId()<<"' vs '"<<created_id<<"'"<<std::endl;
1052 node->SetFieldValue("ID",node_id);
1053 // Insert in TypeId map
1055 ti.type = node->GetType();
1057 mTypeIdToNodeMap[ti] = node;
1058 // std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl;
1062 if (node->GetType()==Node::Patient) summary.added_patients++;
1063 if (node->GetType()==Node::Study) summary.added_studies++;
1064 if (node->GetType()==Node::Series) summary.added_series++;
1065 if (node->GetType()==Node::Image) summary.added_images++;
1069 //=====================================================================
1071 //=====================================================================
1072 Node* SQLiteTreeHandler::GetChildrenLike(Node* parent,
1075 Node::ChildrenListType::iterator i;
1076 for (i = parent->GetChildrenList().begin();
1077 i != parent->GetChildrenList().end();
1080 Node::Type type = alien_node->GetType();
1083 j<SQLiteTreeHandlerStructure::NbQueryFields(type);
1087 alien_node->GetFieldValue(SQLiteTreeHandlerStructure::
1088 QueryField(type,j).key ) !=
1089 (*i)->GetFieldValue(SQLiteTreeHandlerStructure::
1090 QueryField(type,j).key ) )
1103 //=====================================================================
1105 //=====================================================================
1106 std::string SQLiteTreeHandler::DBGetNodeId(Node* node,
1107 const std::string& parent_id)
1109 // std::cout << "SQLiteTreeHandler::DBGetNodeId('"<<node->GetLabel()
1110 // <<"','"<<parent_id<<"')"
1113 int type = node->GetType();
1115 std::string table = SQLiteTreeHandlerStructure::Table(type);
1116 std::string where = "WHERE ";
1118 if (type!=Node::Patient)
1120 where += "PARENT_ID='" + parent_id
1121 //node->GetFieldValue("PARENT_ID")
1125 for (int i=0;i<SQLiteTreeHandlerStructure::NbQueryFields(type);i++)
1127 where += SQLiteTreeHandlerStructure::QueryField(type,i).key + "='"
1128 + node->GetFieldValue(SQLiteTreeHandlerStructure::QueryField(type,i).key) + "' ";
1129 if (i<SQLiteTreeHandlerStructure::NbQueryFields(type)-1)
1133 std::string query = "SELECT ID FROM " + table + " " + where + ";";
1134 // std::cout << "** SQL = '"<<query<<"'"<<std::endl;
1141 // std::cout << " - Node exists " << std::endl;
1142 std::string id = q.getStringField(0);
1143 // std::cout << " id = '"<<id<<"'"<<std::endl;
1150 //=====================================================================
1154 //=====================================================================
1155 Node* SQLiteTreeHandler::GetNodeFromTypeId(Node::Type type,
1156 const std::string& id)
1158 // std::cout << "GetNodeFromTypeId("<<type<<","<<id<<")"<<std::endl;
1164 TypeIdToNodeMapType::iterator i = mTypeIdToNodeMap.find(ti);
1165 if (i == mTypeIdToNodeMap.end())
1168 std::cout << "Internal error : mTypeIdToNodeMap does not contain key"
1170 creaError("Internal error : mTypeIdToNodeMap does not contain key");
1174 // std::cout << " ** Node = "<<i->second<<std::endl;
1178 //=====================================================================
1180 //=====================================================================
1181 bool SQLiteTreeHandler::Remove(Node* node)
1184 //DBRecursiveRemoveNode(node);
1186 // std::cout << "DELETE"<<std::endl;
1187 if (node->GetParent())
1189 node->GetParent()->RemoveChildrenFromList(node);
1192 // std::cout << "DELETE OK"<<std::endl;
1197 //========================================================================
1199 //=====================================================================
1200 void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
1202 // std::cout << "SQLiteTreeHandler::DBRecursiveRemoveNode('"
1203 // <<node->GetLabel()<<"')"<<std::endl;
1205 std::string query = "DELETE FROM ";
1206 query += SQLiteTreeHandlerStructure::Table(node->GetType());
1207 query += " WHERE ID='"+ node->GetFieldValue("ID") + "';";
1211 Node::ChildrenListType::iterator i;
1212 for (i = node->GetChildrenList().begin();
1213 i != node->GetChildrenList().end();
1216 DBRecursiveRemoveNode((*i));
1220 //=====================================================================
1222 //=====================================================================
1223 int SQLiteTreeHandler::DBQueryNumberOfChildren(Node* node)
1225 std::string query = "SELECT COUNT (ID) FROM ";
1226 query += SQLiteTreeHandlerStructure::Table(node->GetType()+1);
1227 if (node->GetType() != Node::Database)
1229 query += " WHERE PARENT_ID='"+ node->GetFieldValue("ID")+"'";
1233 // std::cout << "**SQL = "<< query << std::endl;
1238 // std::cout << "**RES = "<< q.getIntField(0) <<std::endl;
1240 return q.getIntField(0);
1242 //=====================================================================
1250 } // namespace creaImageIO