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;
39 GimmickMessage(1,"SQLite version : "
40 <<std::string(mDB->SQLiteVersion())<< std::endl);
42 //=============================================================
44 //=============================================================
45 SQLiteTreeHandler::~SQLiteTreeHandler()
49 //=============================================================
52 //=============================================================
53 // void SQLiteTreeHandler::Print() const
56 std::cout << "-> '"<<GetName()<< "' - '"
57 << GetFileName()<<"'"<<std::endl;
58 ChildrenListType::const_iterator i;
59 for (i=GetChildrenList().begin(); i!=GetChildrenList().end(); i++)
65 //=============================================================
67 //=====================================================================
69 bool SQLiteTreeHandler::LocationIsValid()
75 //=====================================================================
78 //=====================================================================
79 bool SQLiteTreeHandler::Open(bool writable)
81 // std::cout << "***> SQLiteTreeHandler::Open('"<<GetFileName()<<"')"<<std::endl;
82 SetWritable(writable);
86 //=====================================================================
87 bool SQLiteTreeHandler::Create(bool writable)
89 // std::cout << "***> SQLiteTreeHandler::New('"<<GetFileName()<<"')"<<std::endl;
90 SetWritable(writable);
93 //=====================================================================
96 //=====================================================================
97 bool SQLiteTreeHandler::Close()
101 //=====================================================================
104 //=====================================================================
105 bool SQLiteTreeHandler::Destroy()
110 //=====================================================================
112 //=====================================================================
113 int SQLiteTreeHandler::LoadChildren(tree::Node* parent, int maxlevel)
115 if (parent==0) parent = GetTree().GetTree();
116 return DBLoadChildren(parent,maxlevel);
118 //=====================================================================
123 //=====================================================================
124 void SQLiteTreeHandler::UnLoad(tree::Node* n)
127 //=====================================================================
130 //=====================================================================
131 int SQLiteTreeHandler::AddBranch( const AttributeMapType& attr )
133 tree::Node* parent = DBGetParent(attr);
134 DBGraftToParent(parent,attr);
135 int nChildren = GetNumberOfChildren(parent);
136 std::stringstream out;
138 if(parent->GetLevel()>0&&parent->GetLevel()<GetTree().GetNumberOfLevels())
140 DBSetAttribute(parent,"D1111_0011",out.str());
142 return (parent->GetLevel()+1);
144 //=====================================================================
147 //=====================================================================
148 bool SQLiteTreeHandler::Remove(tree::Node* node)
150 DBRecursiveRemoveNode(node);
152 // std::cout << "DELETE"<<std::endl;
153 if (node->GetParent())
155 node->GetParent()->RemoveChildrenFromList(node);
158 // std::cout << "DELETE OK"<<std::endl;
162 //========================================================================
166 //=====================================================================
168 //=====================================================================
169 /// Sets an attribute of a Node
170 bool SQLiteTreeHandler::SetAttribute(tree::Node* n,
171 const std::string& key,
172 const std::string& value)
174 if (n==0) n=GetTree().GetTree();
175 return DBSetAttribute(n,key,value);
177 //=====================================================================
191 //=====================================================================
192 // SQLite DB specific methods
193 //=====================================================================
198 //=====================================================================
199 char* format_sql(const std::string& s)
201 return sqlite3_mprintf("%q",s.c_str());
203 //=====================================================================
205 // sqlite3_exec(db, zSQL, 0, 0, 0);
206 // sqlite3_free(zSQL);
207 // char* CHAIN = format_sql(QUER); \
208 // sqlite3_free(CHAIN); \
210 //=====================================================================
211 #define QUERYDB(QUER,RES) \
214 GimmickMessage(2,"SQL query: '"<<QUER<<"'"<<std::endl); \
215 RES = mDB->execQuery(QUER.c_str()); \
217 catch (CppSQLite3Exception& e) \
219 GimmickError("SQLite query '"<<QUER<<"' : " \
220 << e.errorCode() << ":" \
221 << e.errorMessage() ); \
224 //=====================================================================
226 //=====================================================================
227 #define UPDATEDB(UP) \
230 GimmickMessage(2,"SQL update: '"<<UP<<"'"<<std::endl); \
231 mDB->execDML(UP.c_str()); \
233 catch (CppSQLite3Exception& e) \
235 GimmickError("SQLite update '"<<UP<<"' Error : " \
236 << e.errorCode() << ":" \
237 << e.errorMessage() ); \
239 //=====================================================================
242 //=====================================================================
243 bool SQLiteTreeHandler::DBOpen()
245 GimmickMessage(1,"Opening SQLite database '"<<GetFileName()
246 <<"' ... "<<std::endl);
248 if (!boost::filesystem::exists(GetFileName()))
255 mDB->open(GetFileName().c_str());
257 catch (CppSQLite3Exception& e)
259 GimmickError("Opening '"<<GetFileName()<<"' : "
260 << e.errorCode() << ":"
261 << e.errorMessage());
264 // IMPORT TREE DESCRIPTION (AND TEST DB VALIDITY)
265 if (!DBImportTreeDescription())
270 GimmickDebugMessage(1,"Opening SQLite database '"<<GetFileName()
271 <<"' ... OK"<<std::endl);
274 //=====================================================================
276 //=====================================================================
277 bool SQLiteTreeHandler::DBCreate()
279 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
280 <<"' ... "<<std::endl);
282 if (boost::filesystem::exists(GetFileName()))
284 GimmickError(GetFileName()<<"' : "
285 << "file already exists");
292 mDB->open(GetFileName().c_str());
294 catch (CppSQLite3Exception& e)
296 GimmickError(e.errorCode() << ":"
297 << e.errorMessage() <<std::endl);
305 // Create LEVELS table
306 command = "create table LEVELS\n";
307 command += "( Name text )\n";
310 // Iterate the Levels
311 for (int l=0; l<GetTree().GetNumberOfLevels(); ++l)
313 command = "INSERT INTO LEVELS (Name) VALUES ('";
314 command += GetTree().GetLevelDescriptor(l).GetName();
318 // Create table of level (for level>0, i.e. not Root)
321 command = "CREATE TABLE ";
322 command += GetTree().GetLevelDescriptor(l).GetName();
323 command += "\n(\nID INTEGER PRIMARY KEY";
326 command += ",\nPARENT_ID int not null";
328 SQLAppendAttributesDefinition(l,command);
331 command += ",\nconstraint FK_PARENT foreign key (PARENT_ID) references ";
332 command += GetTree().GetLevelDescriptor(l-1).GetName();
333 command += "(ID) on delete restrict on update restrict";
339 // Add Attribute 'ID' to Description
340 GetTree().GetDescriptor().Add
341 (AttributeDescriptor( "ID",
342 "Database Identifier",
344 AttributeDescriptor::PRIVATE
349 // Add Attribute 'PARENT_ID' to Description
350 GetTree().GetDescriptor().Add
351 (AttributeDescriptor( "PARENT_ID",
352 "Database Parent Identifier",
354 AttributeDescriptor::PRIVATE
360 // Create table *_ATTRIBUTES
362 command = "CREATE TABLE ";
363 command += GetTree().GetLevelDescriptor(l).GetName();
364 command += "_Attributes\n(\n";
365 command += "Key text,\n";
366 command += "Name text,\n";
367 command += "DicomGroup int,\n";
368 command += "DicomElement int,\n";
369 command += "Flags int\n";
374 // Fill the table *_ATTRIBUTES
375 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
376 for (i = GetTree().GetAttributeDescriptorList(l).begin();
377 i != GetTree().GetAttributeDescriptorList(l).end();
381 std::stringstream insert;
382 insert << "INSERT INTO "
383 << GetTree().GetLevelDescriptor(l).GetName()
384 << "_Attributes (Key,Name,DicomGroup,DicomElement,Flags) "
386 << i->GetKey() << "','"
387 << i->GetName() << "',"
388 << i->GetGroup() << ","
389 << i->GetElement() << ","
390 << i->GetFlags() << ");";
391 UPDATEDB(insert.str());
396 // Initialize the root attributes
397 GetTree().InitializeAttributeMap();
398 // Insert the root in the level 0 table
399 DBInsert(GetTree().GetTree());
402 GetTree().SetChildrenLoaded(true);
403 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
404 <<"' ... OK"<<std::endl);
407 //=====================================================================
409 //=====================================================================
410 void SQLiteTreeHandler::SQLAppendAttributesDefinition(int level,
413 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
414 for (i = GetTree().GetAttributeDescriptorList(level).begin();
415 i != GetTree().GetAttributeDescriptorList(level).end();
418 // if (i->second.flags==1) continue;
424 //=====================================================================
427 //=====================================================================
428 bool SQLiteTreeHandler::DBImportTreeDescription()
430 GimmickMessage(1,"Importing tree description from database ..."
433 // Test table 'LEVELS' existence
434 if ( ! mDB->tableExists("LEVELS") )
436 GimmickMessage(1,"!! ERROR : Table 'LEVELS' does not exist"
441 tree::Descriptor& desc = GetTree().GetDescriptor();
442 // clears the existing one
446 std::string query = "SELECT * FROM LEVELS";
452 std::string name = q.getStringField(0);
453 GimmickMessage(2," * Importing level '"<<name<<"'"<<std::endl);
454 desc.Add(LevelDescriptor(name));
459 for (int level = 0; level < nblevel; ++level )
461 std::string table = GetTree().GetLevelDescriptor(level).GetName();
462 table += "_Attributes";
463 // Test table 'LEVELS' existence
464 if ( ! mDB->tableExists(table.c_str()) )
466 GimmickMessage(1,"!! ERROR : Table '"<<table<<"' does not exist"
471 std::string query = "SELECT * FROM ";
476 GimmickMessage(2," * Level '"
477 <<GetTree().GetLevelDescriptor(level).GetName()
480 // Test that ID and PARENT_ID mandatory attributes exist
481 bool ID_found = false;
482 bool PARENT_ID_found = false;
483 if (level==0) ID_found = true;
484 if (level<=1) PARENT_ID_found = true;
488 std::string key(q.getStringField(0));
489 std::string name(q.getStringField(1));
490 GimmickMessage(2," - Importing attribute '"<<key<<"' '"<<name
493 (AttributeDescriptor( key, // Key
495 q.getIntField(2), // Group
496 q.getIntField(3), // Element
497 q.getIntField(4) // Flags
503 if ( key == "PARENT_ID" )
505 PARENT_ID_found = true;
510 if ( ! (ID_found || PARENT_ID_found ) )
512 GimmickMessage(1,"!! ERROR : Table '"<<table
513 <<"' does not contain mandatory attribute ID or PARENT_ID"
521 // Create the attributes table for Root (i.e. Tree)
522 LevelDescriptor::AttributeDescriptorListType::const_iterator a;
523 for (a = GetTree().GetAttributeDescriptorList(0).begin();
524 a!= GetTree().GetAttributeDescriptorList(0).end();
529 AttributeMapType::const_iterator i = attr.find(a->GetKey());
530 if ( i != attr.end() )
535 GetTree().UnsafeSetAttribute( a->GetKey(), "" );
538 // Reading Root attributes
540 query = "SELECT * FROM ";
541 query += GetTree().GetLevelDescriptor(0).GetName();
544 for (int fld = 0; fld < q.numFields(); fld++)
546 GetTree().UnsafeSetAttribute(q.fieldName(fld),
547 q.getStringField(fld));
550 GimmickMessage(1,"Importing tree description from database ... OK"
554 //=====================================================================
572 //========================================================================
574 std::string& SQLformat(std::string& str)
576 // quote must be doubled
577 boost::algorithm::replace_all(str,"'","''");
578 // Found strange strings which contained NULL char INSIDE string
579 int i,size=str.size();
584 str = str.substr(0,i);
591 //========================================================================
593 //=====================================================================
594 void SQLiteTreeHandler::SQLAppendAttributesValues(tree::Node* n,
597 GimmickMessage(4,"SQLAppendAttributesValues"<<std::endl);
599 std::string values="";
600 tree::Node::AttributeMapType::iterator i;
601 for (i = n->GetAttributeMap().begin();
602 i != n->GetAttributeMap().end();
609 // std::cout << "("<<i->first<<","<<i->second<<")"<<std::endl;
610 atts += "'" + i->first + "'";
611 values += "'" + SQLformat(i->second) + "'";
614 GimmickMessage(4,"'"<<i->first<<"' = '"<<i->second<<"'"<<std::endl);
616 atts[atts.size()-1]=' ';
617 values[values.size()-1]=' ';
619 str = "("+atts+") VALUES ("+values+")";
620 GimmickMessage(4,"Result = '"<<str<<"'"<<std::endl);
622 //=====================================================================
624 //=====================================================================
625 tree::Node* SQLiteTreeHandler::DBGetParent( const AttributeMapType& attr)
627 Node* parent = GetTree().GetTree();
632 // Load the children of the current parent
633 DBLoadChildren(parent);
634 // Iterate the children
635 tree::Node::ChildrenListType::const_iterator i;
636 for (i = parent->GetChildrenList().begin();
637 i!= parent->GetChildrenList().end();
640 if ( (*i)->Matches( attr ) )
651 //=====================================================================
654 //=====================================================================
655 int SQLiteTreeHandler::DBLoadChildren(tree::Node* node,
658 if (node->GetLevel()+1 >= node->GetTree()->GetNumberOfLevels() )
661 GimmickMessage(2,"Loading children of '"<<node->GetLabel()
665 // If children loaded we do not have to do it but we need to recurse
666 // in order to load the children's children if necessary, and so on...
667 if (node->GetChildrenLoaded())
669 // Iterate the children
670 tree::Node::ChildrenListType::iterator i;
671 for (i = node->GetChildrenList().begin();
672 i!= node->GetChildrenList().end();
675 nbloaded += DBLoadChildren(*i,numberoflevels-1);
680 /// If children not loaded : do it and recurse
683 int level = node->GetLevel();
684 std::string query = "SELECT * FROM ";
686 query += GetTree().GetLevelDescriptor(level+1).GetName();
689 query += " WHERE PARENT_ID='" + node->UnsafeGetAttribute("ID")
698 Node* n = new Node(node);
699 for (int fld = 0; fld < q.numFields(); fld++)
701 n->UnsafeSetAttribute(q.fieldName(fld),q.getStringField(fld));
707 ti.id = n->GetFieldValue("ID");
708 mTypeIdToNodeMap[ti] = n;
711 if ( numberoflevels != 1 )
714 nbloaded += DBLoadChildren(n, numberoflevels-1);
721 node->SetChildrenLoaded(true);
726 //=====================================================================
728 //======================================================================
729 void SQLiteTreeHandler::DBInsert(tree::Node* n)
731 GimmickMessage(2,"Inserting in DB '"<<n->GetLabel()
734 SQLAppendAttributesValues(n,val);
735 std::string insert("INSERT INTO ");
736 insert += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
737 insert += " " + val + ";";
741 // Store DB id of newly created node;
742 long lastrow = mDB->lastRowId();
743 std::stringstream ri;
744 ri << mDB->lastRowId();
745 n->SetAttribute("ID",ri.str());
747 //======================================================================
749 //======================================================================
750 /// Graft the branch defined by the attributes to the parent
751 void SQLiteTreeHandler::DBGraftToParent( tree::Node* parent,
752 const AttributeMapType& attr)
754 GimmickMessage(2,"Grafting to parent '"<<parent->GetLabel()
757 for (int level = parent->GetLevel()+1;
758 level < GetTree().GetNumberOfLevels();
762 tree::Node* child = new tree::Node(parent,attr);
764 // Set PARENT_ID if necessary
765 if ( parent->GetLevel()>0 )
766 child->SetAttribute("PARENT_ID",parent->GetAttribute("ID"));
772 SQLAppendAttributesValues(child,val);
773 std::string insert("INSERT INTO ");
774 insert += GetTree().GetLevelDescriptor(child->GetLevel()).GetName();
775 insert += " " + val + ";";
778 // Store DB id of newly created node;
779 long lastrow = mDB->lastRowId();
780 std::stringstream ri;
781 ri << mDB->lastRowId();
782 child->SetAttribute("ID",ri.str());
788 // Insert in TypeId map
790 ti.type = node->GetType();
792 mTypeIdToNodeMap[ti] = node;
793 // std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl;
797 if (node->GetType()==Node::Patient) summary.added_patients++;
798 if (node->GetType()==Node::Study) summary.added_studies++;
799 if (node->GetType()==Node::Series) summary.added_series++;
800 if (node->GetType()==Node::Image) summary.added_images++;
804 //======================================================================
807 //=====================================================================
808 /// Sets an attribute of a Node
809 bool SQLiteTreeHandler::DBSetAttribute(tree::Node* n,
810 const std::string& key,
811 const std::string& value)
813 GimmickMessage(3,"Setting Attribute of '"<<n->GetLabel()<<
814 "' "<<key<<"='"<<value<<"'"<<std::endl);
816 n->SetAttribute(key,value);
817 std::string sql = "UPDATE ";
818 sql += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
823 sql += "' WHERE ID=";
824 sql += n->GetAttribute("ID");
825 // sql += " LIMIT 1";
828 //=====================================================================
831 //=====================================================================
832 void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
835 std::string query = "DELETE FROM ";
837 query += GetTree().GetLevelDescriptor(node->GetLevel()).GetName();
838 query += " WHERE ID='"+ node->GetAttribute("ID") + "';";
841 GimmickDebugMessage(2,
843 <<node->GetLabel()<<"' with ID '"
844 <<node->GetAttribute("ID")
845 <<"' in level "<< GetTree().GetLevelDescriptor(node->GetLevel()).GetName()
848 Node::ChildrenListType::iterator i;
849 for (i = node->GetChildrenList().begin();
850 i != node->GetChildrenList().end();
853 DBRecursiveRemoveNode((*i));
857 //=====================================================================
858 unsigned int SQLiteTreeHandler::GetNumberOfChildren(tree::Node* n)
862 int level = n->GetLevel();
863 if(GetTree().GetNumberOfLevels()!=(level+1))
865 std::string query = "SELECT * FROM ";
866 query += GetTree().GetLevelDescriptor(level+1).GetName();
869 query += " WHERE PARENT_ID='" + n->UnsafeGetAttribute("ID")
887 //=====================================================================
888 bool SQLiteTreeHandler::DBInsert(Node* alien_node,
889 UpdateSummary& summary)
891 // std::cout << "SQLiteTreeHandler::Insert('"<<alien_node->GetLabel()
892 // <<"')"<<std::endl;
894 // if (!ChildrenLoaded()) DBLoadChildren(this,Node::Database);
898 std::string parent_id;
899 parent = DBGetOrCreateParent(alien_node,parent_id,summary);
902 DBRecursiveGetOrCreateNode(alien_node,parent,parent_id,summary);
905 //=====================================================================
908 //=====================================================================
909 Node* SQLiteTreeHandler::DBGetOrCreateParent(Node* alien_node,
910 std::string& parent_id,
911 UpdateSummary& summary)
913 // std::cout << "DBGetOrCreateParent '" << alien_node->GetLabel()<<"'"
915 // Load the patients if not already done
916 DBLoadChildren(this,Node::Patient);
921 // The chain of ancestors
922 std::deque<Node*> chain;
923 Node* cur = alien_node->GetParent();
924 for (int type=Node::Patient;
925 type<alien_node->GetType();++type)
927 chain.push_front(cur);
928 cur = cur->GetParent();
931 // create the nodes if do not exist
932 std::deque<Node*>::iterator i;
933 for (i=chain.begin();i!=chain.end();++i)
935 // std::cout << " cur = '"<<(*i)->GetLabel()<<"'"<<std::endl;
936 // std::string cur_id = DBGetNodeId(*i,parent_id);
937 // if (cur_id.size()==0)
939 // Node does not exist : create it
941 parent = DBGetOrCreateNode(*i,
947 DBLoadChildren(parent,parent->GetType()+1);
953 //=====================================================================
957 //=====================================================================
958 void SQLiteTreeHandler::DBRecursiveGetOrCreateNode(Node* alien_node,
960 const std::string& parent_id,
961 UpdateSummary& summary)
963 // std::cout << "SQLiteTreeHandler::RecursiveGetOrCreateNode('"
964 // <<alien_node->GetLabel()
965 // <<"','"<<parent<<"','"<<parent_id<<"')"<<std::endl;
968 // std::cout << " -- Parent = '"<<parent->GetLabel()<<"'"<<std::endl;
971 Node* new_node = DBGetOrCreateNode(alien_node,
976 Node::ChildrenListType::iterator i;
977 for (i = alien_node->GetChildrenList().begin();
978 i != alien_node->GetChildrenList().end();
981 DBRecursiveGetOrCreateNode((*i),new_node,new_id,summary);
984 //=====================================================================
987 //=====================================================================
988 Node* SQLiteTreeHandler::DBGetOrCreateNode(Node* alien_node,
989 Node* internal_parent,
990 std::string parent_id,
991 std::string& node_id,
992 UpdateSummary& summary)
994 // std::cout << "DBGetOrCreateNode('"<<alien_node->GetLabel()<<"','"
995 // << internal_parent << "','"<< parent_id<<"')"<<std::endl;
996 if (internal_parent != 0)
998 // std::cout << " -- Parent = '"<<internal_parent->GetLabel()<<"'"<<std::endl;
1000 // Node Exists ? return it
1001 // First try among children of internal parent
1002 Node* node = GetChildrenLike(internal_parent,alien_node);
1005 node_id = node->UnsafeGetFieldValue("ID");
1008 // Second : try in DB
1010 // Does not exist : Create new one
1011 node = new Node(alien_node->GetType(),this,internal_parent);
1012 node->SetChildrenLoaded(true);
1013 // Copy fields values from alien
1014 Node::FieldValueMapType::iterator i,j;
1015 for (i = node->GetFieldValueMap().begin();
1016 i != node->GetFieldValueMap().end();
1019 j = alien_node->GetFieldValueMap().find(i->first);
1020 if (j != alien_node->GetFieldValueMap().end() )
1022 i->second = j->second;
1027 if (node->GetType()!=Node::Patient)
1028 node->SetFieldValue("PARENT_ID",parent_id);
1032 BuildSQLFieldsValues(node,val);
1033 std::string insert("INSERT INTO ");
1034 insert += std::string(SQLiteTreeHandlerStructure::Table(node->GetType()))
1036 // std::cout << "** SQL = '"<<insert<<"'"<<std::endl;
1038 // std::cout << "** SQL OK"<<std::endl;
1040 // Store DB id of newly created node;
1041 long lastrow = mDB->lastRowId();
1042 std::stringstream ri;
1043 ri << mDB->lastRowId();
1045 // std::cout << "LastRowId='"<<mDB->lastRowId()<<"' vs '"<<created_id<<"'"<<std::endl;
1047 node->SetFieldValue("ID",node_id);
1048 // Insert in TypeId map
1050 ti.type = node->GetType();
1052 mTypeIdToNodeMap[ti] = node;
1053 // std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl;
1057 if (node->GetType()==Node::Patient) summary.added_patients++;
1058 if (node->GetType()==Node::Study) summary.added_studies++;
1059 if (node->GetType()==Node::Series) summary.added_series++;
1060 if (node->GetType()==Node::Image) summary.added_images++;
1064 //=====================================================================
1066 //=====================================================================
1067 Node* SQLiteTreeHandler::GetChildrenLike(Node* parent,
1070 Node::ChildrenListType::iterator i;
1071 for (i = parent->GetChildrenList().begin();
1072 i != parent->GetChildrenList().end();
1075 Node::Type type = alien_node->GetType();
1078 j<SQLiteTreeHandlerStructure::NbQueryFields(type);
1082 alien_node->GetFieldValue(SQLiteTreeHandlerStructure::
1083 QueryField(type,j).key ) !=
1084 (*i)->GetFieldValue(SQLiteTreeHandlerStructure::
1085 QueryField(type,j).key ) )
1098 //=====================================================================
1100 //=====================================================================
1101 std::string SQLiteTreeHandler::DBGetNodeId(Node* node,
1102 const std::string& parent_id)
1104 // std::cout << "SQLiteTreeHandler::DBGetNodeId('"<<node->GetLabel()
1105 // <<"','"<<parent_id<<"')"
1108 int type = node->GetType();
1110 std::string table = SQLiteTreeHandlerStructure::Table(type);
1111 std::string where = "WHERE ";
1113 if (type!=Node::Patient)
1115 where += "PARENT_ID='" + parent_id
1116 //node->GetFieldValue("PARENT_ID")
1120 for (int i=0;i<SQLiteTreeHandlerStructure::NbQueryFields(type);i++)
1122 where += SQLiteTreeHandlerStructure::QueryField(type,i).key + "='"
1123 + node->GetFieldValue(SQLiteTreeHandlerStructure::QueryField(type,i).key) + "' ";
1124 if (i<SQLiteTreeHandlerStructure::NbQueryFields(type)-1)
1128 std::string query = "SELECT ID FROM " + table + " " + where + ";";
1129 // std::cout << "** SQL = '"<<query<<"'"<<std::endl;
1136 // std::cout << " - Node exists " << std::endl;
1137 std::string id = q.getStringField(0);
1138 // std::cout << " id = '"<<id<<"'"<<std::endl;
1145 //=====================================================================
1149 //=====================================================================
1150 Node* SQLiteTreeHandler::GetNodeFromTypeId(Node::Type type,
1151 const std::string& id)
1153 // std::cout << "GetNodeFromTypeId("<<type<<","<<id<<")"<<std::endl;
1159 TypeIdToNodeMapType::iterator i = mTypeIdToNodeMap.find(ti);
1160 if (i == mTypeIdToNodeMap.end())
1163 std::cout << "Internal error : mTypeIdToNodeMap does not contain key"
1165 creaError("Internal error : mTypeIdToNodeMap does not contain key");
1169 // std::cout << " ** Node = "<<i->second<<std::endl;
1173 //=====================================================================
1175 //=====================================================================
1176 bool SQLiteTreeHandler::Remove(Node* node)
1179 //DBRecursiveRemoveNode(node);
1181 // std::cout << "DELETE"<<std::endl;
1182 if (node->GetParent())
1184 node->GetParent()->RemoveChildrenFromList(node);
1187 // std::cout << "DELETE OK"<<std::endl;
1192 //========================================================================
1194 //=====================================================================
1195 void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
1197 // std::cout << "SQLiteTreeHandler::DBRecursiveRemoveNode('"
1198 // <<node->GetLabel()<<"')"<<std::endl;
1200 std::string query = "DELETE FROM ";
1201 query += SQLiteTreeHandlerStructure::Table(node->GetType());
1202 query += " WHERE ID='"+ node->GetFieldValue("ID") + "';";
1206 Node::ChildrenListType::iterator i;
1207 for (i = node->GetChildrenList().begin();
1208 i != node->GetChildrenList().end();
1211 DBRecursiveRemoveNode((*i));
1215 //=====================================================================
1217 //=====================================================================
1218 int SQLiteTreeHandler::DBQueryNumberOfChildren(Node* node)
1220 std::string query = "SELECT COUNT (ID) FROM ";
1221 query += SQLiteTreeHandlerStructure::Table(node->GetType()+1);
1222 if (node->GetType() != Node::Database)
1224 query += " WHERE PARENT_ID='"+ node->GetFieldValue("ID")+"'";
1228 // std::cout << "**SQL = "<< query << std::endl;
1233 // std::cout << "**RES = "<< q.getIntField(0) <<std::endl;
1235 return q.getIntField(0);
1237 //=====================================================================
1245 } // namespace creaImageIO