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