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 return (parent->GetLevel()+1);
138 //=====================================================================
141 //=====================================================================
142 bool SQLiteTreeHandler::Remove(tree::Node* node)
144 DBRecursiveRemoveNode(node);
146 // std::cout << "DELETE"<<std::endl;
148 tree::Node* parent=node->GetParent();
151 parent->RemoveChildrenFromList(node);
152 int nC=GetNumberOfChildren(parent);
156 std::stringstream out;
158 SetAttribute(parent,"NumberOfChildren",out.str());
167 if(remove&&parent->GetLevel()>0)
171 // std::cout << "DELETE OK"<<std::endl;
175 //========================================================================
179 //=====================================================================
181 //=====================================================================
182 /// Sets an attribute of a Node
183 bool SQLiteTreeHandler::SetAttribute(tree::Node* n,
184 const std::string& key,
185 const std::string& value)
187 if (n==0) n=GetTree().GetTree();
188 return DBSetAttribute(n,key,value);
190 //=====================================================================
204 //=====================================================================
205 // SQLite DB specific methods
206 //=====================================================================
211 //=====================================================================
212 char* format_sql(const std::string& s)
214 return sqlite3_mprintf("%q",s.c_str());
216 //=====================================================================
218 // sqlite3_exec(db, zSQL, 0, 0, 0);
219 // sqlite3_free(zSQL);
220 // char* CHAIN = format_sql(QUER); \
221 // sqlite3_free(CHAIN); \
223 //=====================================================================
224 #define QUERYDB(QUER,RES) \
227 GimmickMessage(2,"SQL query: '"<<QUER<<"'"<<std::endl); \
228 RES = mDB->execQuery(QUER.c_str()); \
230 catch (CppSQLite3Exception& e) \
232 GimmickError("SQLite query '"<<QUER<<"' : " \
233 << e.errorCode() << ":" \
234 << e.errorMessage() ); \
237 //=====================================================================
239 //=====================================================================
240 #define UPDATEDB(UP) \
243 GimmickMessage(2,"SQL update: '"<<UP<<"'"<<std::endl); \
244 mDB->execDML(UP.c_str()); \
246 catch (CppSQLite3Exception& e) \
248 GimmickError("SQLite update '"<<UP<<"' Error : " \
249 << e.errorCode() << ":" \
250 << e.errorMessage() ); \
252 //=====================================================================
255 //=====================================================================
256 bool SQLiteTreeHandler::DBOpen()
258 GimmickMessage(1,"Opening SQLite database '"<<GetFileName()
259 <<"' ... "<<std::endl);
261 if (!boost::filesystem::exists(GetFileName()))
268 mDB->open(GetFileName().c_str());
270 catch (CppSQLite3Exception& e)
272 GimmickError("Opening '"<<GetFileName()<<"' : "
273 << e.errorCode() << ":"
274 << e.errorMessage());
277 // IMPORT TREE DESCRIPTION (AND TEST DB VALIDITY)
278 if (!DBImportTreeDescription())
283 GimmickDebugMessage(1,"Opening SQLite database '"<<GetFileName()
284 <<"' ... OK"<<std::endl);
287 //=====================================================================
289 //=====================================================================
290 bool SQLiteTreeHandler::DBCreate()
292 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
293 <<"' ... "<<std::endl);
295 if (boost::filesystem::exists(GetFileName()))
297 GimmickError(GetFileName()<<"' : "
298 << "file already exists");
305 mDB->open(GetFileName().c_str());
307 catch (CppSQLite3Exception& e)
309 GimmickError(e.errorCode() << ":"
310 << e.errorMessage() <<std::endl);
318 // Create LEVELS table
319 command = "create table LEVELS\n";
320 command += "( Name text )\n";
323 // Iterate the Levels
324 for (int l=0; l<GetTree().GetNumberOfLevels(); ++l)
326 command = "INSERT INTO LEVELS (Name) VALUES ('";
327 command += GetTree().GetLevelDescriptor(l).GetName();
331 // Create table of level (for level>0, i.e. not Root)
334 command = "CREATE TABLE ";
335 command += GetTree().GetLevelDescriptor(l).GetName();
336 command += "\n(\nID INTEGER PRIMARY KEY";
339 command += ",\nPARENT_ID int not null";
341 SQLAppendAttributesDefinition(l,command);
344 command += ",\nconstraint FK_PARENT foreign key (PARENT_ID) references ";
345 command += GetTree().GetLevelDescriptor(l-1).GetName();
346 command += "(ID) on delete restrict on update restrict";
352 // Add Attribute 'ID' to Description
353 GetTree().GetDescriptor().Add
354 (AttributeDescriptor( "ID",
355 "Database Identifier",
357 AttributeDescriptor::PRIVATE
362 // Add Attribute 'PARENT_ID' to Description
363 GetTree().GetDescriptor().Add
364 (AttributeDescriptor( "PARENT_ID",
365 "Database Parent Identifier",
367 AttributeDescriptor::PRIVATE
373 // Create table *_ATTRIBUTES
375 command = "CREATE TABLE ";
376 command += GetTree().GetLevelDescriptor(l).GetName();
377 command += "_Attributes\n(\n";
378 command += "Key text,\n";
379 command += "Name text,\n";
380 command += "DicomGroup int,\n";
381 command += "DicomElement int,\n";
382 command += "Flags int\n";
387 // Fill the table *_ATTRIBUTES
388 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
389 for (i = GetTree().GetAttributeDescriptorList(l).begin();
390 i != GetTree().GetAttributeDescriptorList(l).end();
394 std::stringstream insert;
395 insert << "INSERT INTO "
396 << GetTree().GetLevelDescriptor(l).GetName()
397 << "_Attributes (Key,Name,DicomGroup,DicomElement,Flags) "
399 << i->GetKey() << "','"
400 << i->GetName() << "',"
401 << i->GetGroup() << ","
402 << i->GetElement() << ","
403 << i->GetFlags() << ");";
404 UPDATEDB(insert.str());
409 // Initialize the root attributes
410 GetTree().InitializeAttributeMap();
411 // Insert the root in the level 0 table
412 DBInsert(GetTree().GetTree());
415 GetTree().SetChildrenLoaded(true);
416 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
417 <<"' ... OK"<<std::endl);
420 //=====================================================================
422 //=====================================================================
423 void SQLiteTreeHandler::SQLAppendAttributesDefinition(int level,
426 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
427 for (i = GetTree().GetAttributeDescriptorList(level).begin();
428 i != GetTree().GetAttributeDescriptorList(level).end();
431 // if (i->second.flags==1) continue;
437 //=====================================================================
440 //=====================================================================
441 bool SQLiteTreeHandler::DBImportTreeDescription()
443 GimmickMessage(1,"Importing tree description from database ..."
446 // Test table 'LEVELS' existence
447 if ( ! mDB->tableExists("LEVELS") )
449 GimmickMessage(1,"!! ERROR : Table 'LEVELS' does not exist"
454 tree::Descriptor& desc = GetTree().GetDescriptor();
455 // clears the existing one
459 std::string query = "SELECT * FROM LEVELS";
465 std::string name = q.getStringField(0);
466 GimmickMessage(2," * Importing level '"<<name<<"'"<<std::endl);
467 desc.Add(LevelDescriptor(name));
472 for (int level = 0; level < nblevel; ++level )
474 std::string table = GetTree().GetLevelDescriptor(level).GetName();
475 table += "_Attributes";
476 // Test table 'LEVELS' existence
477 if ( ! mDB->tableExists(table.c_str()) )
479 GimmickMessage(1,"!! ERROR : Table '"<<table<<"' does not exist"
484 std::string query = "SELECT * FROM ";
489 GimmickMessage(2," * Level '"
490 <<GetTree().GetLevelDescriptor(level).GetName()
493 // Test that ID and PARENT_ID mandatory attributes exist
494 bool ID_found = false;
495 bool PARENT_ID_found = false;
496 if (level==0) ID_found = true;
497 if (level<=1) PARENT_ID_found = true;
501 std::string key(q.getStringField(0));
502 std::string name(q.getStringField(1));
503 GimmickMessage(2," - Importing attribute '"<<key<<"' '"<<name
506 (AttributeDescriptor( key, // Key
508 q.getIntField(2), // Group
509 q.getIntField(3), // Element
510 q.getIntField(4) // Flags
516 if ( key == "PARENT_ID" )
518 PARENT_ID_found = true;
523 if ( ! (ID_found || PARENT_ID_found ) )
525 GimmickMessage(1,"!! ERROR : Table '"<<table
526 <<"' does not contain mandatory attribute ID or PARENT_ID"
534 // Create the attributes table for Root (i.e. Tree)
535 LevelDescriptor::AttributeDescriptorListType::const_iterator a;
536 for (a = GetTree().GetAttributeDescriptorList(0).begin();
537 a!= GetTree().GetAttributeDescriptorList(0).end();
542 AttributeMapType::const_iterator i = attr.find(a->GetKey());
543 if ( i != attr.end() )
548 GetTree().UnsafeSetAttribute( a->GetKey(), "" );
551 // Reading Root attributes
553 query = "SELECT * FROM ";
554 query += GetTree().GetLevelDescriptor(0).GetName();
557 for (int fld = 0; fld < q.numFields(); fld++)
559 GetTree().UnsafeSetAttribute(q.fieldName(fld),
560 q.getStringField(fld));
563 GimmickMessage(1,"Importing tree description from database ... OK"
567 //=====================================================================
585 //========================================================================
587 std::string& SQLformat(std::string& str)
589 // quote must be doubled
590 boost::algorithm::replace_all(str,"'","''");
591 // Found strange strings which contained NULL char INSIDE string
592 int i,size=str.size();
597 str = str.substr(0,i);
604 //========================================================================
606 //=====================================================================
607 void SQLiteTreeHandler::SQLAppendAttributesValues(tree::Node* n,
610 GimmickMessage(4,"SQLAppendAttributesValues"<<std::endl);
612 std::string values="";
613 tree::Node::AttributeMapType::iterator i;
614 for (i = n->GetAttributeMap().begin();
615 i != n->GetAttributeMap().end();
622 // std::cout << "("<<i->first<<","<<i->second<<")"<<std::endl;
623 atts += "'" + i->first + "'";
624 values += "'" + SQLformat(i->second) + "'";
627 GimmickMessage(4,"'"<<i->first<<"' = '"<<i->second<<"'"<<std::endl);
629 atts[atts.size()-1]=' ';
630 values[values.size()-1]=' ';
632 str = "("+atts+") VALUES ("+values+")";
633 GimmickMessage(4,"Result = '"<<str<<"'"<<std::endl);
635 //=====================================================================
637 //=====================================================================
638 tree::Node* SQLiteTreeHandler::DBGetParent( const AttributeMapType& attr)
640 Node* parent = GetTree().GetTree();
645 // Load the children of the current parent
646 DBLoadChildren(parent);
647 // Iterate the children
648 tree::Node::ChildrenListType::const_iterator i;
649 for (i = parent->GetChildrenList().begin();
650 i!= parent->GetChildrenList().end();
653 if ( (*i)->Matches( attr ) )
664 //=====================================================================
667 //=====================================================================
668 int SQLiteTreeHandler::DBLoadChildren(tree::Node* node,
671 if (node->GetLevel()+1 >= node->GetTree()->GetNumberOfLevels() )
674 GimmickMessage(2,"Loading children of '"<<node->GetLabel()
678 // If children loaded we do not have to do it but we need to recurse
679 // in order to load the children's children if necessary, and so on...
680 if (node->GetChildrenLoaded())
682 // Iterate the children
684 tree::Node::ChildrenListType::iterator i;
685 for (i = node->GetChildrenList().begin();
686 i!= node->GetChildrenList().end();
689 nbloaded += DBLoadChildren(*i,numberoflevels-1);
691 node->SetChildrenLoaded(true);
697 /// If children not loaded : do it and recurse
700 int level = node->GetLevel();
701 std::string query = "SELECT * FROM ";
703 query += GetTree().GetLevelDescriptor(level+1).GetName();
706 query += " WHERE PARENT_ID='" + node->UnsafeGetAttribute("ID")
716 // std::cout << "DBLoadCh : creating node level "<<level+1<<std::endl;
719 Node* n = new Node(node);
720 for (int fld = 0; fld < q.numFields(); fld++)
722 n->UnsafeSetAttribute(q.fieldName(fld),q.getStringField(fld));
728 ti.id = n->GetFieldValue("ID");
729 mTypeIdToNodeMap[ti] = n;
732 if ( numberoflevels != 1 )
735 nbloaded += DBLoadChildren(n, numberoflevels-1);
742 node->SetChildrenLoaded(true);
749 //=====================================================================
751 //======================================================================
752 void SQLiteTreeHandler::DBInsert(tree::Node* n)
754 GimmickMessage(2,"Inserting in DB '"<<n->GetLabel()
757 SQLAppendAttributesValues(n,val);
758 std::string insert("INSERT INTO ");
759 insert += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
760 insert += " " + val + ";";
764 // Store DB id of newly created node;
765 long lastrow = mDB->lastRowId();
766 std::stringstream ri;
767 ri << mDB->lastRowId();
768 n->SetAttribute("ID",ri.str());
770 //======================================================================
772 //======================================================================
773 /// Graft the branch defined by the attributes to the parent
774 void SQLiteTreeHandler::DBGraftToParent( tree::Node* parent,
775 const AttributeMapType& attr)
777 // std::cout <<"Grafting to parent '"<<parent->GetLabel()
780 for (int level = parent->GetLevel()+1;
781 level < GetTree().GetNumberOfLevels();
785 tree::Node* child = new tree::Node(parent,attr);
786 child->SetChildrenLoaded(true);
789 int nc = GetNumberOfChildren(parent)+1;
791 // std::cout<<"Number of children "<<parent->GetNumberOfChildren()<<std::endl;
792 std::stringstream out;
794 SetAttribute(parent,"NumberOfChildren",out.str());
797 // Set PARENT_ID if necessary
798 if ( parent->GetLevel()>0 )
799 child->SetAttribute("PARENT_ID",parent->GetAttribute("ID"));
805 SQLAppendAttributesValues(child,val);
806 std::string insert("INSERT INTO ");
807 insert += GetTree().GetLevelDescriptor(child->GetLevel()).GetName();
808 insert += " " + val + ";";
811 // Store DB id of newly created node;
812 long lastrow = mDB->lastRowId();
813 std::stringstream ri;
814 ri << mDB->lastRowId();
815 child->SetAttribute("ID",ri.str());
821 // Insert in TypeId map
823 ti.type = node->GetType();
825 mTypeIdToNodeMap[ti] = node;
826 // std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl;
830 if (node->GetType()==Node::Patient) summary.added_patients++;
831 if (node->GetType()==Node::Study) summary.added_studies++;
832 if (node->GetType()==Node::Series) summary.added_series++;
833 if (node->GetType()==Node::Image) summary.added_images++;
837 //======================================================================
840 //=====================================================================
841 /// Sets an attribute of a Node
842 bool SQLiteTreeHandler::DBSetAttribute(tree::Node* n,
843 const std::string& key,
844 const std::string& value)
846 GimmickMessage(3,"Setting Attribute of '"<<n->GetLabel()<<
847 "' "<<key<<"='"<<value<<"'"<<std::endl);
849 n->SetAttribute(key,value);
850 std::string sql = "UPDATE ";
851 sql += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
856 sql += "' WHERE ID=";
857 sql += n->GetAttribute("ID");
858 // sql += " LIMIT 1";
861 //=====================================================================
864 //=====================================================================
865 void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
868 std::string query = "DELETE FROM ";
870 query += GetTree().GetLevelDescriptor(node->GetLevel()).GetName();
871 query += " WHERE ID='"+ node->GetAttribute("ID") + "';";
874 GimmickDebugMessage(2,
876 <<node->GetLabel()<<"' with ID '"
877 <<node->GetAttribute("ID")
878 <<"' in level "<< GetTree().GetLevelDescriptor(node->GetLevel()).GetName()
881 Node::ChildrenListType::iterator i;
882 for (i = node->GetChildrenList().begin();
883 i != node->GetChildrenList().end();
886 DBRecursiveRemoveNode((*i));
890 //=====================================================================
891 unsigned int SQLiteTreeHandler::GetNumberOfChildren(tree::Node* n)
895 int level = n->GetLevel();
897 if(level<GetTree().GetNumberOfLevels()&& level>0)
899 std::string query = "SELECT NumberOfChildren FROM ";
900 query += GetTree().GetLevelDescriptor(level).GetName();
903 query += " WHERE ID='" + n->UnsafeGetAttribute("ID")
912 for (int fld = 0; fld < q.numFields(); fld++)
914 nb=q.getIntField(fld);
929 //=====================================================================
930 bool SQLiteTreeHandler::DBInsert(Node* alien_node,
931 UpdateSummary& summary)
933 // std::cout << "SQLiteTreeHandler::Insert('"<<alien_node->GetLabel()
934 // <<"')"<<std::endl;
936 // if (!ChildrenLoaded()) DBLoadChildren(this,Node::Database);
940 std::string parent_id;
941 parent = DBGetOrCreateParent(alien_node,parent_id,summary);
944 DBRecursiveGetOrCreateNode(alien_node,parent,parent_id,summary);
947 //=====================================================================
950 //=====================================================================
951 Node* SQLiteTreeHandler::DBGetOrCreateParent(Node* alien_node,
952 std::string& parent_id,
953 UpdateSummary& summary)
955 // std::cout << "DBGetOrCreateParent '" << alien_node->GetLabel()<<"'"
957 // Load the patients if not already done
958 DBLoadChildren(this,Node::Patient);
963 // The chain of ancestors
964 std::deque<Node*> chain;
965 Node* cur = alien_node->GetParent();
966 for (int type=Node::Patient;
967 type<alien_node->GetType();++type)
969 chain.push_front(cur);
970 cur = cur->GetParent();
973 // create the nodes if do not exist
974 std::deque<Node*>::iterator i;
975 for (i=chain.begin();i!=chain.end();++i)
977 // std::cout << " cur = '"<<(*i)->GetLabel()<<"'"<<std::endl;
978 // std::string cur_id = DBGetNodeId(*i,parent_id);
979 // if (cur_id.size()==0)
981 // Node does not exist : create it
983 parent = DBGetOrCreateNode(*i,
989 DBLoadChildren(parent,parent->GetType()+1);
995 //=====================================================================
999 //=====================================================================
1000 void SQLiteTreeHandler::DBRecursiveGetOrCreateNode(Node* alien_node,
1002 const std::string& parent_id,
1003 UpdateSummary& summary)
1005 // std::cout << "SQLiteTreeHandler::RecursiveGetOrCreateNode('"
1006 // <<alien_node->GetLabel()
1007 // <<"','"<<parent<<"','"<<parent_id<<"')"<<std::endl;
1010 // std::cout << " -- Parent = '"<<parent->GetLabel()<<"'"<<std::endl;
1013 Node* new_node = DBGetOrCreateNode(alien_node,
1018 Node::ChildrenListType::iterator i;
1019 for (i = alien_node->GetChildrenList().begin();
1020 i != alien_node->GetChildrenList().end();
1023 DBRecursiveGetOrCreateNode((*i),new_node,new_id,summary);
1026 //=====================================================================
1029 //=====================================================================
1030 Node* SQLiteTreeHandler::DBGetOrCreateNode(Node* alien_node,
1031 Node* internal_parent,
1032 std::string parent_id,
1033 std::string& node_id,
1034 UpdateSummary& summary)
1036 // std::cout << "DBGetOrCreateNode('"<<alien_node->GetLabel()<<"','"
1037 // << internal_parent << "','"<< parent_id<<"')"<<std::endl;
1038 if (internal_parent != 0)
1040 // std::cout << " -- Parent = '"<<internal_parent->GetLabel()<<"'"<<std::endl;
1042 // Node Exists ? return it
1043 // First try among children of internal parent
1044 Node* node = GetChildrenLike(internal_parent,alien_node);
1047 node_id = node->UnsafeGetFieldValue("ID");
1050 // Second : try in DB
1052 // Does not exist : Create new one
1053 node = new Node(alien_node->GetType(),this,internal_parent);
1054 node->SetChildrenLoaded(true);
1055 // Copy fields values from alien
1056 Node::FieldValueMapType::iterator i,j;
1057 for (i = node->GetFieldValueMap().begin();
1058 i != node->GetFieldValueMap().end();
1061 j = alien_node->GetFieldValueMap().find(i->first);
1062 if (j != alien_node->GetFieldValueMap().end() )
1064 i->second = j->second;
1069 if (node->GetType()!=Node::Patient)
1070 node->SetFieldValue("PARENT_ID",parent_id);
1074 BuildSQLFieldsValues(node,val);
1075 std::string insert("INSERT INTO ");
1076 insert += std::string(SQLiteTreeHandlerStructure::Table(node->GetType()))
1078 // std::cout << "** SQL = '"<<insert<<"'"<<std::endl;
1080 // std::cout << "** SQL OK"<<std::endl;
1082 // Store DB id of newly created node;
1083 long lastrow = mDB->lastRowId();
1084 std::stringstream ri;
1085 ri << mDB->lastRowId();
1087 // std::cout << "LastRowId='"<<mDB->lastRowId()<<"' vs '"<<created_id<<"'"<<std::endl;
1089 node->SetFieldValue("ID",node_id);
1090 // Insert in TypeId map
1092 ti.type = node->GetType();
1094 mTypeIdToNodeMap[ti] = node;
1095 // std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl;
1099 if (node->GetType()==Node::Patient) summary.added_patients++;
1100 if (node->GetType()==Node::Study) summary.added_studies++;
1101 if (node->GetType()==Node::Series) summary.added_series++;
1102 if (node->GetType()==Node::Image) summary.added_images++;
1106 //=====================================================================
1108 //=====================================================================
1109 Node* SQLiteTreeHandler::GetChildrenLike(Node* parent,
1112 Node::ChildrenListType::iterator i;
1113 for (i = parent->GetChildrenList().begin();
1114 i != parent->GetChildrenList().end();
1117 Node::Type type = alien_node->GetType();
1120 j<SQLiteTreeHandlerStructure::NbQueryFields(type);
1124 alien_node->GetFieldValue(SQLiteTreeHandlerStructure::
1125 QueryField(type,j).key ) !=
1126 (*i)->GetFieldValue(SQLiteTreeHandlerStructure::
1127 QueryField(type,j).key ) )
1140 //=====================================================================
1142 //=====================================================================
1143 std::string SQLiteTreeHandler::DBGetNodeId(Node* node,
1144 const std::string& parent_id)
1146 // std::cout << "SQLiteTreeHandler::DBGetNodeId('"<<node->GetLabel()
1147 // <<"','"<<parent_id<<"')"
1150 int type = node->GetType();
1152 std::string table = SQLiteTreeHandlerStructure::Table(type);
1153 std::string where = "WHERE ";
1155 if (type!=Node::Patient)
1157 where += "PARENT_ID='" + parent_id
1158 //node->GetFieldValue("PARENT_ID")
1162 for (int i=0;i<SQLiteTreeHandlerStructure::NbQueryFields(type);i++)
1164 where += SQLiteTreeHandlerStructure::QueryField(type,i).key + "='"
1165 + node->GetFieldValue(SQLiteTreeHandlerStructure::QueryField(type,i).key) + "' ";
1166 if (i<SQLiteTreeHandlerStructure::NbQueryFields(type)-1)
1170 std::string query = "SELECT ID FROM " + table + " " + where + ";";
1171 // std::cout << "** SQL = '"<<query<<"'"<<std::endl;
1178 // std::cout << " - Node exists " << std::endl;
1179 std::string id = q.getStringField(0);
1180 // std::cout << " id = '"<<id<<"'"<<std::endl;
1187 //=====================================================================
1191 //=====================================================================
1192 Node* SQLiteTreeHandler::GetNodeFromTypeId(Node::Type type,
1193 const std::string& id)
1195 // std::cout << "GetNodeFromTypeId("<<type<<","<<id<<")"<<std::endl;
1201 TypeIdToNodeMapType::iterator i = mTypeIdToNodeMap.find(ti);
1202 if (i == mTypeIdToNodeMap.end())
1205 std::cout << "Internal error : mTypeIdToNodeMap does not contain key"
1207 creaError("Internal error : mTypeIdToNodeMap does not contain key");
1211 // std::cout << " ** Node = "<<i->second<<std::endl;
1215 //=====================================================================
1217 //=====================================================================
1218 bool SQLiteTreeHandler::Remove(Node* node)
1221 //DBRecursiveRemoveNode(node);
1223 // std::cout << "DELETE"<<std::endl;
1224 if (node->GetParent())
1226 node->GetParent()->RemoveChildrenFromList(node);
1229 // std::cout << "DELETE OK"<<std::endl;
1234 //========================================================================
1236 //=====================================================================
1237 void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
1239 // std::cout << "SQLiteTreeHandler::DBRecursiveRemoveNode('"
1240 // <<node->GetLabel()<<"')"<<std::endl;
1242 std::string query = "DELETE FROM ";
1243 query += SQLiteTreeHandlerStructure::Table(node->GetType());
1244 query += " WHERE ID='"+ node->GetFieldValue("ID") + "';";
1248 Node::ChildrenListType::iterator i;
1249 for (i = node->GetChildrenList().begin();
1250 i != node->GetChildrenList().end();
1253 DBRecursiveRemoveNode((*i));
1257 //=====================================================================
1259 //=====================================================================
1260 int SQLiteTreeHandler::DBQueryNumberOfChildren(Node* node)
1262 std::string query = "SELECT COUNT (ID) FROM ";
1263 query += SQLiteTreeHandlerStructure::Table(node->GetType()+1);
1264 if (node->GetType() != Node::Database)
1266 query += " WHERE PARENT_ID='"+ node->GetFieldValue("ID")+"'";
1270 // std::cout << "**SQL = "<< query << std::endl;
1275 // std::cout << "**RES = "<< q.getIntField(0) <<std::endl;
1277 return q.getIntField(0);
1279 //=====================================================================
1287 } // namespace creaImageIO