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 )
133 //std::cout << "AddBranch" << std::endl;
134 tree::Node* parent = DBGetParent(attr);
135 //std::cout << " parent = "<<parent->GetLabel()<<" level "<<parent->GetLevel()<<std::endl;
136 DBGraftToParent(parent,attr);
138 return (parent->GetLevel()+1);
141 //=====================================================================
144 //=====================================================================
145 bool SQLiteTreeHandler::Remove(tree::Node* node)
147 DBRecursiveRemoveNode(node);
149 // std::cout << "DELETE"<<std::endl;
150 if (node->GetParent())
152 node->GetParent()->RemoveChildrenFromList(node);
155 // std::cout << "DELETE OK"<<std::endl;
159 //========================================================================
163 //=====================================================================
165 //=====================================================================
166 /// Sets an attribute of a Node
167 bool SQLiteTreeHandler::SetAttribute(tree::Node* n,
168 const std::string& key,
169 const std::string& value)
171 if (n==0) n=GetTree().GetTree();
172 return DBSetAttribute(n,key,value);
174 //=====================================================================
188 //=====================================================================
189 // SQLite DB specific methods
190 //=====================================================================
195 //=====================================================================
196 char* format_sql(const std::string& s)
198 return sqlite3_mprintf("%q",s.c_str());
200 //=====================================================================
202 // sqlite3_exec(db, zSQL, 0, 0, 0);
203 // sqlite3_free(zSQL);
204 // char* CHAIN = format_sql(QUER); \
205 // sqlite3_free(CHAIN); \
207 //=====================================================================
208 #define QUERYDB(QUER,RES) \
211 GimmickMessage(2,"SQL query: '"<<QUER<<"'"<<std::endl); \
212 RES = mDB->execQuery(QUER.c_str()); \
214 catch (CppSQLite3Exception& e) \
216 GimmickError("SQLite query '"<<QUER<<"' : " \
217 << e.errorCode() << ":" \
218 << e.errorMessage() ); \
221 //=====================================================================
223 //=====================================================================
224 #define UPDATEDB(UP) \
227 GimmickMessage(2,"SQL update: '"<<UP<<"'"<<std::endl); \
228 mDB->execDML(UP.c_str()); \
230 catch (CppSQLite3Exception& e) \
232 GimmickError("SQLite update '"<<UP<<"' Error : " \
233 << e.errorCode() << ":" \
234 << e.errorMessage() ); \
236 //=====================================================================
239 //=====================================================================
240 bool SQLiteTreeHandler::DBOpen()
242 GimmickMessage(1,"Opening SQLite database '"<<GetFileName()
243 <<"' ... "<<std::endl);
245 if (!boost::filesystem::exists(GetFileName()))
252 mDB->open(GetFileName().c_str());
254 catch (CppSQLite3Exception& e)
256 GimmickError("Opening '"<<GetFileName()<<"' : "
257 << e.errorCode() << ":"
258 << e.errorMessage());
261 // IMPORT TREE DESCRIPTION (AND TEST DB VALIDITY)
262 if (!DBImportTreeDescription())
267 GimmickDebugMessage(1,"Opening SQLite database '"<<GetFileName()
268 <<"' ... OK"<<std::endl);
271 //=====================================================================
273 //=====================================================================
274 bool SQLiteTreeHandler::DBCreate()
276 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
277 <<"' ... "<<std::endl);
279 if (boost::filesystem::exists(GetFileName()))
281 GimmickError(GetFileName()<<"' : "
282 << "file already exists");
289 mDB->open(GetFileName().c_str());
291 catch (CppSQLite3Exception& e)
293 GimmickError(e.errorCode() << ":"
294 << e.errorMessage() <<std::endl);
302 // Create LEVELS table
303 command = "create table LEVELS\n";
304 command += "( Name text )\n";
307 // Iterate the Levels
308 for (int l=0; l<GetTree().GetNumberOfLevels(); ++l)
310 command = "INSERT INTO LEVELS (Name) VALUES ('";
311 command += GetTree().GetLevelDescriptor(l).GetName();
315 // Create table of level (for level>0, i.e. not Root)
318 command = "CREATE TABLE ";
319 command += GetTree().GetLevelDescriptor(l).GetName();
320 command += "\n(\nID INTEGER PRIMARY KEY";
323 command += ",\nPARENT_ID int not null";
325 SQLAppendAttributesDefinition(l,command);
328 command += ",\nconstraint FK_PARENT foreign key (PARENT_ID) references ";
329 command += GetTree().GetLevelDescriptor(l-1).GetName();
330 command += "(ID) on delete restrict on update restrict";
336 // Add Attribute 'ID' to Description
337 GetTree().GetDescriptor().Add
338 (AttributeDescriptor( "ID",
339 "Database Identifier",
341 AttributeDescriptor::PRIVATE
346 // Add Attribute 'PARENT_ID' to Description
347 GetTree().GetDescriptor().Add
348 (AttributeDescriptor( "PARENT_ID",
349 "Database Parent Identifier",
351 AttributeDescriptor::PRIVATE
357 // Create table *_ATTRIBUTES
359 command = "CREATE TABLE ";
360 command += GetTree().GetLevelDescriptor(l).GetName();
361 command += "_Attributes\n(\n";
362 command += "Key text,\n";
363 command += "Name text,\n";
364 command += "DicomGroup int,\n";
365 command += "DicomElement int,\n";
366 command += "Flags int\n";
371 // Fill the table *_ATTRIBUTES
372 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
373 for (i = GetTree().GetAttributeDescriptorList(l).begin();
374 i != GetTree().GetAttributeDescriptorList(l).end();
378 std::stringstream insert;
379 insert << "INSERT INTO "
380 << GetTree().GetLevelDescriptor(l).GetName()
381 << "_Attributes (Key,Name,DicomGroup,DicomElement,Flags) "
383 << i->GetKey() << "','"
384 << i->GetName() << "',"
385 << i->GetGroup() << ","
386 << i->GetElement() << ","
387 << i->GetFlags() << ");";
388 UPDATEDB(insert.str());
393 // Initialize the root attributes
394 GetTree().InitializeAttributeMap();
395 // Insert the root in the level 0 table
396 DBInsert(GetTree().GetTree());
399 GetTree().SetChildrenLoaded(true);
400 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
401 <<"' ... OK"<<std::endl);
404 //=====================================================================
406 //=====================================================================
407 void SQLiteTreeHandler::SQLAppendAttributesDefinition(int level,
410 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
411 for (i = GetTree().GetAttributeDescriptorList(level).begin();
412 i != GetTree().GetAttributeDescriptorList(level).end();
415 // if (i->second.flags==1) continue;
421 //=====================================================================
424 //=====================================================================
425 bool SQLiteTreeHandler::DBImportTreeDescription()
427 GimmickMessage(1,"Importing tree description from database ..."
430 // Test table 'LEVELS' existence
431 if ( ! mDB->tableExists("LEVELS") )
433 GimmickMessage(1,"!! ERROR : Table 'LEVELS' does not exist"
438 tree::Descriptor& desc = GetTree().GetDescriptor();
439 // clears the existing one
443 std::string query = "SELECT * FROM LEVELS";
449 std::string name = q.getStringField(0);
450 GimmickMessage(2," * Importing level '"<<name<<"'"<<std::endl);
451 desc.Add(LevelDescriptor(name));
456 for (int level = 0; level < nblevel; ++level )
458 std::string table = GetTree().GetLevelDescriptor(level).GetName();
459 table += "_Attributes";
460 // Test table 'LEVELS' existence
461 if ( ! mDB->tableExists(table.c_str()) )
463 GimmickMessage(1,"!! ERROR : Table '"<<table<<"' does not exist"
468 std::string query = "SELECT * FROM ";
473 GimmickMessage(2," * Level '"
474 <<GetTree().GetLevelDescriptor(level).GetName()
477 // Test that ID and PARENT_ID mandatory attributes exist
478 bool ID_found = false;
479 bool PARENT_ID_found = false;
480 if (level==0) ID_found = true;
481 if (level<=1) PARENT_ID_found = true;
485 std::string key(q.getStringField(0));
486 std::string name(q.getStringField(1));
487 GimmickMessage(2," - Importing attribute '"<<key<<"' '"<<name
490 (AttributeDescriptor( key, // Key
492 q.getIntField(2), // Group
493 q.getIntField(3), // Element
494 q.getIntField(4) // Flags
500 if ( key == "PARENT_ID" )
502 PARENT_ID_found = true;
507 if ( ! (ID_found || PARENT_ID_found ) )
509 GimmickMessage(1,"!! ERROR : Table '"<<table
510 <<"' does not contain mandatory attribute ID or PARENT_ID"
518 // Create the attributes table for Root (i.e. Tree)
519 LevelDescriptor::AttributeDescriptorListType::const_iterator a;
520 for (a = GetTree().GetAttributeDescriptorList(0).begin();
521 a!= GetTree().GetAttributeDescriptorList(0).end();
526 AttributeMapType::const_iterator i = attr.find(a->GetKey());
527 if ( i != attr.end() )
532 GetTree().UnsafeSetAttribute( a->GetKey(), "" );
535 // Reading Root attributes
537 query = "SELECT * FROM ";
538 query += GetTree().GetLevelDescriptor(0).GetName();
541 for (int fld = 0; fld < q.numFields(); fld++)
543 GetTree().UnsafeSetAttribute(q.fieldName(fld),
544 q.getStringField(fld));
547 GimmickMessage(1,"Importing tree description from database ... OK"
551 //=====================================================================
569 //========================================================================
571 std::string& SQLformat(std::string& str)
573 // quote must be doubled
574 boost::algorithm::replace_all(str,"'","''");
575 // Found strange strings which contained NULL char INSIDE string
576 int i,size=str.size();
581 str = str.substr(0,i);
588 //========================================================================
590 //=====================================================================
591 void SQLiteTreeHandler::SQLAppendAttributesValues(tree::Node* n,
594 GimmickMessage(4,"SQLAppendAttributesValues"<<std::endl);
596 std::string values="";
597 tree::Node::AttributeMapType::iterator i;
598 for (i = n->GetAttributeMap().begin();
599 i != n->GetAttributeMap().end();
606 // std::cout << "("<<i->first<<","<<i->second<<")"<<std::endl;
607 atts += "'" + i->first + "'";
608 values += "'" + SQLformat(i->second) + "'";
611 GimmickMessage(4,"'"<<i->first<<"' = '"<<i->second<<"'"<<std::endl);
613 atts[atts.size()-1]=' ';
614 values[values.size()-1]=' ';
616 str = "("+atts+") VALUES ("+values+")";
617 GimmickMessage(4,"Result = '"<<str<<"'"<<std::endl);
619 //=====================================================================
621 //=====================================================================
622 tree::Node* SQLiteTreeHandler::DBGetParent( const AttributeMapType& attr)
624 Node* parent = GetTree().GetTree();
629 // Load the children of the current parent
630 DBLoadChildren(parent);
631 // Iterate the children
632 tree::Node::ChildrenListType::const_iterator i;
633 for (i = parent->GetChildrenList().begin();
634 i!= parent->GetChildrenList().end();
637 if ( (*i)->Matches( attr ) )
648 //=====================================================================
651 //=====================================================================
652 int SQLiteTreeHandler::DBLoadChildren(tree::Node* node,
655 if (node->GetLevel()+1 >= node->GetTree()->GetNumberOfLevels() )
658 GimmickMessage(2,"Loading children of '"<<node->GetLabel()
662 // If children loaded we do not have to do it but we need to recurse
663 // in order to load the children's children if necessary, and so on...
664 if (node->GetChildrenLoaded()||mIsAdding)
666 // Iterate the children
668 tree::Node::ChildrenListType::iterator i;
669 for (i = node->GetChildrenList().begin();
670 i!= node->GetChildrenList().end();
673 nbloaded += DBLoadChildren(*i,numberoflevels-1);
675 node->SetChildrenLoaded(true);
681 /// If children not loaded : do it and recurse
684 int level = node->GetLevel();
685 std::string query = "SELECT * FROM ";
687 query += GetTree().GetLevelDescriptor(level+1).GetName();
690 query += " WHERE PARENT_ID='" + node->UnsafeGetAttribute("ID")
700 // std::cout << "DBLoadCh : creating node level "<<level+1<<std::endl;
703 Node* n = new Node(node);
704 for (int fld = 0; fld < q.numFields(); fld++)
706 n->UnsafeSetAttribute(q.fieldName(fld),q.getStringField(fld));
712 ti.id = n->GetFieldValue("ID");
713 mTypeIdToNodeMap[ti] = n;
716 if ( numberoflevels != 1 )
719 nbloaded += DBLoadChildren(n, numberoflevels-1);
726 node->SetChildrenLoaded(true);
733 //=====================================================================
735 //======================================================================
736 void SQLiteTreeHandler::DBInsert(tree::Node* n)
738 GimmickMessage(2,"Inserting in DB '"<<n->GetLabel()
741 SQLAppendAttributesValues(n,val);
742 std::string insert("INSERT INTO ");
743 insert += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
744 insert += " " + val + ";";
748 // Store DB id of newly created node;
749 long lastrow = mDB->lastRowId();
750 std::stringstream ri;
751 ri << mDB->lastRowId();
752 n->SetAttribute("ID",ri.str());
754 //======================================================================
756 //======================================================================
757 /// Graft the branch defined by the attributes to the parent
758 void SQLiteTreeHandler::DBGraftToParent( tree::Node* parent,
759 const AttributeMapType& attr)
761 // std::cout <<"Grafting to parent '"<<parent->GetLabel()
764 for (int level = parent->GetLevel()+1;
765 level < GetTree().GetNumberOfLevels();
769 tree::Node* child = new tree::Node(parent,attr);
770 child->SetChildrenLoaded(true);
771 // std::cout<<"Number of children "<<parent->GetNumberOfChildren()<<std::endl;
772 // Set PARENT_ID if necessary
773 if ( parent->GetLevel()>0 )
774 child->SetAttribute("PARENT_ID",parent->GetAttribute("ID"));
780 SQLAppendAttributesValues(child,val);
781 std::string insert("INSERT INTO ");
782 insert += GetTree().GetLevelDescriptor(child->GetLevel()).GetName();
783 insert += " " + val + ";";
786 // Store DB id of newly created node;
787 long lastrow = mDB->lastRowId();
788 std::stringstream ri;
789 ri << mDB->lastRowId();
790 child->SetAttribute("ID",ri.str());
796 // Insert in TypeId map
798 ti.type = node->GetType();
800 mTypeIdToNodeMap[ti] = node;
801 // std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl;
805 if (node->GetType()==Node::Patient) summary.added_patients++;
806 if (node->GetType()==Node::Study) summary.added_studies++;
807 if (node->GetType()==Node::Series) summary.added_series++;
808 if (node->GetType()==Node::Image) summary.added_images++;
812 //======================================================================
815 //=====================================================================
816 /// Sets an attribute of a Node
817 bool SQLiteTreeHandler::DBSetAttribute(tree::Node* n,
818 const std::string& key,
819 const std::string& value)
821 GimmickMessage(3,"Setting Attribute of '"<<n->GetLabel()<<
822 "' "<<key<<"='"<<value<<"'"<<std::endl);
824 n->SetAttribute(key,value);
825 std::string sql = "UPDATE ";
826 sql += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
831 sql += "' WHERE ID=";
832 sql += n->GetAttribute("ID");
833 // sql += " LIMIT 1";
836 //=====================================================================
839 //=====================================================================
840 void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
843 std::string query = "DELETE FROM ";
845 query += GetTree().GetLevelDescriptor(node->GetLevel()).GetName();
846 query += " WHERE ID='"+ node->GetAttribute("ID") + "';";
849 GimmickDebugMessage(2,
851 <<node->GetLabel()<<"' with ID '"
852 <<node->GetAttribute("ID")
853 <<"' in level "<< GetTree().GetLevelDescriptor(node->GetLevel()).GetName()
856 Node::ChildrenListType::iterator i;
857 for (i = node->GetChildrenList().begin();
858 i != node->GetChildrenList().end();
861 DBRecursiveRemoveNode((*i));
865 //=====================================================================
866 unsigned int SQLiteTreeHandler::GetNumberOfChildren(tree::Node* n)
870 int level = n->GetLevel();
871 if(GetTree().GetNumberOfLevels()!=(level+1))
873 std::string query = "SELECT * FROM ";
874 query += GetTree().GetLevelDescriptor(level+1).GetName();
877 query += " WHERE PARENT_ID='" + n->UnsafeGetAttribute("ID")
895 //=====================================================================
896 bool SQLiteTreeHandler::DBInsert(Node* alien_node,
897 UpdateSummary& summary)
899 // std::cout << "SQLiteTreeHandler::Insert('"<<alien_node->GetLabel()
900 // <<"')"<<std::endl;
902 // if (!ChildrenLoaded()) DBLoadChildren(this,Node::Database);
906 std::string parent_id;
907 parent = DBGetOrCreateParent(alien_node,parent_id,summary);
910 DBRecursiveGetOrCreateNode(alien_node,parent,parent_id,summary);
913 //=====================================================================
916 //=====================================================================
917 Node* SQLiteTreeHandler::DBGetOrCreateParent(Node* alien_node,
918 std::string& parent_id,
919 UpdateSummary& summary)
921 // std::cout << "DBGetOrCreateParent '" << alien_node->GetLabel()<<"'"
923 // Load the patients if not already done
924 DBLoadChildren(this,Node::Patient);
929 // The chain of ancestors
930 std::deque<Node*> chain;
931 Node* cur = alien_node->GetParent();
932 for (int type=Node::Patient;
933 type<alien_node->GetType();++type)
935 chain.push_front(cur);
936 cur = cur->GetParent();
939 // create the nodes if do not exist
940 std::deque<Node*>::iterator i;
941 for (i=chain.begin();i!=chain.end();++i)
943 // std::cout << " cur = '"<<(*i)->GetLabel()<<"'"<<std::endl;
944 // std::string cur_id = DBGetNodeId(*i,parent_id);
945 // if (cur_id.size()==0)
947 // Node does not exist : create it
949 parent = DBGetOrCreateNode(*i,
955 DBLoadChildren(parent,parent->GetType()+1);
961 //=====================================================================
965 //=====================================================================
966 void SQLiteTreeHandler::DBRecursiveGetOrCreateNode(Node* alien_node,
968 const std::string& parent_id,
969 UpdateSummary& summary)
971 // std::cout << "SQLiteTreeHandler::RecursiveGetOrCreateNode('"
972 // <<alien_node->GetLabel()
973 // <<"','"<<parent<<"','"<<parent_id<<"')"<<std::endl;
976 // std::cout << " -- Parent = '"<<parent->GetLabel()<<"'"<<std::endl;
979 Node* new_node = DBGetOrCreateNode(alien_node,
984 Node::ChildrenListType::iterator i;
985 for (i = alien_node->GetChildrenList().begin();
986 i != alien_node->GetChildrenList().end();
989 DBRecursiveGetOrCreateNode((*i),new_node,new_id,summary);
992 //=====================================================================
995 //=====================================================================
996 Node* SQLiteTreeHandler::DBGetOrCreateNode(Node* alien_node,
997 Node* internal_parent,
998 std::string parent_id,
999 std::string& node_id,
1000 UpdateSummary& summary)
1002 // std::cout << "DBGetOrCreateNode('"<<alien_node->GetLabel()<<"','"
1003 // << internal_parent << "','"<< parent_id<<"')"<<std::endl;
1004 if (internal_parent != 0)
1006 // std::cout << " -- Parent = '"<<internal_parent->GetLabel()<<"'"<<std::endl;
1008 // Node Exists ? return it
1009 // First try among children of internal parent
1010 Node* node = GetChildrenLike(internal_parent,alien_node);
1013 node_id = node->UnsafeGetFieldValue("ID");
1016 // Second : try in DB
1018 // Does not exist : Create new one
1019 node = new Node(alien_node->GetType(),this,internal_parent);
1020 node->SetChildrenLoaded(true);
1021 // Copy fields values from alien
1022 Node::FieldValueMapType::iterator i,j;
1023 for (i = node->GetFieldValueMap().begin();
1024 i != node->GetFieldValueMap().end();
1027 j = alien_node->GetFieldValueMap().find(i->first);
1028 if (j != alien_node->GetFieldValueMap().end() )
1030 i->second = j->second;
1035 if (node->GetType()!=Node::Patient)
1036 node->SetFieldValue("PARENT_ID",parent_id);
1040 BuildSQLFieldsValues(node,val);
1041 std::string insert("INSERT INTO ");
1042 insert += std::string(SQLiteTreeHandlerStructure::Table(node->GetType()))
1044 // std::cout << "** SQL = '"<<insert<<"'"<<std::endl;
1046 // std::cout << "** SQL OK"<<std::endl;
1048 // Store DB id of newly created node;
1049 long lastrow = mDB->lastRowId();
1050 std::stringstream ri;
1051 ri << mDB->lastRowId();
1053 // std::cout << "LastRowId='"<<mDB->lastRowId()<<"' vs '"<<created_id<<"'"<<std::endl;
1055 node->SetFieldValue("ID",node_id);
1056 // Insert in TypeId map
1058 ti.type = node->GetType();
1060 mTypeIdToNodeMap[ti] = node;
1061 // std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl;
1065 if (node->GetType()==Node::Patient) summary.added_patients++;
1066 if (node->GetType()==Node::Study) summary.added_studies++;
1067 if (node->GetType()==Node::Series) summary.added_series++;
1068 if (node->GetType()==Node::Image) summary.added_images++;
1072 //=====================================================================
1074 //=====================================================================
1075 Node* SQLiteTreeHandler::GetChildrenLike(Node* parent,
1078 Node::ChildrenListType::iterator i;
1079 for (i = parent->GetChildrenList().begin();
1080 i != parent->GetChildrenList().end();
1083 Node::Type type = alien_node->GetType();
1086 j<SQLiteTreeHandlerStructure::NbQueryFields(type);
1090 alien_node->GetFieldValue(SQLiteTreeHandlerStructure::
1091 QueryField(type,j).key ) !=
1092 (*i)->GetFieldValue(SQLiteTreeHandlerStructure::
1093 QueryField(type,j).key ) )
1106 //=====================================================================
1108 //=====================================================================
1109 std::string SQLiteTreeHandler::DBGetNodeId(Node* node,
1110 const std::string& parent_id)
1112 // std::cout << "SQLiteTreeHandler::DBGetNodeId('"<<node->GetLabel()
1113 // <<"','"<<parent_id<<"')"
1116 int type = node->GetType();
1118 std::string table = SQLiteTreeHandlerStructure::Table(type);
1119 std::string where = "WHERE ";
1121 if (type!=Node::Patient)
1123 where += "PARENT_ID='" + parent_id
1124 //node->GetFieldValue("PARENT_ID")
1128 for (int i=0;i<SQLiteTreeHandlerStructure::NbQueryFields(type);i++)
1130 where += SQLiteTreeHandlerStructure::QueryField(type,i).key + "='"
1131 + node->GetFieldValue(SQLiteTreeHandlerStructure::QueryField(type,i).key) + "' ";
1132 if (i<SQLiteTreeHandlerStructure::NbQueryFields(type)-1)
1136 std::string query = "SELECT ID FROM " + table + " " + where + ";";
1137 // std::cout << "** SQL = '"<<query<<"'"<<std::endl;
1144 // std::cout << " - Node exists " << std::endl;
1145 std::string id = q.getStringField(0);
1146 // std::cout << " id = '"<<id<<"'"<<std::endl;
1153 //=====================================================================
1157 //=====================================================================
1158 Node* SQLiteTreeHandler::GetNodeFromTypeId(Node::Type type,
1159 const std::string& id)
1161 // std::cout << "GetNodeFromTypeId("<<type<<","<<id<<")"<<std::endl;
1167 TypeIdToNodeMapType::iterator i = mTypeIdToNodeMap.find(ti);
1168 if (i == mTypeIdToNodeMap.end())
1171 std::cout << "Internal error : mTypeIdToNodeMap does not contain key"
1173 creaError("Internal error : mTypeIdToNodeMap does not contain key");
1177 // std::cout << " ** Node = "<<i->second<<std::endl;
1181 //=====================================================================
1183 //=====================================================================
1184 bool SQLiteTreeHandler::Remove(Node* node)
1187 //DBRecursiveRemoveNode(node);
1189 // std::cout << "DELETE"<<std::endl;
1190 if (node->GetParent())
1192 node->GetParent()->RemoveChildrenFromList(node);
1195 // std::cout << "DELETE OK"<<std::endl;
1200 //========================================================================
1202 //=====================================================================
1203 void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
1205 // std::cout << "SQLiteTreeHandler::DBRecursiveRemoveNode('"
1206 // <<node->GetLabel()<<"')"<<std::endl;
1208 std::string query = "DELETE FROM ";
1209 query += SQLiteTreeHandlerStructure::Table(node->GetType());
1210 query += " WHERE ID='"+ node->GetFieldValue("ID") + "';";
1214 Node::ChildrenListType::iterator i;
1215 for (i = node->GetChildrenList().begin();
1216 i != node->GetChildrenList().end();
1219 DBRecursiveRemoveNode((*i));
1223 //=====================================================================
1225 //=====================================================================
1226 int SQLiteTreeHandler::DBQueryNumberOfChildren(Node* node)
1228 std::string query = "SELECT COUNT (ID) FROM ";
1229 query += SQLiteTreeHandlerStructure::Table(node->GetType()+1);
1230 if (node->GetType() != Node::Database)
1232 query += " WHERE PARENT_ID='"+ node->GetFieldValue("ID")+"'";
1236 // std::cout << "**SQL = "<< query << std::endl;
1241 // std::cout << "**RES = "<< q.getIntField(0) <<std::endl;
1243 return q.getIntField(0);
1245 //=====================================================================
1253 } // namespace creaImageIO