]> Creatis software - creaImageIO.git/blob - src2/creaImageIOSQLiteTreeHandler.cpp
*** empty log message ***
[creaImageIO.git] / src2 / creaImageIOSQLiteTreeHandler.cpp
1 #include <creaImageIOSQLiteTreeHandler.h>
2 #include <creaImageIOSystem.h>
3
4 #include "CppSQLite3.h"
5
6 #include <sys/stat.h>
7
8 //#include <creaImageIOSQLiteTreeHandlerStructure.h>
9
10 //#include <creaImageIOUtilities.h>
11
12 //#include <icons/database.xpm>
13
14 #include <deque>
15
16 #include "wx/wx.h"
17 #include <wx/dir.h>
18 #include <wx/filename.h>
19
20
21 //#include <icons/close.xpm>
22
23 #include <creaWx.h>
24 using namespace crea;
25
26 #include <boost/filesystem.hpp>
27 #include <boost/algorithm/string/replace.hpp>
28
29 namespace creaImageIO
30 {
31   using namespace tree;
32
33
34   //=============================================================
35   SQLiteTreeHandler::SQLiteTreeHandler(const std::string& filename)
36     : mFileName(filename)
37   {
38     mDB = new CppSQLite3DB;
39     GimmickMessage(1,"SQLite version : "
40                    <<std::string(mDB->SQLiteVersion())<< std::endl);
41   }
42   //=============================================================
43
44   //=============================================================
45   SQLiteTreeHandler::~SQLiteTreeHandler()
46   {
47     delete mDB;
48   }
49   //=============================================================
50   
51
52   //=============================================================
53   //  void SQLiteTreeHandler::Print() const 
54   //  {
55     /*
56     std::cout << "-> '"<<GetName()<< "' - '"
57               << GetFileName()<<"'"<<std::endl;
58     ChildrenListType::const_iterator i;
59     for (i=GetChildrenList().begin(); i!=GetChildrenList().end(); i++)
60       {
61         (*i)->Print();
62       }
63     */
64   //  }
65   //=============================================================
66   
67   //=====================================================================
68   /*
69   bool SQLiteTreeHandler::LocationIsValid()
70   {
71     // TO DO 
72     return true;
73   }
74   */
75   //=====================================================================
76
77
78   //=====================================================================
79   bool SQLiteTreeHandler::Open(bool writable)
80   {
81     //    std::cout << "***> SQLiteTreeHandler::Open('"<<GetFileName()<<"')"<<std::endl;
82     SetWritable(writable);
83     return DBOpen();
84   }
85
86   //=====================================================================
87   bool SQLiteTreeHandler::Create(bool writable)
88   {
89     //    std::cout << "***> SQLiteTreeHandler::New('"<<GetFileName()<<"')"<<std::endl;
90     SetWritable(writable);
91     return DBCreate();
92   }
93   //=====================================================================
94
95
96   //=====================================================================
97   bool SQLiteTreeHandler::Close()
98   {
99     return true;
100   }
101   //=====================================================================
102
103
104   //=====================================================================
105   bool SQLiteTreeHandler::Destroy()
106   {
107     return false;
108   }
109   //=====================================================================
110
111   //===================================================================== 
112   unsigned int SQLiteTreeHandler::GetNumberOfChildren(tree::Node* n) 
113   { 
114     return 0; 
115   }
116   //===================================================================== 
117
118   //===================================================================== 
119   int SQLiteTreeHandler::LoadChildren(tree::Node* parent, int maxlevel)
120   {
121     if (parent==0) parent = GetTree().GetTree();
122     return DBLoadChildren(parent,maxlevel);
123   }
124   //===================================================================== 
125
126
127
128
129   //===================================================================== 
130   void SQLiteTreeHandler::UnLoad(tree::Node* n)
131   {
132   }
133   //===================================================================== 
134
135
136   //===================================================================== 
137   int SQLiteTreeHandler::AddBranch( const AttributeMapType& attr )
138   {
139     tree::Node* parent = DBGetParent(attr);
140     DBGraftToParent(parent,attr);
141     return (parent->GetLevel()+1);
142   }
143   //===================================================================== 
144  
145
146   //===================================================================== 
147    bool SQLiteTreeHandler::Remove(tree::Node*)
148    {
149      return false;
150    }
151   //===================================================================== 
152
153   //===================================================================== 
154   /// Sets an attribute of a Node
155   bool SQLiteTreeHandler::SetAttribute(tree::Node* n, 
156                                        const std::string& key,
157                                        const std::string& value)
158   {
159     if (n==0) n=GetTree().GetTree();
160     return DBSetAttribute(n,key,value);
161   }
162   //===================================================================== 
163
164
165
166
167
168
169
170
171
172
173
174
175
176   //=====================================================================
177   // SQLite DB specific methods
178   //=====================================================================
179
180
181
182
183   //=====================================================================
184   char* format_sql(const std::string& s)
185   { 
186     return sqlite3_mprintf("%q",s.c_str());
187   }
188   //=====================================================================
189
190   //  sqlite3_exec(db, zSQL, 0, 0, 0);
191   //  sqlite3_free(zSQL);
192   //    char* CHAIN = format_sql(QUER);         \
193 //  sqlite3_free(CHAIN);                                \
194
195   //=====================================================================
196 #define QUERYDB(QUER,RES)                                               \
197     try                                                                 \
198       {                                                                 \
199         GimmickMessage(2,"SQL query: '"<<QUER<<"'"<<std::endl);         \
200         RES = mDB->execQuery(QUER.c_str());                             \
201       }                                                                 \
202     catch (CppSQLite3Exception& e)                                      \
203       {                                                                 \
204         GimmickError("SQLite query '"<<QUER<<"' : "                     \
205                      << e.errorCode() << ":"                            \
206                      << e.errorMessage() );                             \
207       }                                                                 \
208     
209   //=====================================================================
210   
211   //=====================================================================
212 #define UPDATEDB(UP)                                                    \
213   try                                                                   \
214     {                                                                   \
215       GimmickMessage(2,"SQL update: '"<<UP<<"'"<<std::endl);            \
216       mDB->execDML(UP.c_str());                                         \
217     }                                                                   \
218   catch (CppSQLite3Exception& e)                                        \
219     {                                                                   \
220       GimmickError("SQLite update '"<<UP<<"' Error : "                  \
221                    << e.errorCode() << ":"                              \
222                    << e.errorMessage() );                               \
223     }                                                                   
224   //=====================================================================
225
226
227   //=====================================================================
228   bool SQLiteTreeHandler::DBOpen()
229   {
230     GimmickMessage(1,"Opening SQLite database '"<<GetFileName()
231                    <<"' ... "<<std::endl);
232     // OPENING FILE
233     if (!boost::filesystem::exists(GetFileName())) 
234       {
235         return false;
236       }
237
238     try
239       {
240         mDB->open(GetFileName().c_str());
241       }
242     catch (CppSQLite3Exception& e)
243       {
244         GimmickError("Opening '"<<GetFileName()<<"' : "
245                      << e.errorCode() << ":" 
246                      << e.errorMessage());
247         return false;
248       }
249     // IMPORT TREE DESCRIPTION (AND TEST DB VALIDITY)
250     if (!DBImportTreeDescription())
251       {
252         return false;
253       }
254
255     GimmickDebugMessage(1,"Opening SQLite database '"<<GetFileName()
256                    <<"' ... OK"<<std::endl);
257     return true;
258   }
259   //=====================================================================
260
261   //=====================================================================
262   bool SQLiteTreeHandler::DBCreate()
263   {
264     GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
265                    <<"' ... "<<std::endl);
266
267     if (boost::filesystem::exists(GetFileName())) 
268       {
269         GimmickError(GetFileName()<<"' : "
270                      << "file already exists");
271         return false;
272       }
273     
274     // OPENING
275     try
276       {
277         mDB->open(GetFileName().c_str());
278       }
279     catch (CppSQLite3Exception& e)
280       {
281         GimmickError(e.errorCode() << ":" 
282                      << e.errorMessage() <<std::endl);
283         return false;
284       }
285     
286      
287     // CREATING TABLES
288     
289     std::string command;
290     // Create LEVELS table
291     command = "create table LEVELS\n";
292     command += "( Name text )\n";
293     UPDATEDB(command);
294     
295     // Iterate the Levels
296     for (int l=0; l<GetTree().GetNumberOfLevels(); ++l)
297       {
298         command = "INSERT INTO LEVELS (Name) VALUES ('";
299         command += GetTree().GetLevelDescriptor(l).GetName();
300         command += "')";
301         UPDATEDB(command);
302         
303         // Create table of level (for level>0, i.e. not Root)
304         if (l>=0)
305           {
306             command = "CREATE TABLE ";
307             command += GetTree().GetLevelDescriptor(l).GetName();
308             command += "\n(\nID INTEGER PRIMARY KEY";
309             if (l>1) 
310               {
311                 command += ",\nPARENT_ID int not null"; 
312               }
313             SQLAppendAttributesDefinition(l,command);
314             if (l>1) 
315               {
316                 command += ",\nconstraint FK_PARENT foreign key (PARENT_ID) references ";
317                 command += GetTree().GetLevelDescriptor(l-1).GetName();
318                 command += "(ID) on delete restrict on update restrict";
319               }
320             command += "\n)";
321             UPDATEDB(command);
322             
323             
324             // Add Attribute 'ID' to Description
325             GetTree().GetLevelDescriptor(l).Add
326               (AttributeDescriptor( "ID",
327                                     "Database Identifier",
328                                     0,0,
329                                     AttributeDescriptor::PRIVATE
330                                     ));
331             
332             if (l>1) 
333               {
334                 // Add Attribute 'PARENT_ID' to Description
335                 GetTree().GetLevelDescriptor(l).Add
336                   (AttributeDescriptor( "PARENT_ID",
337                                         "Database Parent Identifier",
338                                         0,0,
339                                         AttributeDescriptor::PRIVATE
340                                         ));
341               }
342             
343           }
344         
345         // Create table *_ATTRIBUTES
346         
347         command = "CREATE TABLE ";
348         command += GetTree().GetLevelDescriptor(l).GetName();
349         command += "_Attributes\n(\n";
350         command += "Key text,\n";
351         command += "Name text,\n";          
352         command += "DicomGroup int,\n";
353         command += "DicomElement int,\n";           
354         command += "Flags int\n";           
355         command += "\n)";
356         UPDATEDB(command);
357         
358         
359         // Fill the table *_ATTRIBUTES
360         LevelDescriptor::AttributeDescriptorListType::const_iterator i;
361         for (i  = GetTree().GetAttributeDescriptorList(l).begin();
362              i != GetTree().GetAttributeDescriptorList(l).end();
363              ++i)
364           {
365             
366             std::stringstream insert;
367             insert << "INSERT INTO "
368                    << GetTree().GetLevelDescriptor(l).GetName()
369                    << "_Attributes (Key,Name,DicomGroup,DicomElement,Flags) "
370                    << "VALUES ('"
371                    << i->GetKey() << "','"
372                    << i->GetName() << "',"
373                    << i->GetGroup() << ","
374                    << i->GetElement() << ","
375                    << i->GetFlags() << ");";
376             
377             UPDATEDB(insert.str());
378           }
379
380       } // For l=0...
381
382     // Initialize the root attributes
383     GetTree().InitializeAttributeMap();
384     // Insert the root in the level 0 table 
385     DBInsert(GetTree().GetTree());
386     
387     
388     GetTree().SetChildrenLoaded(true);
389     GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
390                    <<"' ... OK"<<std::endl);
391     return true;
392   }
393   //=====================================================================
394   
395   //=====================================================================
396   void SQLiteTreeHandler::SQLAppendAttributesDefinition(int level,
397                                                         std::string& s)
398   {
399     LevelDescriptor::AttributeDescriptorListType::const_iterator i;
400     for (i  = GetTree().GetAttributeDescriptorList(level).begin();
401          i != GetTree().GetAttributeDescriptorList(level).end();
402          ++i)
403       {
404         //      if (i->second.flags==1) continue;
405         s += ",\n";
406         s += i->GetKey();
407         s += " text";
408       }
409   }
410   //=====================================================================
411   
412   
413   //=====================================================================
414   bool SQLiteTreeHandler::DBImportTreeDescription()
415   {
416     GimmickMessage(1,"Importing tree description from database ..."
417                    <<std::endl);
418
419     // Test table 'LEVELS' existence
420     if ( ! mDB->tableExists("LEVELS") )
421       {
422         GimmickMessage(1,"!! ERROR : Table 'LEVELS' does not exist"
423                        <<std::endl);
424         return false;
425       }
426
427     tree::Descriptor& desc = GetTree().GetDescriptor();
428     // clears the existing one
429     desc.GetLevelDescriptorList().clear();
430      
431     int nblevel = 0;
432     std::string query = "SELECT * FROM LEVELS";
433     CppSQLite3Query q;
434     QUERYDB(query,q);
435
436     while (!q.eof())
437       {
438         std::string name = q.getStringField(0);
439         GimmickMessage(2," * Importing level '"<<name<<"'"<<std::endl);
440         desc.GetLevelDescriptorList().push_back(LevelDescriptor(name));
441         nblevel++;
442         q.nextRow();
443       }   
444     
445     for (int level = 0; level < nblevel; ++level )
446       {
447         std::string table = GetTree().GetLevelDescriptor(level).GetName();
448         table += "_Attributes";
449         // Test table 'LEVELS' existence
450         if ( ! mDB->tableExists(table.c_str()) )
451           {
452             GimmickMessage(1,"!! ERROR : Table '"<<table<<"' does not exist"
453                            <<std::endl);
454             return false;
455           }
456         
457         std::string query = "SELECT * FROM ";
458         query += table;
459         CppSQLite3Query q;
460         QUERYDB(query,q);
461         
462         GimmickMessage(2," * Level '"
463                        <<GetTree().GetLevelDescriptor(level).GetName()
464                        <<"'"<<std::endl);
465
466         // Test that ID and PARENT_ID mandatory attributes exist
467         bool ID_found = false;
468         bool PARENT_ID_found = false;
469         if (level==0) ID_found = true;
470         if (level<=1) PARENT_ID_found = true;
471
472         while (!q.eof())
473           {
474             std::string key(q.getStringField(0));
475             std::string name(q.getStringField(1));
476             GimmickMessage(2,"  - Importing attribute '"<<key<<"' '"<<name
477                            <<"'"<<std::endl);
478             desc.GetLevelDescriptor(level).Add
479               (AttributeDescriptor( key, // Key
480                                     name, // Name
481                                     q.getIntField(2), // Group
482                                     q.getIntField(3), // Element 
483                                     q.getIntField(4) // Flags
484                                     ));
485             if ( key == "ID" ) 
486               {
487                 ID_found = true;
488               }
489             if ( key == "PARENT_ID" ) 
490               {
491                 PARENT_ID_found = true;
492               }
493             q.nextRow();
494           }
495         
496         if ( ! (ID_found || PARENT_ID_found ) )
497           {
498             GimmickMessage(1,"!! ERROR : Table '"<<table
499                            <<"' does not contain mandatory attribute ID or PARENT_ID"
500                            <<std::endl);
501             return false;
502  
503           }
504       }
505
506
507     // Create the attributes table for Root (i.e. Tree)
508     LevelDescriptor::AttributeDescriptorListType::const_iterator a;
509     for (a = GetTree().GetAttributeDescriptorList(0).begin();
510          a!= GetTree().GetAttributeDescriptorList(0).end();
511          ++a)
512       {
513         /*
514         std::string v;
515         AttributeMapType::const_iterator i = attr.find(a->GetKey());
516         if ( i != attr.end() )  
517           {
518             v = i->second;
519           }
520         */
521         GetTree().UnsafeSetAttribute( a->GetKey(), "" );
522       }
523
524     // Reading Root attributes
525     // Query DB
526     query = "SELECT * FROM ";
527     query += GetTree().GetLevelDescriptor(0).GetName();
528     QUERYDB(query,q);
529
530     for (int fld = 0; fld < q.numFields(); fld++)
531       {
532         GetTree().UnsafeSetAttribute(q.fieldName(fld),
533                                      q.getStringField(fld));        
534       }
535
536     GimmickMessage(1,"Importing tree description from database ... OK"
537                    <<std::endl);
538     return true;
539   }
540   //=====================================================================
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558   //========================================================================
559   /// 
560   std::string& SQLformat(std::string& str)
561   {
562     // quote must be doubled
563     boost::algorithm::replace_all(str,"'","''");
564     // Found strange strings which contained NULL char INSIDE string 
565     int i,size=str.size();
566     for (i=0;i<size;++i) 
567       {
568         if (str[i]==0) 
569           {
570             str = str.substr(0,i);
571             break;
572           }
573       }
574     //    if (i<str.size())
575     return str;
576   }
577   //========================================================================
578   
579   //=====================================================================
580   void SQLiteTreeHandler::SQLAppendAttributesValues(tree::Node* n, 
581                                                     std::string& str)
582   {
583     GimmickMessage(4,"SQLAppendAttributesValues"<<std::endl);
584     std::string atts="";
585     std::string values="";
586     tree::Node::AttributeMapType::iterator i;
587     for (i =  n->GetAttributeMap().begin();
588          i != n->GetAttributeMap().end();
589          i++)
590       {
591         if (i->first=="ID") 
592           {
593             continue;
594           }
595         //      std::cout << "("<<i->first<<","<<i->second<<")"<<std::endl;
596         atts += "'" + i->first + "'";
597         values += "'" + SQLformat(i->second) + "'"; 
598         atts += ",";
599         values += ",";
600         GimmickMessage(4,"'"<<i->first<<"' = '"<<i->second<<"'"<<std::endl);
601       }
602     atts[atts.size()-1]=' ';
603     values[values.size()-1]=' ';
604
605     str = "("+atts+") VALUES ("+values+")";
606     GimmickMessage(4,"Result = '"<<str<<"'"<<std::endl);
607   }
608   //=====================================================================
609
610   //=====================================================================
611   tree::Node* SQLiteTreeHandler::DBGetParent( const AttributeMapType& attr) 
612   {
613     Node* parent = GetTree().GetTree();
614     bool go_down;
615     do 
616       {
617         go_down = false;
618         // Load the children of the current parent
619         DBLoadChildren(parent);
620         // Iterate the children 
621         tree::Node::ChildrenListType::const_iterator i;
622         for (i = parent->GetChildrenList().begin();
623              i!= parent->GetChildrenList().end();
624              ++i)
625           {
626             if ( (*i)->Matches( attr ) ) 
627               {
628                 go_down = true;
629                 parent = *i;
630                 break;
631               }
632           }     
633       }
634     while (go_down);
635     return parent;
636   }
637   //=====================================================================
638
639
640   //=====================================================================
641   int SQLiteTreeHandler::DBLoadChildren(tree::Node* node, 
642                                         int numberoflevels)
643   {
644     if (node->GetLevel()+1 >= node->GetTree()->GetNumberOfLevels() ) 
645       return 0;
646
647     GimmickMessage(2,"Loading children of '"<<node->GetLabel()
648                    <<"'"<<std::endl);
649
650     int nbloaded = 0;
651     // If children loaded we do not have to do it but we need to recurse
652     // in order to load the children's children if necessary, and so on...
653     if (node->GetChildrenLoaded()) 
654       {
655         // Iterate the children 
656         tree::Node::ChildrenListType::iterator i;
657         for (i = node->GetChildrenList().begin();
658              i!= node->GetChildrenList().end();
659              ++i)
660           {
661             nbloaded += DBLoadChildren(*i,numberoflevels-1);
662           }
663         return nbloaded;
664       }
665     
666     /// If children not loaded : do it and recurse
667
668     // Query DB
669     int level = node->GetLevel();
670     std::string query = "SELECT * FROM ";
671     query += GetTree().GetLevelDescriptor(level+1).GetName();
672     if (level>0)
673       {
674         query += " WHERE PARENT_ID='" + node->UnsafeGetAttribute("ID") 
675           + "'";
676       }
677     CppSQLite3Query q;
678     QUERYDB(query,q);
679
680     while (!q.eof())
681       {
682         nbloaded++;
683         Node* n = new Node(node);
684         for (int fld = 0; fld < q.numFields(); fld++)
685           {
686             n->UnsafeSetAttribute(q.fieldName(fld),q.getStringField(fld));          
687           }
688         /*
689         // Index 
690         TypeId ti;
691         ti.type = type;
692         ti.id = n->GetFieldValue("ID");    
693         mTypeIdToNodeMap[ti] = n;
694         */
695         // recurse 
696         if ( numberoflevels != 1 ) 
697           {
698             //  msw[2].Pause();
699             nbloaded += DBLoadChildren(n, numberoflevels-1);
700             //      msw[2].Resume();
701           }
702         // next entry in db
703         q.nextRow();
704       }
705
706     node->SetChildrenLoaded(true);
707     
708     //    msw[2].Pause();
709     return nbloaded;
710   }
711   //=====================================================================
712
713   //======================================================================
714   void SQLiteTreeHandler::DBInsert(tree::Node* n)
715   {
716     GimmickMessage(2,"Inserting in DB '"<<n->GetLabel()
717                    <<"'"<<std::endl);
718     std::string val;
719     SQLAppendAttributesValues(n,val);
720     std::string insert("INSERT INTO ");
721     insert += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
722     insert += " " + val + ";";
723     UPDATEDB(insert);
724         
725     // Store DB id of newly created node;
726     long lastrow = mDB->lastRowId();
727     std::stringstream ri;
728     ri << mDB->lastRowId();
729     n->SetAttribute("ID",ri.str());
730   }
731   //======================================================================
732
733   //======================================================================
734   /// Graft the branch defined by the attributes to the parent
735   void SQLiteTreeHandler::DBGraftToParent( tree::Node* parent, 
736                                             const AttributeMapType& attr)
737   {
738     GimmickMessage(2,"Grafting to parent '"<<parent->GetLabel()
739                    <<"'"<<std::endl);
740
741     for (int level = parent->GetLevel()+1;
742          level < GetTree().GetNumberOfLevels();
743          level++)
744       {
745         // Create Node
746         tree::Node* child = new tree::Node(parent,attr);
747         
748         // Set PARENT_ID if necessary 
749         if ( parent->GetLevel()>0 )
750           child->SetAttribute("PARENT_ID",parent->GetAttribute("ID"));
751         
752         // Insert in DB
753         DBInsert(child);
754         /*
755         std::string val;
756         SQLAppendAttributesValues(child,val);
757         std::string insert("INSERT INTO ");
758         insert += GetTree().GetLevelDescriptor(child->GetLevel()).GetName();
759         insert += " " + val + ";";
760         UPDATEDB(insert);
761         
762         // Store DB id of newly created node;
763         long lastrow = mDB->lastRowId();
764         std::stringstream ri;
765         ri << mDB->lastRowId();
766         child->SetAttribute("ID",ri.str());
767         */
768         // Down one level
769         parent = child;
770         
771         /*
772         // Insert in TypeId map
773         TypeId ti;
774         ti.type = node->GetType();
775         ti.id = node_id;
776         mTypeIdToNodeMap[ti] = node;
777         //    std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl; 
778         // 
779         msw[2].Pause();
780         
781         if (node->GetType()==Node::Patient) summary.added_patients++;
782         if (node->GetType()==Node::Study) summary.added_studies++;
783         if (node->GetType()==Node::Series) summary.added_series++;
784         if (node->GetType()==Node::Image) summary.added_images++;
785         */
786       }
787   }
788   //======================================================================
789
790
791   //===================================================================== 
792   /// Sets an attribute of a Node
793   bool SQLiteTreeHandler::DBSetAttribute(tree::Node* n, 
794                                          const std::string& key,
795                                          const std::string& value)
796   {
797     GimmickMessage(3,"Setting Attribute of '"<<n->GetLabel()<<
798                    "' "<<key<<"='"<<value<<"'"<<std::endl);
799
800     n->SetAttribute(key,value);
801     std::string sql = "UPDATE ";
802     sql += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
803     sql += " SET ";
804     sql += key;
805     sql += "='";
806     sql += value;
807     sql += "' WHERE ID=";
808     sql += n->GetAttribute("ID");
809     //    sql += " LIMIT 1";
810     UPDATEDB(sql);
811   }
812   //===================================================================== 
813
814   /*
815   //=====================================================================
816   bool SQLiteTreeHandler::DBInsert(Node* alien_node,
817                                    UpdateSummary& summary)
818   {
819     //    std::cout << "SQLiteTreeHandler::Insert('"<<alien_node->GetLabel()
820     //        <<"')"<<std::endl;
821     
822     //    if (!ChildrenLoaded()) DBLoadChildren(this,Node::Database);
823     
824     // Find parent
825     Node* parent;
826     std::string parent_id; 
827     parent = DBGetOrCreateParent(alien_node,parent_id,summary);
828     
829     // Insert 
830     DBRecursiveGetOrCreateNode(alien_node,parent,parent_id,summary);
831    return true;
832   }
833   //=====================================================================
834
835
836   //=====================================================================
837   Node* SQLiteTreeHandler::DBGetOrCreateParent(Node* alien_node,
838                                                 std::string& parent_id,
839                                                 UpdateSummary& summary)
840   {
841     //    std::cout << "DBGetOrCreateParent '" << alien_node->GetLabel()<<"'"
842     //        << std::endl;
843     // Load the patients if not already done
844     DBLoadChildren(this,Node::Patient);
845
846     parent_id = "";
847     Node* parent = this;
848
849     // The chain of ancestors
850     std::deque<Node*> chain;
851     Node* cur = alien_node->GetParent();
852     for (int type=Node::Patient; 
853          type<alien_node->GetType();++type)
854       {
855         chain.push_front(cur);
856         cur = cur->GetParent();
857       }
858
859     // create the nodes if do not exist
860     std::deque<Node*>::iterator i;
861     for (i=chain.begin();i!=chain.end();++i)
862       {
863         //      std::cout << " cur = '"<<(*i)->GetLabel()<<"'"<<std::endl;
864         //      std::string cur_id = DBGetNodeId(*i,parent_id);
865         //      if (cur_id.size()==0)
866         //        {
867         // Node does not exist : create it
868         std::string cur_id;
869         parent = DBGetOrCreateNode(*i, 
870                                         parent,
871                                         parent_id,
872                                         cur_id,
873                                         summary
874                                         );
875         DBLoadChildren(parent,parent->GetType()+1);
876
877         parent_id = cur_id;
878       }
879     return parent;
880   }
881   //=====================================================================
882
883
884
885   //=====================================================================
886   void SQLiteTreeHandler::DBRecursiveGetOrCreateNode(Node* alien_node, 
887                                                       Node* parent, 
888                                                       const std::string& parent_id,
889                                                       UpdateSummary& summary)
890   {
891     //    std::cout << "SQLiteTreeHandler::RecursiveGetOrCreateNode('"
892     //        <<alien_node->GetLabel()
893     //        <<"','"<<parent<<"','"<<parent_id<<"')"<<std::endl;
894     if (parent != 0) 
895       {
896         //      std::cout << " -- Parent = '"<<parent->GetLabel()<<"'"<<std::endl;
897       }   
898     std::string new_id;
899     Node* new_node = DBGetOrCreateNode(alien_node, 
900                                                  parent,
901                                                  parent_id,
902                                                  new_id,
903                                                  summary);
904     Node::ChildrenListType::iterator i;
905     for (i  = alien_node->GetChildrenList().begin();
906          i != alien_node->GetChildrenList().end();
907          i++)
908       {
909         DBRecursiveGetOrCreateNode((*i),new_node,new_id,summary);
910       }
911   }
912   //=====================================================================
913
914
915   //=====================================================================
916   Node* SQLiteTreeHandler::DBGetOrCreateNode(Node* alien_node, 
917                                                    Node* internal_parent,
918                                                    std::string parent_id,
919                                                    std::string& node_id,
920                                                    UpdateSummary& summary)
921   {
922     //   std::cout << "DBGetOrCreateNode('"<<alien_node->GetLabel()<<"','"
923     //        << internal_parent << "','"<< parent_id<<"')"<<std::endl;
924     if (internal_parent != 0) 
925       {
926         //      std::cout << " -- Parent = '"<<internal_parent->GetLabel()<<"'"<<std::endl;
927       }
928     // Node Exists ? return it 
929     // First try among children of internal parent 
930     Node* node = GetChildrenLike(internal_parent,alien_node);
931     if (node>0)
932       {
933         node_id = node->UnsafeGetFieldValue("ID");
934         return node;
935       }
936     // Second : try in DB 
937    
938     // Does not exist : Create new one
939     node = new Node(alien_node->GetType(),this,internal_parent);
940     node->SetChildrenLoaded(true);
941     // Copy fields values from alien
942     Node::FieldValueMapType::iterator i,j;
943     for (i =  node->GetFieldValueMap().begin();
944          i != node->GetFieldValueMap().end();
945          i++)
946       {
947         j = alien_node->GetFieldValueMap().find(i->first);
948         if (j != alien_node->GetFieldValueMap().end() )
949           {
950             i->second = j->second;
951           }
952       }
953
954     msw[2].Resume();
955     if (node->GetType()!=Node::Patient) 
956       node->SetFieldValue("PARENT_ID",parent_id);
957
958     // Insert in DB
959     std::string val;
960     BuildSQLFieldsValues(node,val);
961     std::string insert("INSERT INTO ");
962     insert += std::string(SQLiteTreeHandlerStructure::Table(node->GetType())) 
963       + " " + val + ";";
964     //    std::cout << "** SQL = '"<<insert<<"'"<<std::endl;
965     UPDATEDB(insert);
966     //    std::cout << "** SQL OK"<<std::endl;
967
968     // Store DB id of newly created node;
969     long lastrow = mDB->lastRowId();
970     std::stringstream ri;
971     ri << mDB->lastRowId();
972     node_id = ri.str();
973     //    std::cout << "LastRowId='"<<mDB->lastRowId()<<"' vs '"<<created_id<<"'"<<std::endl;
974
975     node->SetFieldValue("ID",node_id);
976     // Insert in TypeId map
977     TypeId ti;
978     ti.type = node->GetType();
979     ti.id = node_id;
980     mTypeIdToNodeMap[ti] = node;
981     //    std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl; 
982     // 
983     msw[2].Pause();
984
985     if (node->GetType()==Node::Patient) summary.added_patients++;
986     if (node->GetType()==Node::Study) summary.added_studies++;
987     if (node->GetType()==Node::Series) summary.added_series++;
988     if (node->GetType()==Node::Image) summary.added_images++;
989
990     return node;
991   }
992   //=====================================================================
993
994   //=====================================================================
995   Node* SQLiteTreeHandler::GetChildrenLike(Node* parent,
996                                             Node* alien_node)
997   {
998     Node::ChildrenListType::iterator i;
999     for (i  = parent->GetChildrenList().begin();
1000          i != parent->GetChildrenList().end();
1001          i++)
1002       {
1003         Node::Type type = alien_node->GetType();
1004         bool ok = true;
1005         for (int j=0;
1006              j<SQLiteTreeHandlerStructure::NbQueryFields(type);
1007              j++) 
1008           {
1009             if ( 
1010                 alien_node->GetFieldValue(SQLiteTreeHandlerStructure::
1011                                     QueryField(type,j).key )   !=
1012                 (*i)->GetFieldValue(SQLiteTreeHandlerStructure::
1013                                     QueryField(type,j).key ) )
1014               {
1015                 ok = false;
1016                 break;
1017               }
1018           }
1019         if (ok) 
1020           {
1021             return (*i);
1022           }
1023       }
1024     return 0;    
1025   }
1026   //=====================================================================
1027
1028   //=====================================================================
1029   std::string SQLiteTreeHandler::DBGetNodeId(Node* node, 
1030                                               const std::string& parent_id)
1031   {
1032     //    std::cout << "SQLiteTreeHandler::DBGetNodeId('"<<node->GetLabel()
1033     //        <<"','"<<parent_id<<"')"
1034     //        <<std::endl;
1035     msw[2].Resume();
1036     int type = node->GetType();
1037
1038     std::string table = SQLiteTreeHandlerStructure::Table(type);
1039     std::string where = "WHERE ";
1040     
1041     if (type!=Node::Patient)
1042       {
1043         where += "PARENT_ID='" + parent_id 
1044           //node->GetFieldValue("PARENT_ID") 
1045           + "' AND ";
1046       }
1047
1048     for (int i=0;i<SQLiteTreeHandlerStructure::NbQueryFields(type);i++) 
1049       {
1050         where += SQLiteTreeHandlerStructure::QueryField(type,i).key + "='"
1051           + node->GetFieldValue(SQLiteTreeHandlerStructure::QueryField(type,i).key) + "' ";
1052         if (i<SQLiteTreeHandlerStructure::NbQueryFields(type)-1)
1053           where += "AND ";
1054     }
1055
1056     std::string query = "SELECT ID FROM " + table + " " + where + ";";                                                    
1057     //    std::cout << "** SQL = '"<<query<<"'"<<std::endl;
1058     CppSQLite3Query q;
1059     QUERYDB(query,q);
1060
1061     if (!q.eof())
1062       {
1063         
1064         //      std::cout << " - Node exists " << std::endl;
1065         std::string id = q.getStringField(0);
1066         //      std::cout << " id = '"<<id<<"'"<<std::endl;
1067         msw[2].Pause();
1068         return id;
1069       }
1070     msw[2].Pause();
1071     return "";
1072   }
1073   //=====================================================================
1074
1075
1076
1077   //=====================================================================
1078   Node* SQLiteTreeHandler::GetNodeFromTypeId(Node::Type type,
1079                                        const std::string& id)
1080   {
1081     //    std::cout << "GetNodeFromTypeId("<<type<<","<<id<<")"<<std::endl;
1082
1083     TypeId ti;
1084     ti.type = type;
1085     ti.id = id;
1086     
1087     TypeIdToNodeMapType::iterator i = mTypeIdToNodeMap.find(ti);
1088     if (i == mTypeIdToNodeMap.end())
1089       {
1090
1091             std::cout << "Internal error : mTypeIdToNodeMap does not contain key"
1092                       << std::endl;
1093             creaError("Internal error : mTypeIdToNodeMap does not contain key");
1094             // }
1095       }
1096
1097     //    std::cout << " ** Node = "<<i->second<<std::endl;
1098     return i->second;
1099   }
1100   //=====================================================================
1101
1102   //=====================================================================
1103   bool SQLiteTreeHandler::Remove(Node* node)
1104   {
1105     DBRecursiveRemoveNode(node);
1106  
1107     //    std::cout << "DELETE"<<std::endl;
1108     if (node->GetParent())
1109       {
1110         node->GetParent()->RemoveChildrenFromList(node);
1111       }
1112     delete node;
1113     //    std::cout << "DELETE OK"<<std::endl;
1114     return true;
1115   }
1116   //========================================================================
1117
1118   //=====================================================================
1119   void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
1120   {
1121     //    std::cout << "SQLiteTreeHandler::DBRecursiveRemoveNode('"
1122     //        <<node->GetLabel()<<"')"<<std::endl;
1123
1124     std::string query = "DELETE FROM ";
1125     query += SQLiteTreeHandlerStructure::Table(node->GetType());
1126     query += " WHERE ID='"+ node->GetFieldValue("ID") + "';";
1127  
1128     UPDATEDB(query);
1129
1130     Node::ChildrenListType::iterator i;
1131     for (i  = node->GetChildrenList().begin();
1132          i != node->GetChildrenList().end();
1133          i++)
1134       {
1135         DBRecursiveRemoveNode((*i));
1136       }
1137   }
1138   //=====================================================================
1139   
1140   //=====================================================================
1141   int SQLiteTreeHandler::DBQueryNumberOfChildren(Node* node)
1142   {
1143     std::string query = "SELECT COUNT (ID) FROM ";
1144     query += SQLiteTreeHandlerStructure::Table(node->GetType()+1);
1145     if (node->GetType() != Node::Database) 
1146       {
1147         query += " WHERE PARENT_ID='"+ node->GetFieldValue("ID")+"'";
1148       }
1149     query  += ";";
1150     
1151     //   std::cout << "**SQL = "<< query << std::endl;
1152     
1153     CppSQLite3Query q;
1154     QUERYDB(query,q);
1155    
1156      //    std::cout << "**RES = "<< q.getIntField(0) <<std::endl;
1157
1158     return q.getIntField(0);
1159   }
1160   //=====================================================================
1161  
1162  
1163
1164 */
1165
1166
1167
1168 } // namespace creaImageIO