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 tree::Node* parent = DBGetParent(attr);
134 DBGraftToParent(parent,attr);
135 if(parent->GetLevel()<GetTree().GetNumberOfLevels()-1&&parent->GetLevel()>0)
137 int nC=GetNumberOfChildren(parent);
139 std::stringstream out;
141 SetAttribute(parent,"D1111_0011",out.str());
143 return (parent->GetLevel()+1);
146 //=====================================================================
149 //=====================================================================
150 bool SQLiteTreeHandler::Remove(tree::Node* node)
152 DBRecursiveRemoveNode(node);
154 // std::cout << "DELETE"<<std::endl;
156 tree::Node* parent=node->GetParent();
159 parent->RemoveChildrenFromList(node);
160 int nC=GetNumberOfChildren(parent);
164 std::stringstream out;
166 SetAttribute(parent,"D1111_0011",out.str());
175 if(remove&&parent->GetLevel()>0)
179 // std::cout << "DELETE OK"<<std::endl;
183 //========================================================================
187 //=====================================================================
189 //=====================================================================
190 /// Sets an attribute of a Node
191 bool SQLiteTreeHandler::SetAttribute(tree::Node* n,
192 const std::string& key,
193 const std::string& value)
195 if (n==0) n=GetTree().GetTree();
196 return DBSetAttribute(n,key,value);
198 //=====================================================================
212 //=====================================================================
213 // SQLite DB specific methods
214 //=====================================================================
219 //=====================================================================
220 char* format_sql(const std::string& s)
222 return sqlite3_mprintf("%q",s.c_str());
224 //=====================================================================
226 // sqlite3_exec(db, zSQL, 0, 0, 0);
227 // sqlite3_free(zSQL);
228 // char* CHAIN = format_sql(QUER); \
229 // sqlite3_free(CHAIN); \
231 //=====================================================================
232 #define QUERYDB(QUER,RES) \
235 GimmickMessage(2,"SQL query: '"<<QUER<<"'"<<std::endl); \
236 RES = mDB->execQuery(QUER.c_str()); \
238 catch (CppSQLite3Exception& e) \
240 GimmickError("SQLite query '"<<QUER<<"' : " \
241 << e.errorCode() << ":" \
242 << e.errorMessage() ); \
245 //=====================================================================
247 //=====================================================================
248 #define UPDATEDB(UP) \
251 GimmickMessage(2,"SQL update: '"<<UP<<"'"<<std::endl); \
252 mDB->execDML(UP.c_str()); \
254 catch (CppSQLite3Exception& e) \
256 GimmickError("SQLite update '"<<UP<<"' Error : " \
257 << e.errorCode() << ":" \
258 << e.errorMessage() ); \
260 //=====================================================================
263 //=====================================================================
264 bool SQLiteTreeHandler::DBOpen()
266 GimmickMessage(1,"Opening SQLite database '"<<GetFileName()
267 <<"' ... "<<std::endl);
269 if (!boost::filesystem::exists(GetFileName()))
276 mDB->open(GetFileName().c_str());
278 catch (CppSQLite3Exception& e)
280 GimmickError("Opening '"<<GetFileName()<<"' : "
281 << e.errorCode() << ":"
282 << e.errorMessage());
285 // IMPORT TREE DESCRIPTION (AND TEST DB VALIDITY)
286 if (!DBImportTreeDescription())
291 GimmickDebugMessage(1,"Opening SQLite database '"<<GetFileName()
292 <<"' ... OK"<<std::endl);
295 //=====================================================================
297 //=====================================================================
298 bool SQLiteTreeHandler::DBCreate()
300 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
301 <<"' ... "<<std::endl);
303 if (boost::filesystem::exists(GetFileName()))
305 GimmickError(GetFileName()<<"' : "
306 << "file already exists");
313 mDB->open(GetFileName().c_str());
315 catch (CppSQLite3Exception& e)
317 GimmickError(e.errorCode() << ":"
318 << e.errorMessage() <<std::endl);
326 // Create LEVELS table
327 command = "create table LEVELS\n";
328 command += "( Name text )\n";
331 // Iterate the Levels
332 for (int l=0; l<GetTree().GetNumberOfLevels(); ++l)
334 command = "INSERT INTO LEVELS (Name) VALUES ('";
335 command += GetTree().GetLevelDescriptor(l).GetName();
339 // Create table of level (for level>0, i.e. not Root)
342 command = "CREATE TABLE ";
343 command += GetTree().GetLevelDescriptor(l).GetName();
344 command += "\n(\nID INTEGER PRIMARY KEY";
347 command += ",\nPARENT_ID int not null";
349 SQLAppendAttributesDefinition(l,command);
352 command += ",\nconstraint FK_PARENT foreign key (PARENT_ID) references ";
353 command += GetTree().GetLevelDescriptor(l-1).GetName();
354 command += "(ID) on delete restrict on update restrict";
360 // Add Attribute 'ID' to Description
361 GetTree().GetDescriptor().Add
362 (AttributeDescriptor( "ID",
363 "Database Identifier",
365 AttributeDescriptor::PRIVATE
370 // Add Attribute 'PARENT_ID' to Description
371 GetTree().GetDescriptor().Add
372 (AttributeDescriptor( "PARENT_ID",
373 "Database Parent Identifier",
375 AttributeDescriptor::PRIVATE
381 // Create table *_ATTRIBUTES
383 command = "CREATE TABLE ";
384 command += GetTree().GetLevelDescriptor(l).GetName();
385 command += "_Attributes\n(\n";
386 command += "Key text,\n";
387 command += "Name text,\n";
388 command += "DicomGroup int,\n";
389 command += "DicomElement int,\n";
390 command += "Flags int\n";
395 // Fill the table *_ATTRIBUTES
396 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
397 for (i = GetTree().GetAttributeDescriptorList(l).begin();
398 i != GetTree().GetAttributeDescriptorList(l).end();
402 std::stringstream insert;
403 insert << "INSERT INTO "
404 << GetTree().GetLevelDescriptor(l).GetName()
405 << "_Attributes (Key,Name,DicomGroup,DicomElement,Flags) "
407 << i->GetKey() << "','"
408 << i->GetName() << "',"
409 << i->GetGroup() << ","
410 << i->GetElement() << ","
411 << i->GetFlags() << ");";
412 UPDATEDB(insert.str());
417 // Initialize the root attributes
418 GetTree().InitializeAttributeMap();
419 // Insert the root in the level 0 table
420 DBInsert(GetTree().GetTree());
423 GetTree().SetChildrenLoaded(true);
424 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
425 <<"' ... OK"<<std::endl);
428 //=====================================================================
430 //=====================================================================
431 void SQLiteTreeHandler::SQLAppendAttributesDefinition(int level,
434 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
435 for (i = GetTree().GetAttributeDescriptorList(level).begin();
436 i != GetTree().GetAttributeDescriptorList(level).end();
439 // if (i->second.flags==1) continue;
445 //=====================================================================
448 //=====================================================================
449 bool SQLiteTreeHandler::DBImportTreeDescription()
451 GimmickMessage(1,"Importing tree description from database ..."
454 // Test table 'LEVELS' existence
455 if ( ! mDB->tableExists("LEVELS") )
457 GimmickMessage(1,"!! ERROR : Table 'LEVELS' does not exist"
462 tree::Descriptor& desc = GetTree().GetDescriptor();
463 // clears the existing one
467 std::string query = "SELECT * FROM LEVELS";
473 std::string name = q.getStringField(0);
474 GimmickMessage(2," * Importing level '"<<name<<"'"<<std::endl);
475 desc.Add(LevelDescriptor(name));
480 for (int level = 0; level < nblevel; ++level )
482 std::string table = GetTree().GetLevelDescriptor(level).GetName();
483 table += "_Attributes";
484 // Test table 'LEVELS' existence
485 if ( ! mDB->tableExists(table.c_str()) )
487 GimmickMessage(1,"!! ERROR : Table '"<<table<<"' does not exist"
492 std::string query = "SELECT * FROM ";
497 GimmickMessage(2," * Level '"
498 <<GetTree().GetLevelDescriptor(level).GetName()
501 // Test that ID and PARENT_ID mandatory attributes exist
502 bool ID_found = false;
503 bool PARENT_ID_found = false;
504 if (level==0) ID_found = true;
505 if (level<=1) PARENT_ID_found = true;
509 std::string key(q.getStringField(0));
510 std::string name(q.getStringField(1));
511 GimmickMessage(2," - Importing attribute '"<<key<<"' '"<<name
514 (AttributeDescriptor( key, // Key
516 q.getIntField(2), // Group
517 q.getIntField(3), // Element
518 q.getIntField(4) // Flags
524 if ( key == "PARENT_ID" )
526 PARENT_ID_found = true;
531 if ( ! (ID_found || PARENT_ID_found ) )
533 GimmickMessage(1,"!! ERROR : Table '"<<table
534 <<"' does not contain mandatory attribute ID or PARENT_ID"
542 // Create the attributes table for Root (i.e. Tree)
543 LevelDescriptor::AttributeDescriptorListType::const_iterator a;
544 for (a = GetTree().GetAttributeDescriptorList(0).begin();
545 a!= GetTree().GetAttributeDescriptorList(0).end();
550 AttributeMapType::const_iterator i = attr.find(a->GetKey());
551 if ( i != attr.end() )
556 GetTree().UnsafeSetAttribute( a->GetKey(), "" );
559 // Reading Root attributes
561 query = "SELECT * FROM ";
562 query += GetTree().GetLevelDescriptor(0).GetName();
565 for (int fld = 0; fld < q.numFields(); fld++)
567 GetTree().UnsafeSetAttribute(q.fieldName(fld),
568 q.getStringField(fld));
571 GimmickMessage(1,"Importing tree description from database ... OK"
575 //=====================================================================
593 //========================================================================
595 std::string& SQLformat(std::string& str)
597 // quote must be doubled
598 boost::algorithm::replace_all(str,"'","''");
599 // Found strange strings which contained NULL char INSIDE string
600 int i,size=str.size();
605 str = str.substr(0,i);
612 //========================================================================
614 //=====================================================================
615 void SQLiteTreeHandler::SQLAppendAttributesValues(tree::Node* n,
618 GimmickMessage(4,"SQLAppendAttributesValues"<<std::endl);
620 std::string values="";
621 tree::Node::AttributeMapType::iterator i;
622 for (i = n->GetAttributeMap().begin();
623 i != n->GetAttributeMap().end();
630 // std::cout << "("<<i->first<<","<<i->second<<")"<<std::endl;
631 atts += "'" + i->first + "'";
632 values += "'" + SQLformat(i->second) + "'";
635 GimmickMessage(4,"'"<<i->first<<"' = '"<<i->second<<"'"<<std::endl);
637 atts[atts.size()-1]=' ';
638 values[values.size()-1]=' ';
640 str = "("+atts+") VALUES ("+values+")";
641 GimmickMessage(4,"Result = '"<<str<<"'"<<std::endl);
643 //=====================================================================
645 //=====================================================================
646 tree::Node* SQLiteTreeHandler::DBGetParent( const AttributeMapType& attr)
648 Node* parent = GetTree().GetTree();
653 // Load the children of the current parent
654 DBLoadChildren(parent);
655 // Iterate the children
656 tree::Node::ChildrenListType::const_iterator i;
657 for (i = parent->GetChildrenList().begin();
658 i!= parent->GetChildrenList().end();
661 if ( (*i)->Matches( attr ) )
672 //=====================================================================
675 //=====================================================================
676 int SQLiteTreeHandler::DBLoadChildren(tree::Node* node,
679 if (node->GetLevel()+1 >= node->GetTree()->GetNumberOfLevels() )
682 GimmickMessage(2,"Loading children of '"<<node->GetLabel()
686 // If children loaded we do not have to do it but we need to recurse
687 // in order to load the children's children if necessary, and so on...
688 if (node->GetChildrenLoaded())
690 // Iterate the children
692 tree::Node::ChildrenListType::iterator i;
693 for (i = node->GetChildrenList().begin();
694 i!= node->GetChildrenList().end();
697 nbloaded += DBLoadChildren(*i,numberoflevels-1);
699 node->SetChildrenLoaded(true);
705 /// If children not loaded : do it and recurse
708 int level = node->GetLevel();
709 std::string query = "SELECT * FROM ";
711 query += GetTree().GetLevelDescriptor(level+1).GetName();
714 query += " WHERE PARENT_ID='" + node->UnsafeGetAttribute("ID")
724 // std::cout << "DBLoadCh : creating node level "<<level+1<<std::endl;
727 Node* n = new Node(node);
728 for (int fld = 0; fld < q.numFields(); fld++)
730 n->UnsafeSetAttribute(q.fieldName(fld),q.getStringField(fld));
736 ti.id = n->GetFieldValue("ID");
737 mTypeIdToNodeMap[ti] = n;
740 if ( numberoflevels != 1 )
743 nbloaded += DBLoadChildren(n, numberoflevels-1);
750 node->SetChildrenLoaded(true);
757 //=====================================================================
759 //======================================================================
760 void SQLiteTreeHandler::DBInsert(tree::Node* n)
762 GimmickMessage(2,"Inserting in DB '"<<n->GetLabel()
765 SQLAppendAttributesValues(n,val);
766 std::string insert("INSERT INTO ");
767 insert += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
768 insert += " " + val + ";";
772 // Store DB id of newly created node;
773 long lastrow = mDB->lastRowId();
774 std::stringstream ri;
775 ri << mDB->lastRowId();
776 n->SetAttribute("ID",ri.str());
778 //======================================================================
780 //======================================================================
781 /// Graft the branch defined by the attributes to the parent
782 void SQLiteTreeHandler::DBGraftToParent( tree::Node* parent,
783 const AttributeMapType& attr)
785 // std::cout <<"Grafting to parent '"<<parent->GetLabel()
788 for (int level = parent->GetLevel()+1;
789 level < GetTree().GetNumberOfLevels();
793 tree::Node* child = new tree::Node(parent,attr);
794 GetNumberOfChildren(parent);
795 child->SetChildrenLoaded(true);
796 // std::cout<<"Number of children "<<parent->GetNumberOfChildren()<<std::endl;
798 // Set PARENT_ID if necessary
799 if ( parent->GetLevel()>0 )
800 child->SetAttribute("PARENT_ID",parent->GetAttribute("ID"));
806 SQLAppendAttributesValues(child,val);
807 std::string insert("INSERT INTO ");
808 insert += GetTree().GetLevelDescriptor(child->GetLevel()).GetName();
809 insert += " " + val + ";";
812 // Store DB id of newly created node;
813 long lastrow = mDB->lastRowId();
814 std::stringstream ri;
815 ri << mDB->lastRowId();
816 child->SetAttribute("ID",ri.str());
822 // Insert in TypeId map
824 ti.type = node->GetType();
826 mTypeIdToNodeMap[ti] = node;
827 // std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl;
831 if (node->GetType()==Node::Patient) summary.added_patients++;
832 if (node->GetType()==Node::Study) summary.added_studies++;
833 if (node->GetType()==Node::Series) summary.added_series++;
834 if (node->GetType()==Node::Image) summary.added_images++;
838 //======================================================================
841 //=====================================================================
842 /// Sets an attribute of a Node
843 bool SQLiteTreeHandler::DBSetAttribute(tree::Node* n,
844 const std::string& key,
845 const std::string& value)
847 GimmickMessage(3,"Setting Attribute of '"<<n->GetLabel()<<
848 "' "<<key<<"='"<<value<<"'"<<std::endl);
850 n->SetAttribute(key,value);
851 std::string sql = "UPDATE ";
852 sql += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
857 sql += "' WHERE ID=";
858 sql += n->GetAttribute("ID");
859 // sql += " LIMIT 1";
862 //=====================================================================
865 //=====================================================================
866 void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
869 std::string query = "DELETE FROM ";
871 query += GetTree().GetLevelDescriptor(node->GetLevel()).GetName();
872 query += " WHERE ID='"+ node->GetAttribute("ID") + "';";
875 GimmickDebugMessage(2,
877 <<node->GetLabel()<<"' with ID '"
878 <<node->GetAttribute("ID")
879 <<"' in level "<< GetTree().GetLevelDescriptor(node->GetLevel()).GetName()
882 Node::ChildrenListType::iterator i;
883 for (i = node->GetChildrenList().begin();
884 i != node->GetChildrenList().end();
887 DBRecursiveRemoveNode((*i));
891 //=====================================================================
892 unsigned int SQLiteTreeHandler::GetNumberOfChildren(tree::Node* n)
896 int level = n->GetLevel();
898 if(level<GetTree().GetNumberOfLevels()&& level>0)
900 std::string query = "SELECT D1111_0011 FROM ";
901 query += GetTree().GetLevelDescriptor(level).GetName();
904 query += " WHERE ID='" + n->UnsafeGetAttribute("ID")
913 for (int fld = 0; fld < q.numFields(); fld++)
915 nb=q.getIntField(fld);
925 //=====================================================================
926 bool SQLiteTreeHandler::DBInsert(Node* alien_node,
927 UpdateSummary& summary)
929 // std::cout << "SQLiteTreeHandler::Insert('"<<alien_node->GetLabel()
930 // <<"')"<<std::endl;
932 // if (!ChildrenLoaded()) DBLoadChildren(this,Node::Database);
936 std::string parent_id;
937 parent = DBGetOrCreateParent(alien_node,parent_id,summary);
940 DBRecursiveGetOrCreateNode(alien_node,parent,parent_id,summary);
943 //=====================================================================
946 //=====================================================================
947 Node* SQLiteTreeHandler::DBGetOrCreateParent(Node* alien_node,
948 std::string& parent_id,
949 UpdateSummary& summary)
951 // std::cout << "DBGetOrCreateParent '" << alien_node->GetLabel()<<"'"
953 // Load the patients if not already done
954 DBLoadChildren(this,Node::Patient);
959 // The chain of ancestors
960 std::deque<Node*> chain;
961 Node* cur = alien_node->GetParent();
962 for (int type=Node::Patient;
963 type<alien_node->GetType();++type)
965 chain.push_front(cur);
966 cur = cur->GetParent();
969 // create the nodes if do not exist
970 std::deque<Node*>::iterator i;
971 for (i=chain.begin();i!=chain.end();++i)
973 // std::cout << " cur = '"<<(*i)->GetLabel()<<"'"<<std::endl;
974 // std::string cur_id = DBGetNodeId(*i,parent_id);
975 // if (cur_id.size()==0)
977 // Node does not exist : create it
979 parent = DBGetOrCreateNode(*i,
985 DBLoadChildren(parent,parent->GetType()+1);
991 //=====================================================================
995 //=====================================================================
996 void SQLiteTreeHandler::DBRecursiveGetOrCreateNode(Node* alien_node,
998 const std::string& parent_id,
999 UpdateSummary& summary)
1001 // std::cout << "SQLiteTreeHandler::RecursiveGetOrCreateNode('"
1002 // <<alien_node->GetLabel()
1003 // <<"','"<<parent<<"','"<<parent_id<<"')"<<std::endl;
1006 // std::cout << " -- Parent = '"<<parent->GetLabel()<<"'"<<std::endl;
1009 Node* new_node = DBGetOrCreateNode(alien_node,
1014 Node::ChildrenListType::iterator i;
1015 for (i = alien_node->GetChildrenList().begin();
1016 i != alien_node->GetChildrenList().end();
1019 DBRecursiveGetOrCreateNode((*i),new_node,new_id,summary);
1022 //=====================================================================
1025 //=====================================================================
1026 Node* SQLiteTreeHandler::DBGetOrCreateNode(Node* alien_node,
1027 Node* internal_parent,
1028 std::string parent_id,
1029 std::string& node_id,
1030 UpdateSummary& summary)
1032 // std::cout << "DBGetOrCreateNode('"<<alien_node->GetLabel()<<"','"
1033 // << internal_parent << "','"<< parent_id<<"')"<<std::endl;
1034 if (internal_parent != 0)
1036 // std::cout << " -- Parent = '"<<internal_parent->GetLabel()<<"'"<<std::endl;
1038 // Node Exists ? return it
1039 // First try among children of internal parent
1040 Node* node = GetChildrenLike(internal_parent,alien_node);
1043 node_id = node->UnsafeGetFieldValue("ID");
1046 // Second : try in DB
1048 // Does not exist : Create new one
1049 node = new Node(alien_node->GetType(),this,internal_parent);
1050 node->SetChildrenLoaded(true);
1051 // Copy fields values from alien
1052 Node::FieldValueMapType::iterator i,j;
1053 for (i = node->GetFieldValueMap().begin();
1054 i != node->GetFieldValueMap().end();
1057 j = alien_node->GetFieldValueMap().find(i->first);
1058 if (j != alien_node->GetFieldValueMap().end() )
1060 i->second = j->second;
1065 if (node->GetType()!=Node::Patient)
1066 node->SetFieldValue("PARENT_ID",parent_id);
1070 BuildSQLFieldsValues(node,val);
1071 std::string insert("INSERT INTO ");
1072 insert += std::string(SQLiteTreeHandlerStructure::Table(node->GetType()))
1074 // std::cout << "** SQL = '"<<insert<<"'"<<std::endl;
1076 // std::cout << "** SQL OK"<<std::endl;
1078 // Store DB id of newly created node;
1079 long lastrow = mDB->lastRowId();
1080 std::stringstream ri;
1081 ri << mDB->lastRowId();
1083 // std::cout << "LastRowId='"<<mDB->lastRowId()<<"' vs '"<<created_id<<"'"<<std::endl;
1085 node->SetFieldValue("ID",node_id);
1086 // Insert in TypeId map
1088 ti.type = node->GetType();
1090 mTypeIdToNodeMap[ti] = node;
1091 // std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl;
1095 if (node->GetType()==Node::Patient) summary.added_patients++;
1096 if (node->GetType()==Node::Study) summary.added_studies++;
1097 if (node->GetType()==Node::Series) summary.added_series++;
1098 if (node->GetType()==Node::Image) summary.added_images++;
1102 //=====================================================================
1104 //=====================================================================
1105 Node* SQLiteTreeHandler::GetChildrenLike(Node* parent,
1108 Node::ChildrenListType::iterator i;
1109 for (i = parent->GetChildrenList().begin();
1110 i != parent->GetChildrenList().end();
1113 Node::Type type = alien_node->GetType();
1116 j<SQLiteTreeHandlerStructure::NbQueryFields(type);
1120 alien_node->GetFieldValue(SQLiteTreeHandlerStructure::
1121 QueryField(type,j).key ) !=
1122 (*i)->GetFieldValue(SQLiteTreeHandlerStructure::
1123 QueryField(type,j).key ) )
1136 //=====================================================================
1138 //=====================================================================
1139 std::string SQLiteTreeHandler::DBGetNodeId(Node* node,
1140 const std::string& parent_id)
1142 // std::cout << "SQLiteTreeHandler::DBGetNodeId('"<<node->GetLabel()
1143 // <<"','"<<parent_id<<"')"
1146 int type = node->GetType();
1148 std::string table = SQLiteTreeHandlerStructure::Table(type);
1149 std::string where = "WHERE ";
1151 if (type!=Node::Patient)
1153 where += "PARENT_ID='" + parent_id
1154 //node->GetFieldValue("PARENT_ID")
1158 for (int i=0;i<SQLiteTreeHandlerStructure::NbQueryFields(type);i++)
1160 where += SQLiteTreeHandlerStructure::QueryField(type,i).key + "='"
1161 + node->GetFieldValue(SQLiteTreeHandlerStructure::QueryField(type,i).key) + "' ";
1162 if (i<SQLiteTreeHandlerStructure::NbQueryFields(type)-1)
1166 std::string query = "SELECT ID FROM " + table + " " + where + ";";
1167 // std::cout << "** SQL = '"<<query<<"'"<<std::endl;
1174 // std::cout << " - Node exists " << std::endl;
1175 std::string id = q.getStringField(0);
1176 // std::cout << " id = '"<<id<<"'"<<std::endl;
1183 //=====================================================================
1187 //=====================================================================
1188 Node* SQLiteTreeHandler::GetNodeFromTypeId(Node::Type type,
1189 const std::string& id)
1191 // std::cout << "GetNodeFromTypeId("<<type<<","<<id<<")"<<std::endl;
1197 TypeIdToNodeMapType::iterator i = mTypeIdToNodeMap.find(ti);
1198 if (i == mTypeIdToNodeMap.end())
1201 std::cout << "Internal error : mTypeIdToNodeMap does not contain key"
1203 creaError("Internal error : mTypeIdToNodeMap does not contain key");
1207 // std::cout << " ** Node = "<<i->second<<std::endl;
1211 //=====================================================================
1213 //=====================================================================
1214 bool SQLiteTreeHandler::Remove(Node* node)
1217 //DBRecursiveRemoveNode(node);
1219 // std::cout << "DELETE"<<std::endl;
1220 if (node->GetParent())
1222 node->GetParent()->RemoveChildrenFromList(node);
1225 // std::cout << "DELETE OK"<<std::endl;
1230 //========================================================================
1232 //=====================================================================
1233 void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
1235 // std::cout << "SQLiteTreeHandler::DBRecursiveRemoveNode('"
1236 // <<node->GetLabel()<<"')"<<std::endl;
1238 std::string query = "DELETE FROM ";
1239 query += SQLiteTreeHandlerStructure::Table(node->GetType());
1240 query += " WHERE ID='"+ node->GetFieldValue("ID") + "';";
1244 Node::ChildrenListType::iterator i;
1245 for (i = node->GetChildrenList().begin();
1246 i != node->GetChildrenList().end();
1249 DBRecursiveRemoveNode((*i));
1253 //=====================================================================
1255 //=====================================================================
1256 int SQLiteTreeHandler::DBQueryNumberOfChildren(Node* node)
1258 std::string query = "SELECT COUNT (ID) FROM ";
1259 query += SQLiteTreeHandlerStructure::Table(node->GetType()+1);
1260 if (node->GetType() != Node::Database)
1262 query += " WHERE PARENT_ID='"+ node->GetFieldValue("ID")+"'";
1266 // std::cout << "**SQL = "<< query << std::endl;
1271 // std::cout << "**RES = "<< q.getIntField(0) <<std::endl;
1273 return q.getIntField(0);
1275 //=====================================================================
1283 } // namespace creaImageIO