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 //=====================================================================
191 //=====================================================================
192 /// Sets an attribute
193 void SQLiteTreeHandler::SetAttribute(const std::string& levelDescriptor,
194 const std::string& key,
195 const std::string& value,
196 const std::string& searchParam,
197 const std::string& searchVal)
199 DBSetAttribute(levelDescriptor,key,value,searchParam, searchVal);
201 //=====================================================================
203 void SQLiteTreeHandler::DeleteTuple(std::string levelDescriptor,
204 std::string key, std::string value)
206 DBDelete(levelDescriptor,key,value);
208 //=====================================================================
222 //=====================================================================
223 // SQLite DB specific methods
224 //=====================================================================
229 //=====================================================================
230 char* format_sql(const std::string& s)
232 return sqlite3_mprintf("%q",s.c_str());
234 //=====================================================================
236 // sqlite3_exec(db, zSQL, 0, 0, 0);
237 // sqlite3_free(zSQL);
238 // char* CHAIN = format_sql(QUER); \
239 // sqlite3_free(CHAIN); \
241 //=====================================================================
242 #define QUERYDB(QUER,RES) \
245 GimmickMessage(2,"SQL query: '"<<QUER<<"'"<<std::endl); \
246 RES = mDB->execQuery(QUER.c_str()); \
248 catch (CppSQLite3Exception& e) \
250 GimmickError("SQLite query '"<<QUER<<"' : " \
251 << e.errorCode() << ":" \
252 << e.errorMessage() ); \
255 //=====================================================================
257 //=====================================================================
258 #define UPDATEDB(UP) \
261 GimmickMessage(2,"SQL update: '"<<UP<<"'"<<std::endl); \
262 mDB->execDML(UP.c_str()); \
264 catch (CppSQLite3Exception& e) \
266 GimmickError("SQLite update '"<<UP<<"' Error : " \
267 << e.errorCode() << ":" \
268 << e.errorMessage() ); \
270 //=====================================================================
273 //=====================================================================
274 bool SQLiteTreeHandler::DBOpen()
276 GimmickMessage(1,"Opening SQLite database '"<<GetFileName()
277 <<"' ... "<<std::endl);
279 if (!boost::filesystem::exists(GetFileName()))
286 mDB->open(GetFileName().c_str());
288 catch (CppSQLite3Exception& e)
290 GimmickError("Opening '"<<GetFileName()<<"' : "
291 << e.errorCode() << ":"
292 << e.errorMessage());
295 // IMPORT TREE DESCRIPTION (AND TEST DB VALIDITY)
296 if (!DBImportTreeDescription())
301 GimmickDebugMessage(1,"Opening SQLite database '"<<GetFileName()
302 <<"' ... OK"<<std::endl);
305 //=====================================================================
307 //=====================================================================
308 bool SQLiteTreeHandler::DBCreate()
310 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
311 <<"' ... "<<std::endl);
313 if (boost::filesystem::exists(GetFileName()))
315 GimmickError(GetFileName()<<"' : "
316 << "file already exists");
323 mDB->open(GetFileName().c_str());
325 catch (CppSQLite3Exception& e)
327 GimmickError(e.errorCode() << ":"
328 << e.errorMessage() <<std::endl);
336 // Create LEVELS table
337 command = "create table LEVELS\n";
338 command += "( Name text )\n";
341 // Iterate the Levels
342 for (int l=0; l<GetTree().GetNumberOfLevels(); ++l)
344 command = "INSERT INTO LEVELS (Name) VALUES ('";
345 command += GetTree().GetLevelDescriptor(l).GetName();
349 // Create table of level (for level>0, i.e. not Root)
352 command = "CREATE TABLE ";
353 command += GetTree().GetLevelDescriptor(l).GetName();
354 command += "\n(\nID INTEGER PRIMARY KEY";
357 command += ",\nPARENT_ID int not null";
359 SQLAppendAttributesDefinition(l,command);
362 command += ",\nconstraint FK_PARENT foreign key (PARENT_ID) references ";
363 command += GetTree().GetLevelDescriptor(l-1).GetName();
364 command += "(ID) on delete restrict on update restrict";
370 // Add Attribute 'ID' to Description
371 GetTree().GetDescriptor().Add
372 (AttributeDescriptor( "ID",
373 "Database Identifier",
375 AttributeDescriptor::PRIVATE
380 // Add Attribute 'PARENT_ID' to Description
381 GetTree().GetDescriptor().Add
382 (AttributeDescriptor( "PARENT_ID",
383 "Database Parent Identifier",
385 AttributeDescriptor::PRIVATE
391 // Create table *_ATTRIBUTES
393 command = "CREATE TABLE ";
394 command += GetTree().GetLevelDescriptor(l).GetName();
395 command += "_Attributes\n(\n";
396 command += "Key text,\n";
397 command += "Name text,\n";
398 command += "DicomGroup int,\n";
399 command += "DicomElement int,\n";
400 command += "Flags int\n";
405 // Fill the table *_ATTRIBUTES
406 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
407 for (i = GetTree().GetAttributeDescriptorList(l).begin();
408 i != GetTree().GetAttributeDescriptorList(l).end();
412 std::stringstream insert;
413 insert << "INSERT INTO "
414 << GetTree().GetLevelDescriptor(l).GetName()
415 << "_Attributes (Key,Name,DicomGroup,DicomElement,Flags) "
417 << i->GetKey() << "','"
418 << i->GetName() << "',"
419 << i->GetGroup() << ","
420 << i->GetElement() << ","
421 << i->GetFlags() << ");";
422 UPDATEDB(insert.str());
427 // Initialize the root attributes
428 GetTree().InitializeAttributeMap();
429 // Insert the root in the level 0 table
430 DBInsert(GetTree().GetTree());
433 GetTree().SetChildrenLoaded(true);
434 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
435 <<"' ... OK"<<std::endl);
438 //=====================================================================
440 //=====================================================================
441 void SQLiteTreeHandler::SQLAppendAttributesDefinition(int level,
444 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
445 for (i = GetTree().GetAttributeDescriptorList(level).begin();
446 i != GetTree().GetAttributeDescriptorList(level).end();
449 // if (i->second.flags==1) continue;
455 //=====================================================================
458 //=====================================================================
459 bool SQLiteTreeHandler::DBImportTreeDescription()
461 GimmickMessage(1,"Importing tree description from database ..."
464 // Test table 'LEVELS' existence
465 if ( ! mDB->tableExists("LEVELS") )
467 GimmickMessage(1,"!! ERROR : Table 'LEVELS' does not exist"
472 tree::Descriptor& desc = GetTree().GetDescriptor();
473 // clears the existing one
477 std::string query = "SELECT * FROM LEVELS";
483 std::string name = q.getStringField(0);
484 GimmickMessage(2," * Importing level '"<<name<<"'"<<std::endl);
485 desc.Add(LevelDescriptor(name));
490 for (int level = 0; level < nblevel; ++level )
492 std::string table = GetTree().GetLevelDescriptor(level).GetName();
493 table += "_Attributes";
494 // Test table 'LEVELS' existence
495 if ( ! mDB->tableExists(table.c_str()) )
497 GimmickMessage(1,"!! ERROR : Table '"<<table<<"' does not exist"
502 std::string query = "SELECT * FROM ";
507 GimmickMessage(2," * Level '"
508 <<GetTree().GetLevelDescriptor(level).GetName()
511 // Test that ID and PARENT_ID mandatory attributes exist
512 bool ID_found = false;
513 bool PARENT_ID_found = false;
514 if (level==0) ID_found = true;
515 if (level<=1) PARENT_ID_found = true;
519 std::string key(q.getStringField(0));
520 std::string name(q.getStringField(1));
521 GimmickMessage(2," - Importing attribute '"<<key<<"' '"<<name
524 (AttributeDescriptor( key, // Key
526 q.getIntField(2), // Group
527 q.getIntField(3), // Element
528 q.getIntField(4) // Flags
534 if ( key == "PARENT_ID" )
536 PARENT_ID_found = true;
541 if ( ! (ID_found || PARENT_ID_found ) )
543 GimmickMessage(1,"!! ERROR : Table '"<<table
544 <<"' does not contain mandatory attribute ID or PARENT_ID"
552 // Create the attributes table for Root (i.e. Tree)
553 LevelDescriptor::AttributeDescriptorListType::const_iterator a;
554 for (a = GetTree().GetAttributeDescriptorList(0).begin();
555 a!= GetTree().GetAttributeDescriptorList(0).end();
560 AttributeMapType::const_iterator i = attr.find(a->GetKey());
561 if ( i != attr.end() )
566 GetTree().UnsafeSetAttribute( a->GetKey(), "" );
569 // Reading Root attributes
571 query = "SELECT * FROM ";
572 query += GetTree().GetLevelDescriptor(0).GetName();
575 for (int fld = 0; fld < q.numFields(); fld++)
577 GetTree().UnsafeSetAttribute(q.fieldName(fld),
578 q.getStringField(fld));
581 GimmickMessage(1,"Importing tree description from database ... OK"
585 //=====================================================================
603 //========================================================================
605 std::string& SQLformat(std::string& str)
607 // quote must be doubled
608 boost::algorithm::replace_all(str,"'","''");
609 // Found strange strings which contained NULL char INSIDE string
610 int i,size=str.size();
615 str = str.substr(0,i);
622 //========================================================================
624 //=====================================================================
625 void SQLiteTreeHandler::SQLAppendAttributesValues(tree::Node* n,
628 GimmickMessage(4,"SQLAppendAttributesValues"<<std::endl);
630 std::string values="";
631 tree::Node::AttributeMapType::iterator i;
632 for (i = n->GetAttributeMap().begin();
633 i != n->GetAttributeMap().end();
640 // std::cout << "("<<i->first<<","<<i->second<<")"<<std::endl;
641 atts += "'" + i->first + "'";
642 values += "'" + SQLformat(i->second) + "'";
645 GimmickMessage(4,"'"<<i->first<<"' = '"<<i->second<<"'"<<std::endl);
647 atts[atts.size()-1]=' ';
648 values[values.size()-1]=' ';
650 str = "("+atts+") VALUES ("+values+")";
651 GimmickMessage(4,"Result = '"<<str<<"'"<<std::endl);
653 //=====================================================================
655 //=====================================================================
656 tree::Node* SQLiteTreeHandler::DBGetParent( const AttributeMapType& attr)
658 Node* parent = GetTree().GetTree();
663 // Load the children of the current parent
664 DBLoadChildren(parent);
665 // Iterate the children
666 tree::Node::ChildrenListType::const_iterator i;
667 for (i = parent->GetChildrenList().begin();
668 i!= parent->GetChildrenList().end();
671 if ( (*i)->Matches( attr ) )
682 //=====================================================================
685 //=====================================================================
686 int SQLiteTreeHandler::DBLoadChildren(tree::Node* node,
689 if (node->GetLevel()+1 >= node->GetTree()->GetNumberOfLevels() )
692 GimmickMessage(2,"Loading children of '"<<node->GetLabel()
696 // If children loaded we do not have to do it but we need to recurse
697 // in order to load the children's children if necessary, and so on...
698 if (node->GetChildrenLoaded())
700 // Iterate the children
702 tree::Node::ChildrenListType::iterator i;
703 for (i = node->GetChildrenList().begin();
704 i!= node->GetChildrenList().end();
707 nbloaded += DBLoadChildren(*i,numberoflevels-1);
709 node->SetChildrenLoaded(true);
715 /// If children not loaded : do it and recurse
718 int level = node->GetLevel();
719 std::string query = "SELECT * FROM ";
721 query += GetTree().GetLevelDescriptor(level+1).GetName();
724 query += " WHERE PARENT_ID='" + node->UnsafeGetAttribute("ID")
734 // std::cout << "DBLoadCh : creating node level "<<level+1<<std::endl;
737 Node* n = new Node(node);
738 for (int fld = 0; fld < q.numFields(); fld++)
740 n->UnsafeSetAttribute(q.fieldName(fld),q.getStringField(fld));
746 ti.id = n->GetFieldValue("ID");
747 mTypeIdToNodeMap[ti] = n;
750 if ( numberoflevels != 1 )
753 nbloaded += DBLoadChildren(n, numberoflevels-1);
760 node->SetChildrenLoaded(true);
767 //=====================================================================
769 //======================================================================
770 void SQLiteTreeHandler::DBInsert(tree::Node* n)
772 GimmickMessage(2,"Inserting in DB '"<<n->GetLabel()
775 SQLAppendAttributesValues(n,val);
776 std::string insert("INSERT INTO ");
777 insert += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
778 insert += " " + val + ";";
782 // Store DB id of newly created node;
783 long lastrow = mDB->lastRowId();
784 std::stringstream ri;
785 ri << mDB->lastRowId();
786 n->SetAttribute("ID",ri.str());
788 //======================================================================
790 //======================================================================
791 /// Graft the branch defined by the attributes to the parent
792 void SQLiteTreeHandler::DBGraftToParent( tree::Node* parent,
793 const AttributeMapType& attr)
795 // std::cout <<"Grafting to parent '"<<parent->GetLabel()
798 for (int level = parent->GetLevel()+1;
799 level < GetTree().GetNumberOfLevels();
803 tree::Node* child = new tree::Node(parent,attr);
804 child->SetChildrenLoaded(true);
807 int nc = GetNumberOfChildren(parent)+1;
809 // std::cout<<"Number of children "<<parent->GetNumberOfChildren()<<std::endl;
810 std::stringstream out;
812 SetAttribute(parent,"NumberOfChildren",out.str());
815 // Set PARENT_ID if necessary
816 if ( parent->GetLevel()>0 )
817 child->SetAttribute("PARENT_ID",parent->GetAttribute("ID"));
823 SQLAppendAttributesValues(child,val);
824 std::string insert("INSERT INTO ");
825 insert += GetTree().GetLevelDescriptor(child->GetLevel()).GetName();
826 insert += " " + val + ";";
829 // Store DB id of newly created node;
830 long lastrow = mDB->lastRowId();
831 std::stringstream ri;
832 ri << mDB->lastRowId();
833 child->SetAttribute("ID",ri.str());
839 // Insert in TypeId map
841 ti.type = node->GetType();
843 mTypeIdToNodeMap[ti] = node;
844 // std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl;
848 if (node->GetType()==Node::Patient) summary.added_patients++;
849 if (node->GetType()==Node::Study) summary.added_studies++;
850 if (node->GetType()==Node::Series) summary.added_series++;
851 if (node->GetType()==Node::Image) summary.added_images++;
855 //======================================================================
858 //=====================================================================
859 /// Sets an attribute of a Node
860 bool SQLiteTreeHandler::DBSetAttribute(tree::Node* n,
861 const std::string& key,
862 const std::string& value)
864 GimmickMessage(3,"Setting Attribute of '"<<n->GetLabel()<<
865 "' "<<key<<"='"<<value<<"'"<<std::endl);
867 n->SetAttribute(key,value);
868 std::string sql = "UPDATE ";
869 sql += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
874 sql += "' WHERE ID=";
875 sql += n->GetAttribute("ID");
876 // sql += " LIMIT 1";
880 //=====================================================================
881 /// Sets an attribute of a Node
882 void SQLiteTreeHandler::DBSetAttribute(const std::string& levelDescriptor,
883 const std::string& key,
884 const std::string& value,
885 const std::string& searchParam,
886 const std::string& searchVal)
889 std::string sql = "UPDATE ";
890 sql += levelDescriptor;
902 //=====================================================================
903 void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
906 std::string query = "DELETE FROM ";
908 query += GetTree().GetLevelDescriptor(node->GetLevel()).GetName();
909 query += " WHERE ID='"+ node->GetAttribute("ID") + "';";
912 GimmickDebugMessage(2,
914 <<node->GetLabel()<<"' with ID '"
915 <<node->GetAttribute("ID")
916 <<"' in level "<< GetTree().GetLevelDescriptor(node->GetLevel()).GetName()
919 Node::ChildrenListType::iterator i;
920 for (i = node->GetChildrenList().begin();
921 i != node->GetChildrenList().end();
924 DBRecursiveRemoveNode((*i));
928 //=====================================================================
929 void SQLiteTreeHandler::DBDelete(std::string levelDescriptor, std::string key, std::string value)
932 std::stringstream query;
933 query<<"DELETE FROM "<<levelDescriptor<<" WHERE "<<key<<"='"<<value<<"';";
935 UPDATEDB(query.str());
936 GimmickMessage(1," Deleting: Query: "<<query.str()<<std::endl);
940 //=====================================================================
941 void SQLiteTreeHandler::GetAttribute(std::string levelDescriptor,
942 std::string searchParam,
943 std::string searchVal,
947 std::stringstream out;
948 std::stringstream results;
949 out<<"SELECT "<<key<<" FROM "<<levelDescriptor;
952 out<<" WHERE "<<searchParam<<"='"<<searchVal<<"'";
956 QUERYDB(out.str(),q);
961 for (int fld = 0; fld < q.numFields(); fld++)
963 results<<q.getStringField(fld);
971 result=results.str();
974 //=====================================================================
975 unsigned int SQLiteTreeHandler::GetNumberOfChildren(tree::Node* n)
979 int level = n->GetLevel();
981 if(level<GetTree().GetNumberOfLevels()&& level>0)
983 std::string query = "SELECT NumberOfChildren FROM ";
984 query += GetTree().GetLevelDescriptor(level).GetName();
987 query += " WHERE ID='" + n->UnsafeGetAttribute("ID")
996 for (int fld = 0; fld < q.numFields(); fld++)
998 nb=q.getIntField(fld);
1013 //=====================================================================
1014 bool SQLiteTreeHandler::DBInsert(Node* alien_node,
1015 UpdateSummary& summary)
1017 // std::cout << "SQLiteTreeHandler::Insert('"<<alien_node->GetLabel()
1018 // <<"')"<<std::endl;
1020 // if (!ChildrenLoaded()) DBLoadChildren(this,Node::Database);
1024 std::string parent_id;
1025 parent = DBGetOrCreateParent(alien_node,parent_id,summary);
1028 DBRecursiveGetOrCreateNode(alien_node,parent,parent_id,summary);
1031 //=====================================================================
1034 //=====================================================================
1035 Node* SQLiteTreeHandler::DBGetOrCreateParent(Node* alien_node,
1036 std::string& parent_id,
1037 UpdateSummary& summary)
1039 // std::cout << "DBGetOrCreateParent '" << alien_node->GetLabel()<<"'"
1041 // Load the patients if not already done
1042 DBLoadChildren(this,Node::Patient);
1045 Node* parent = this;
1047 // The chain of ancestors
1048 std::deque<Node*> chain;
1049 Node* cur = alien_node->GetParent();
1050 for (int type=Node::Patient;
1051 type<alien_node->GetType();++type)
1053 chain.push_front(cur);
1054 cur = cur->GetParent();
1057 // create the nodes if do not exist
1058 std::deque<Node*>::iterator i;
1059 for (i=chain.begin();i!=chain.end();++i)
1061 // std::cout << " cur = '"<<(*i)->GetLabel()<<"'"<<std::endl;
1062 // std::string cur_id = DBGetNodeId(*i,parent_id);
1063 // if (cur_id.size()==0)
1065 // Node does not exist : create it
1067 parent = DBGetOrCreateNode(*i,
1073 DBLoadChildren(parent,parent->GetType()+1);
1079 //=====================================================================
1083 //=====================================================================
1084 void SQLiteTreeHandler::DBRecursiveGetOrCreateNode(Node* alien_node,
1086 const std::string& parent_id,
1087 UpdateSummary& summary)
1089 // std::cout << "SQLiteTreeHandler::RecursiveGetOrCreateNode('"
1090 // <<alien_node->GetLabel()
1091 // <<"','"<<parent<<"','"<<parent_id<<"')"<<std::endl;
1094 // std::cout << " -- Parent = '"<<parent->GetLabel()<<"'"<<std::endl;
1097 Node* new_node = DBGetOrCreateNode(alien_node,
1102 Node::ChildrenListType::iterator i;
1103 for (i = alien_node->GetChildrenList().begin();
1104 i != alien_node->GetChildrenList().end();
1107 DBRecursiveGetOrCreateNode((*i),new_node,new_id,summary);
1110 //=====================================================================
1113 //=====================================================================
1114 Node* SQLiteTreeHandler::DBGetOrCreateNode(Node* alien_node,
1115 Node* internal_parent,
1116 std::string parent_id,
1117 std::string& node_id,
1118 UpdateSummary& summary)
1120 // std::cout << "DBGetOrCreateNode('"<<alien_node->GetLabel()<<"','"
1121 // << internal_parent << "','"<< parent_id<<"')"<<std::endl;
1122 if (internal_parent != 0)
1124 // std::cout << " -- Parent = '"<<internal_parent->GetLabel()<<"'"<<std::endl;
1126 // Node Exists ? return it
1127 // First try among children of internal parent
1128 Node* node = GetChildrenLike(internal_parent,alien_node);
1131 node_id = node->UnsafeGetFieldValue("ID");
1134 // Second : try in DB
1136 // Does not exist : Create new one
1137 node = new Node(alien_node->GetType(),this,internal_parent);
1138 node->SetChildrenLoaded(true);
1139 // Copy fields values from alien
1140 Node::FieldValueMapType::iterator i,j;
1141 for (i = node->GetFieldValueMap().begin();
1142 i != node->GetFieldValueMap().end();
1145 j = alien_node->GetFieldValueMap().find(i->first);
1146 if (j != alien_node->GetFieldValueMap().end() )
1148 i->second = j->second;
1153 if (node->GetType()!=Node::Patient)
1154 node->SetFieldValue("PARENT_ID",parent_id);
1158 BuildSQLFieldsValues(node,val);
1159 std::string insert("INSERT INTO ");
1160 insert += std::string(SQLiteTreeHandlerStructure::Table(node->GetType()))
1162 // std::cout << "** SQL = '"<<insert<<"'"<<std::endl;
1164 // std::cout << "** SQL OK"<<std::endl;
1166 // Store DB id of newly created node;
1167 long lastrow = mDB->lastRowId();
1168 std::stringstream ri;
1169 ri << mDB->lastRowId();
1171 // std::cout << "LastRowId='"<<mDB->lastRowId()<<"' vs '"<<created_id<<"'"<<std::endl;
1173 node->SetFieldValue("ID",node_id);
1174 // Insert in TypeId map
1176 ti.type = node->GetType();
1178 mTypeIdToNodeMap[ti] = node;
1179 // std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl;
1183 if (node->GetType()==Node::Patient) summary.added_patients++;
1184 if (node->GetType()==Node::Study) summary.added_studies++;
1185 if (node->GetType()==Node::Series) summary.added_series++;
1186 if (node->GetType()==Node::Image) summary.added_images++;
1190 //=====================================================================
1192 //=====================================================================
1193 Node* SQLiteTreeHandler::GetChildrenLike(Node* parent,
1196 Node::ChildrenListType::iterator i;
1197 for (i = parent->GetChildrenList().begin();
1198 i != parent->GetChildrenList().end();
1201 Node::Type type = alien_node->GetType();
1204 j<SQLiteTreeHandlerStructure::NbQueryFields(type);
1208 alien_node->GetFieldValue(SQLiteTreeHandlerStructure::
1209 QueryField(type,j).key ) !=
1210 (*i)->GetFieldValue(SQLiteTreeHandlerStructure::
1211 QueryField(type,j).key ) )
1224 //=====================================================================
1226 //=====================================================================
1227 std::string SQLiteTreeHandler::DBGetNodeId(Node* node,
1228 const std::string& parent_id)
1230 // std::cout << "SQLiteTreeHandler::DBGetNodeId('"<<node->GetLabel()
1231 // <<"','"<<parent_id<<"')"
1234 int type = node->GetType();
1236 std::string table = SQLiteTreeHandlerStructure::Table(type);
1237 std::string where = "WHERE ";
1239 if (type!=Node::Patient)
1241 where += "PARENT_ID='" + parent_id
1242 //node->GetFieldValue("PARENT_ID")
1246 for (int i=0;i<SQLiteTreeHandlerStructure::NbQueryFields(type);i++)
1248 where += SQLiteTreeHandlerStructure::QueryField(type,i).key + "='"
1249 + node->GetFieldValue(SQLiteTreeHandlerStructure::QueryField(type,i).key) + "' ";
1250 if (i<SQLiteTreeHandlerStructure::NbQueryFields(type)-1)
1254 std::string query = "SELECT ID FROM " + table + " " + where + ";";
1255 // std::cout << "** SQL = '"<<query<<"'"<<std::endl;
1262 // std::cout << " - Node exists " << std::endl;
1263 std::string id = q.getStringField(0);
1264 // std::cout << " id = '"<<id<<"'"<<std::endl;
1271 //=====================================================================
1275 //=====================================================================
1276 Node* SQLiteTreeHandler::GetNodeFromTypeId(Node::Type type,
1277 const std::string& id)
1279 // std::cout << "GetNodeFromTypeId("<<type<<","<<id<<")"<<std::endl;
1285 TypeIdToNodeMapType::iterator i = mTypeIdToNodeMap.find(ti);
1286 if (i == mTypeIdToNodeMap.end())
1289 std::cout << "Internal error : mTypeIdToNodeMap does not contain key"
1291 creaError("Internal error : mTypeIdToNodeMap does not contain key");
1295 // std::cout << " ** Node = "<<i->second<<std::endl;
1299 //=====================================================================
1301 //=====================================================================
1302 bool SQLiteTreeHandler::Remove(Node* node)
1305 //DBRecursiveRemoveNode(node);
1307 // std::cout << "DELETE"<<std::endl;
1308 if (node->GetParent())
1310 node->GetParent()->RemoveChildrenFromList(node);
1313 // std::cout << "DELETE OK"<<std::endl;
1318 //========================================================================
1320 //=====================================================================
1321 void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
1323 // std::cout << "SQLiteTreeHandler::DBRecursiveRemoveNode('"
1324 // <<node->GetLabel()<<"')"<<std::endl;
1326 std::string query = "DELETE FROM ";
1327 query += SQLiteTreeHandlerStructure::Table(node->GetType());
1328 query += " WHERE ID='"+ node->GetFieldValue("ID") + "';";
1332 Node::ChildrenListType::iterator i;
1333 for (i = node->GetChildrenList().begin();
1334 i != node->GetChildrenList().end();
1337 DBRecursiveRemoveNode((*i));
1341 //=====================================================================
1343 //=====================================================================
1344 int SQLiteTreeHandler::DBQueryNumberOfChildren(Node* node)
1346 std::string query = "SELECT COUNT (ID) FROM ";
1347 query += SQLiteTreeHandlerStructure::Table(node->GetType()+1);
1348 if (node->GetType() != Node::Database)
1350 query += " WHERE PARENT_ID='"+ node->GetFieldValue("ID")+"'";
1354 // std::cout << "**SQL = "<< query << std::endl;
1359 // std::cout << "**RES = "<< q.getIntField(0) <<std::endl;
1361 return q.getIntField(0);
1363 //=====================================================================
1371 } // namespace creaImageIO