]> Creatis software - creaImageIO.git/blob - src2/creaImageIOSQLiteTreeHandler.cpp
8dcdd1795dcda95800944e9934bddd3f7c33200f
[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         mIsAdding=false;
40     GimmickMessage(1,"SQLite version : "
41                    <<std::string(mDB->SQLiteVersion())<< std::endl);
42   }
43   //=============================================================
44
45   //=============================================================
46   SQLiteTreeHandler::~SQLiteTreeHandler()
47   {
48     delete mDB;
49   }
50   //=============================================================
51   
52
53   //=============================================================
54   //  void SQLiteTreeHandler::Print() const 
55   //  {
56     /*
57     std::cout << "-> '"<<GetName()<< "' - '"
58               << GetFileName()<<"'"<<std::endl;
59     ChildrenListType::const_iterator i;
60     for (i=GetChildrenList().begin(); i!=GetChildrenList().end(); i++)
61       {
62         (*i)->Print();
63       }
64     */
65   //  }
66   //=============================================================
67   
68   //=====================================================================
69   /*
70   bool SQLiteTreeHandler::LocationIsValid()
71   {
72     // TO DO 
73     return true;
74   }
75   */
76   //=====================================================================
77
78
79   //=====================================================================
80   bool SQLiteTreeHandler::Open(bool writable)
81   {
82     //    std::cout << "***> SQLiteTreeHandler::Open('"<<GetFileName()<<"')"<<std::endl;
83     SetWritable(writable);
84     return DBOpen();
85   }
86
87   //=====================================================================
88   bool SQLiteTreeHandler::Create(bool writable)
89   {
90     //    std::cout << "***> SQLiteTreeHandler::New('"<<GetFileName()<<"')"<<std::endl;
91     SetWritable(writable);
92     return DBCreate();
93   }
94   //=====================================================================
95
96
97   //=====================================================================
98   bool SQLiteTreeHandler::Close()
99   {
100     return true;
101   }
102   //=====================================================================
103
104
105   //=====================================================================
106   bool SQLiteTreeHandler::Destroy()
107   {
108     return false;
109   }
110   
111   //===================================================================== 
112
113   //===================================================================== 
114   int SQLiteTreeHandler::LoadChildren(tree::Node* parent, int maxlevel)
115   {
116     if (parent==0) parent = GetTree().GetTree();
117     return DBLoadChildren(parent,maxlevel);
118   }
119   //===================================================================== 
120
121
122
123
124   //===================================================================== 
125   void SQLiteTreeHandler::UnLoad(tree::Node* n)
126   {
127   }
128   //===================================================================== 
129
130   //===================================================================== 
131   int SQLiteTreeHandler::AddBranch( const AttributeMapType& attr )
132   {
133     tree::Node* parent = DBGetParent(attr);
134     DBGraftToParent(parent,attr);
135     return (parent->GetLevel()+1);
136           
137   }
138   //===================================================================== 
139  
140
141   //===================================================================== 
142    bool SQLiteTreeHandler::Remove(tree::Node* node)
143    {
144    DBRecursiveRemoveNode(node);
145  
146     //    std::cout << "DELETE"<<std::endl;
147    bool remove=false;
148    tree::Node* parent=node->GetParent();
149     if (parent)
150       {
151         parent->RemoveChildrenFromList(node);
152         int nC=GetNumberOfChildren(parent);
153         nC=nC-1;
154         if(nC>0)
155         {       
156                 std::stringstream out;
157                 out <<nC;
158                 SetAttribute(parent,"NumberOfChildren",out.str());
159         }
160         else
161         {
162                 remove=true;
163         }
164
165       }
166     delete node;
167         if(remove&&parent->GetLevel()>0)
168         {
169                 Remove(parent);
170         }
171     //    std::cout << "DELETE OK"<<std::endl;
172     return true;
173    }
174
175     //========================================================================
176
177   
178   
179   //===================================================================== 
180
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)
186   {
187     if (n==0) n=GetTree().GetTree();
188     return DBSetAttribute(n,key,value);
189   }
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)
198   {
199         DBSetAttribute(levelDescriptor,key,value,searchParam, searchVal);
200   }
201   //===================================================================== 
202   /// Deletes a tuple
203   void SQLiteTreeHandler::DeleteTuple(std::string levelDescriptor, 
204                                                                 std::string key, std::string value)
205   {
206     DBDelete(levelDescriptor,key,value);
207   }
208   //===================================================================== 
209
210
211
212
213
214
215
216
217
218
219
220
221
222   //=====================================================================
223   // SQLite DB specific methods
224   //=====================================================================
225
226
227
228
229   //=====================================================================
230   char* format_sql(const std::string& s)
231   { 
232     return sqlite3_mprintf("%q",s.c_str());
233   }
234   //=====================================================================
235
236   //  sqlite3_exec(db, zSQL, 0, 0, 0);
237   //  sqlite3_free(zSQL);
238   //    char* CHAIN = format_sql(QUER);         \
239 //  sqlite3_free(CHAIN);                                \
240
241   //=====================================================================
242 #define QUERYDB(QUER,RES)                                               \
243     try                                                                 \
244       {                                                                 \
245         GimmickMessage(2,"SQL query: '"<<QUER<<"'"<<std::endl);         \
246         RES = mDB->execQuery(QUER.c_str());                             \
247       }                                                                 \
248     catch (CppSQLite3Exception& e)                                      \
249       {                                                                 \
250         GimmickError("SQLite query '"<<QUER<<"' : "                     \
251                      << e.errorCode() << ":"                            \
252                      << e.errorMessage() );                             \
253       }                                                                 \
254     
255   //=====================================================================
256   
257   //=====================================================================
258 #define UPDATEDB(UP)                                                    \
259   try                                                                   \
260     {                                                                   \
261       GimmickMessage(2,"SQL update: '"<<UP<<"'"<<std::endl);            \
262       mDB->execDML(UP.c_str());                                         \
263     }                                                                   \
264   catch (CppSQLite3Exception& e)                                        \
265     {                                                                   \
266       GimmickError("SQLite update '"<<UP<<"' Error : "                  \
267                    << e.errorCode() << ":"                              \
268                    << e.errorMessage() );                               \
269     }                                                                   
270   //=====================================================================
271
272
273   //=====================================================================
274   bool SQLiteTreeHandler::DBOpen()
275   {
276     GimmickMessage(1,"Opening SQLite database '"<<GetFileName()
277                    <<"' ... "<<std::endl);
278     // OPENING FILE
279     if (!boost::filesystem::exists(GetFileName())) 
280       {
281         return false;
282       }
283
284     try
285       {
286         mDB->open(GetFileName().c_str());
287       }
288     catch (CppSQLite3Exception& e)
289       {
290         GimmickError("Opening '"<<GetFileName()<<"' : "
291                      << e.errorCode() << ":" 
292                      << e.errorMessage());
293         return false;
294       }
295     // IMPORT TREE DESCRIPTION (AND TEST DB VALIDITY)
296     if (!DBImportTreeDescription())
297       {
298         return false;
299       }
300
301     GimmickDebugMessage(1,"Opening SQLite database '"<<GetFileName()
302                    <<"' ... OK"<<std::endl);
303     return true;
304   }
305   //=====================================================================
306
307   //=====================================================================
308   bool SQLiteTreeHandler::DBCreate()
309   {
310     GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
311                    <<"' ... "<<std::endl);
312
313     if (boost::filesystem::exists(GetFileName())) 
314       {
315         GimmickError(GetFileName()<<"' : "
316                      << "file already exists");
317         return false;
318       }
319     
320     // OPENING
321     try
322       {
323         mDB->open(GetFileName().c_str());
324       }
325     catch (CppSQLite3Exception& e)
326       {
327         GimmickError(e.errorCode() << ":" 
328                      << e.errorMessage() <<std::endl);
329         return false;
330       }
331     
332      
333     // CREATING TABLES
334     
335     std::string command;
336     // Create LEVELS table
337     command = "create table LEVELS\n";
338     command += "( Name text )\n";
339     UPDATEDB(command);
340     
341     // Iterate the Levels
342     for (int l=0; l<GetTree().GetNumberOfLevels(); ++l)
343       {
344         command = "INSERT INTO LEVELS (Name) VALUES ('";
345         command += GetTree().GetLevelDescriptor(l).GetName();
346         command += "')";
347         UPDATEDB(command);
348         
349         // Create table of level (for level>0, i.e. not Root)
350         if (l>=0)
351           {
352             command = "CREATE TABLE ";
353             command += GetTree().GetLevelDescriptor(l).GetName();
354             command += "\n(\nID INTEGER PRIMARY KEY";
355             if (l>1) 
356               {
357                 command += ",\nPARENT_ID int not null"; 
358               }
359             SQLAppendAttributesDefinition(l,command);
360             if (l>1) 
361               {
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";
365               }
366             command += "\n)";
367             UPDATEDB(command);
368             
369             
370             // Add Attribute 'ID' to Description
371             GetTree().GetDescriptor().Add
372               (AttributeDescriptor( "ID",
373                                     "Database Identifier",
374                                     0,0,
375                                     AttributeDescriptor::PRIVATE
376                                     ),l);
377             
378             if (l>1) 
379               {
380                 // Add Attribute 'PARENT_ID' to Description
381                 GetTree().GetDescriptor().Add
382                   (AttributeDescriptor( "PARENT_ID",
383                                         "Database Parent Identifier",
384                                         0,0,
385                                         AttributeDescriptor::PRIVATE
386                                         ),l);
387               }
388             
389           }
390         
391         // Create table *_ATTRIBUTES
392         
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";           
401         command += "\n)";
402         UPDATEDB(command);
403         
404         
405         // Fill the table *_ATTRIBUTES
406         LevelDescriptor::AttributeDescriptorListType::const_iterator i;
407         for (i  = GetTree().GetAttributeDescriptorList(l).begin();
408              i != GetTree().GetAttributeDescriptorList(l).end();
409              ++i)
410           {
411             
412             std::stringstream insert;
413             insert << "INSERT INTO "
414                    << GetTree().GetLevelDescriptor(l).GetName()
415                    << "_Attributes (Key,Name,DicomGroup,DicomElement,Flags) "
416                    << "VALUES ('"
417                    << i->GetKey() << "','"
418                    << i->GetName() << "',"
419                    << i->GetGroup() << ","
420                    << i->GetElement() << ","
421                    << i->GetFlags() << ");";
422             UPDATEDB(insert.str());
423           }
424
425       } // For l=0...
426
427     // Initialize the root attributes
428     GetTree().InitializeAttributeMap();
429     // Insert the root in the level 0 table 
430     DBInsert(GetTree().GetTree());
431     
432     
433     GetTree().SetChildrenLoaded(true);
434     GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
435                    <<"' ... OK"<<std::endl);
436     return true;
437   }
438   //=====================================================================
439   
440   //=====================================================================
441   void SQLiteTreeHandler::SQLAppendAttributesDefinition(int level,
442                                                         std::string& s)
443   {
444     LevelDescriptor::AttributeDescriptorListType::const_iterator i;
445     for (i  = GetTree().GetAttributeDescriptorList(level).begin();
446          i != GetTree().GetAttributeDescriptorList(level).end();
447          ++i)
448       {
449         //      if (i->second.flags==1) continue;
450         s += ",\n";
451         s += i->GetKey();
452         s += " text";
453       }
454   }
455   //=====================================================================
456   
457   
458   //=====================================================================
459   bool SQLiteTreeHandler::DBImportTreeDescription()
460   {
461     GimmickMessage(1,"Importing tree description from database ..."
462                    <<std::endl);
463
464     // Test table 'LEVELS' existence
465     if ( ! mDB->tableExists("LEVELS") )
466       {
467         GimmickMessage(1,"!! ERROR : Table 'LEVELS' does not exist"
468                        <<std::endl);
469         return false;
470       }
471
472     tree::Descriptor& desc = GetTree().GetDescriptor();
473     // clears the existing one
474     desc.Clear();
475      
476     int nblevel = 0;
477     std::string query = "SELECT * FROM LEVELS";
478     CppSQLite3Query q;
479     QUERYDB(query,q);
480
481     while (!q.eof())
482       {
483         std::string name = q.getStringField(0);
484         GimmickMessage(2," * Importing level '"<<name<<"'"<<std::endl);
485         desc.Add(LevelDescriptor(name));
486         nblevel++;
487         q.nextRow();
488       }   
489     
490     for (int level = 0; level < nblevel; ++level )
491       {
492         std::string table = GetTree().GetLevelDescriptor(level).GetName();
493         table += "_Attributes";
494         // Test table 'LEVELS' existence
495         if ( ! mDB->tableExists(table.c_str()) )
496           {
497             GimmickMessage(1,"!! ERROR : Table '"<<table<<"' does not exist"
498                            <<std::endl);
499             return false;
500           }
501         
502         std::string query = "SELECT * FROM ";
503         query += table;
504         CppSQLite3Query q;
505         QUERYDB(query,q);
506         
507         GimmickMessage(2," * Level '"
508                        <<GetTree().GetLevelDescriptor(level).GetName()
509                        <<"'"<<std::endl);
510
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;
516
517         while (!q.eof())
518           {
519             std::string key(q.getStringField(0));
520             std::string name(q.getStringField(1));
521             GimmickMessage(2,"  - Importing attribute '"<<key<<"' '"<<name
522                            <<"'"<<std::endl);
523             desc.Add
524               (AttributeDescriptor( key, // Key
525                                     name, // Name
526                                     q.getIntField(2), // Group
527                                     q.getIntField(3), // Element 
528                                     q.getIntField(4) // Flags
529                                     ),level);
530             if ( key == "ID" ) 
531               {
532                 ID_found = true;
533               }
534             if ( key == "PARENT_ID" ) 
535               {
536                 PARENT_ID_found = true;
537               }
538             q.nextRow();
539           }
540         
541         if ( ! (ID_found || PARENT_ID_found ) )
542           {
543             GimmickMessage(1,"!! ERROR : Table '"<<table
544                            <<"' does not contain mandatory attribute ID or PARENT_ID"
545                            <<std::endl);
546             return false;
547  
548           }
549       }
550
551
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();
556          ++a)
557       {
558         /*
559         std::string v;
560         AttributeMapType::const_iterator i = attr.find(a->GetKey());
561         if ( i != attr.end() )  
562           {
563             v = i->second;
564           }
565         */
566         GetTree().UnsafeSetAttribute( a->GetKey(), "" );
567       }
568
569     // Reading Root attributes
570     // Query DB
571     query = "SELECT * FROM ";
572     query += GetTree().GetLevelDescriptor(0).GetName();
573     QUERYDB(query,q);
574
575     for (int fld = 0; fld < q.numFields(); fld++)
576       {
577         GetTree().UnsafeSetAttribute(q.fieldName(fld),
578                                      q.getStringField(fld));        
579       }
580
581     GimmickMessage(1,"Importing tree description from database ... OK"
582                    <<std::endl);
583     return true;
584   }
585   //=====================================================================
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603   //========================================================================
604   /// 
605   std::string& SQLformat(std::string& str)
606   {
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();
611     for (i=0;i<size;++i) 
612       {
613         if (str[i]==0) 
614           {
615             str = str.substr(0,i);
616             break;
617           }
618       }
619     //    if (i<str.size())
620     return str;
621   }
622   //========================================================================
623   
624   //=====================================================================
625   void SQLiteTreeHandler::SQLAppendAttributesValues(tree::Node* n, 
626                                                     std::string& str)
627   {
628     GimmickMessage(4,"SQLAppendAttributesValues"<<std::endl);
629     std::string atts="";
630     std::string values="";
631     tree::Node::AttributeMapType::iterator i;
632     for (i =  n->GetAttributeMap().begin();
633          i != n->GetAttributeMap().end();
634          i++)
635       {
636         if (i->first=="ID") 
637           {
638             continue;
639           }
640         //      std::cout << "("<<i->first<<","<<i->second<<")"<<std::endl;
641         atts += "'" + i->first + "'";
642         values += "'" + SQLformat(i->second) + "'"; 
643         atts += ",";
644         values += ",";
645         GimmickMessage(4,"'"<<i->first<<"' = '"<<i->second<<"'"<<std::endl);
646       }
647     atts[atts.size()-1]=' ';
648     values[values.size()-1]=' ';
649
650     str = "("+atts+") VALUES ("+values+")";
651     GimmickMessage(4,"Result = '"<<str<<"'"<<std::endl);
652   }
653   //=====================================================================
654
655   //=====================================================================
656   tree::Node* SQLiteTreeHandler::DBGetParent( const AttributeMapType& attr) 
657   {
658     Node* parent = GetTree().GetTree();
659     bool go_down;
660     do 
661       {
662         go_down = false;
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();
669              ++i)
670           {
671             if ( (*i)->Matches( attr ) ) 
672               {
673                 go_down = true;
674                 parent = *i;
675                 break;
676               }
677           }     
678       }
679     while (go_down);
680     return parent;
681   }
682   //=====================================================================
683
684
685   //=====================================================================
686   int SQLiteTreeHandler::DBLoadChildren(tree::Node* node, 
687                                         int numberoflevels)
688   {
689     if (node->GetLevel()+1 >= node->GetTree()->GetNumberOfLevels() ) 
690       return 0;
691
692     GimmickMessage(2,"Loading children of '"<<node->GetLabel()
693                    <<"'"<<std::endl);
694
695     int nbloaded = 0;
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()) 
699       {
700         // Iterate the children 
701
702         tree::Node::ChildrenListType::iterator i;
703         for (i = node->GetChildrenList().begin();
704              i!= node->GetChildrenList().end();
705              ++i)
706           {
707             nbloaded += DBLoadChildren(*i,numberoflevels-1);
708           }
709         node->SetChildrenLoaded(true);
710         return nbloaded;
711
712       }
713         else
714         {
715     /// If children not loaded : do it and recurse
716
717     // Query DB
718     int level = node->GetLevel();
719     std::string query = "SELECT * FROM ";
720         
721     query += GetTree().GetLevelDescriptor(level+1).GetName();
722     if (level>0)
723       {
724         query += " WHERE PARENT_ID='" + node->UnsafeGetAttribute("ID") 
725           + "'";
726       }
727     CppSQLite3Query q;
728     QUERYDB(query,q);
729
730         int p=0;
731     while (!q.eof())
732       {
733
734         //      std::cout << "DBLoadCh : creating node level "<<level+1<<std::endl;
735
736         nbloaded++;
737         Node* n = new Node(node);
738         for (int fld = 0; fld < q.numFields(); fld++)
739           {
740             n->UnsafeSetAttribute(q.fieldName(fld),q.getStringField(fld));          
741           }
742         /*
743         // Index 
744         TypeId ti;
745         ti.type = type;
746         ti.id = n->GetFieldValue("ID");    
747         mTypeIdToNodeMap[ti] = n;
748         */
749         // recurse 
750         if ( numberoflevels != 1 ) 
751           {
752             //  msw[2].Pause();
753             nbloaded += DBLoadChildren(n, numberoflevels-1);
754             //      msw[2].Resume();
755           }
756         // next entry in db
757         q.nextRow();
758       }
759
760     node->SetChildrenLoaded(true);
761         
762     
763     //    msw[2].Pause();
764     return nbloaded;
765         }
766   }
767   //=====================================================================
768
769   //======================================================================
770   void SQLiteTreeHandler::DBInsert(tree::Node* n)
771   {
772     GimmickMessage(2,"Inserting in DB '"<<n->GetLabel()
773                    <<"'"<<std::endl);
774     std::string val;
775     SQLAppendAttributesValues(n,val);
776     std::string insert("INSERT INTO ");
777     insert += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
778     insert += " " + val + ";";
779
780     UPDATEDB(insert);
781         
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());
787   }
788   //======================================================================
789
790   //======================================================================
791   /// Graft the branch defined by the attributes to the parent
792   void SQLiteTreeHandler::DBGraftToParent( tree::Node* parent, 
793                                             const AttributeMapType& attr)
794   {
795     //    std::cout <<"Grafting to parent '"<<parent->GetLabel()
796     //             <<"'"<<std::endl;
797
798     for (int level = parent->GetLevel()+1;
799          level < GetTree().GetNumberOfLevels();
800          level++)
801       {
802         // Create Node
803         tree::Node* child = new tree::Node(parent,attr);
804         child->SetChildrenLoaded(true);
805         if (level>1)
806           {
807             int nc = GetNumberOfChildren(parent)+1;
808             
809             //  std::cout<<"Number of children "<<parent->GetNumberOfChildren()<<std::endl;
810             std::stringstream out;
811             out << nc;
812             SetAttribute(parent,"NumberOfChildren",out.str());
813           }
814
815         // Set PARENT_ID if necessary 
816         if ( parent->GetLevel()>0 )
817           child->SetAttribute("PARENT_ID",parent->GetAttribute("ID"));
818         
819         // Insert in DB
820         DBInsert(child);
821         /*
822         std::string val;
823         SQLAppendAttributesValues(child,val);
824         std::string insert("INSERT INTO ");
825         insert += GetTree().GetLevelDescriptor(child->GetLevel()).GetName();
826         insert += " " + val + ";";
827         UPDATEDB(insert);
828         
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());
834         */
835         // Down one level
836         parent = child;
837         
838         /*
839         // Insert in TypeId map
840         TypeId ti;
841         ti.type = node->GetType();
842         ti.id = node_id;
843         mTypeIdToNodeMap[ti] = node;
844         //    std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl; 
845         // 
846         msw[2].Pause();
847         
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++;
852         */
853       }
854   }
855   //======================================================================
856
857
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)
863   {
864     GimmickMessage(3,"Setting Attribute of '"<<n->GetLabel()<<
865                    "' "<<key<<"='"<<value<<"'"<<std::endl);
866
867     n->SetAttribute(key,value);
868     std::string sql = "UPDATE ";
869     sql += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
870     sql += " SET ";
871     sql += key;
872     sql += "='";
873     sql += value;
874     sql += "' WHERE ID=";
875     sql += n->GetAttribute("ID");
876     //    sql += " LIMIT 1";
877     UPDATEDB(sql);
878   }
879
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)
887   {
888
889     std::string sql = "UPDATE ";
890     sql += levelDescriptor;
891     sql += " SET ";
892     sql += key;
893     sql += " = '";
894     sql += value;
895     sql += "' WHERE ";
896         sql += searchParam;
897         sql += " = '";
898     sql += searchVal;
899         sql += "'";
900     UPDATEDB(sql);
901   }
902    //=====================================================================
903   void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
904   {
905        
906     std::string query = "DELETE FROM ";
907    
908     query += GetTree().GetLevelDescriptor(node->GetLevel()).GetName();
909     query += " WHERE ID='"+ node->GetAttribute("ID") + "';";
910  
911     UPDATEDB(query);
912         GimmickDebugMessage(2,
913                             " Deleting '"
914                                 <<node->GetLabel()<<"' with ID '"
915                             <<node->GetAttribute("ID")
916                             <<"' in level "<< GetTree().GetLevelDescriptor(node->GetLevel()).GetName()
917                             <<std::endl);
918
919     Node::ChildrenListType::iterator i;
920     for (i  = node->GetChildrenList().begin();
921          i != node->GetChildrenList().end();
922          i++)
923       {
924         DBRecursiveRemoveNode((*i));
925       }
926   }
927
928   //=====================================================================
929   void SQLiteTreeHandler::DBDelete(std::string levelDescriptor, std::string key, std::string value)
930   {
931        
932     std::stringstream query;
933         query<<"DELETE FROM "<<levelDescriptor<<" WHERE "<<key<<"='"<<value<<"';";
934  
935     UPDATEDB(query.str());
936         GimmickMessage(1," Deleting: Query: "<<query.str()<<std::endl);
937   }
938
939
940   //===================================================================== 
941   void SQLiteTreeHandler::GetAttribute(std::string levelDescriptor,
942                                                                            std::string searchParam, 
943                                                                            std::string searchVal, 
944                                                                            std::string key, 
945                                                                            std::string& result) 
946   { 
947         std::stringstream out;
948         std::stringstream results;
949         out<<"SELECT "<<key<<" FROM "<<levelDescriptor;
950         if(searchParam!="")
951         {
952                 out<<" WHERE "<<searchParam<<"='"<<searchVal<<"'";
953         }
954         
955         CppSQLite3Query q;
956         QUERYDB(out.str(),q);
957         
958         
959         while (!q.eof())
960           {
961             for (int fld = 0; fld < q.numFields(); fld++)
962               {
963                           results<<q.getStringField(fld);
964                           if(searchParam=="")
965                           {
966                                   results<<"#";
967                           }
968               }
969             q.nextRow();
970           }
971         result=results.str();
972       
973   }
974   //===================================================================== 
975   unsigned int SQLiteTreeHandler::GetNumberOfChildren(tree::Node* n) 
976   { 
977     // Query DB
978     int nb=0;
979     int level = n->GetLevel();
980     
981     if(level<GetTree().GetNumberOfLevels()&& level>0)
982       {
983         std::string query = "SELECT NumberOfChildren FROM ";
984         query += GetTree().GetLevelDescriptor(level).GetName();
985         if (level>0)
986           {
987             query += " WHERE ID='" + n->UnsafeGetAttribute("ID") 
988               + "'";
989           }
990         CppSQLite3Query q;
991         QUERYDB(query,q);
992         
993         
994         while (!q.eof())
995           {
996             for (int fld = 0; fld < q.numFields(); fld++)
997               {
998                 nb=q.getIntField(fld);  
999               }
1000             q.nextRow();
1001           }
1002       }
1003     /*
1004     if(nb==0)
1005       { 
1006         nb=1;
1007       }
1008     */
1009     return nb; 
1010   }
1011
1012   /*
1013   //=====================================================================
1014   bool SQLiteTreeHandler::DBInsert(Node* alien_node,
1015                                    UpdateSummary& summary)
1016   {
1017     //    std::cout << "SQLiteTreeHandler::Insert('"<<alien_node->GetLabel()
1018     //        <<"')"<<std::endl;
1019     
1020     //    if (!ChildrenLoaded()) DBLoadChildren(this,Node::Database);
1021     
1022     // Find parent
1023     Node* parent;
1024     std::string parent_id; 
1025     parent = DBGetOrCreateParent(alien_node,parent_id,summary);
1026     
1027     // Insert 
1028     DBRecursiveGetOrCreateNode(alien_node,parent,parent_id,summary);
1029    return true;
1030   }
1031   //=====================================================================
1032
1033
1034   //=====================================================================
1035   Node* SQLiteTreeHandler::DBGetOrCreateParent(Node* alien_node,
1036                                                 std::string& parent_id,
1037                                                 UpdateSummary& summary)
1038   {
1039     //    std::cout << "DBGetOrCreateParent '" << alien_node->GetLabel()<<"'"
1040     //        << std::endl;
1041     // Load the patients if not already done
1042     DBLoadChildren(this,Node::Patient);
1043
1044     parent_id = "";
1045     Node* parent = this;
1046
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)
1052       {
1053         chain.push_front(cur);
1054         cur = cur->GetParent();
1055       }
1056
1057     // create the nodes if do not exist
1058     std::deque<Node*>::iterator i;
1059     for (i=chain.begin();i!=chain.end();++i)
1060       {
1061         //      std::cout << " cur = '"<<(*i)->GetLabel()<<"'"<<std::endl;
1062         //      std::string cur_id = DBGetNodeId(*i,parent_id);
1063         //      if (cur_id.size()==0)
1064         //        {
1065         // Node does not exist : create it
1066         std::string cur_id;
1067         parent = DBGetOrCreateNode(*i, 
1068                                         parent,
1069                                         parent_id,
1070                                         cur_id,
1071                                         summary
1072                                         );
1073         DBLoadChildren(parent,parent->GetType()+1);
1074
1075         parent_id = cur_id;
1076       }
1077     return parent;
1078   }
1079   //=====================================================================
1080
1081
1082
1083   //=====================================================================
1084   void SQLiteTreeHandler::DBRecursiveGetOrCreateNode(Node* alien_node, 
1085                                                       Node* parent, 
1086                                                       const std::string& parent_id,
1087                                                       UpdateSummary& summary)
1088   {
1089     //    std::cout << "SQLiteTreeHandler::RecursiveGetOrCreateNode('"
1090     //        <<alien_node->GetLabel()
1091     //        <<"','"<<parent<<"','"<<parent_id<<"')"<<std::endl;
1092     if (parent != 0) 
1093       {
1094         //      std::cout << " -- Parent = '"<<parent->GetLabel()<<"'"<<std::endl;
1095       }   
1096     std::string new_id;
1097     Node* new_node = DBGetOrCreateNode(alien_node, 
1098                                                  parent,
1099                                                  parent_id,
1100                                                  new_id,
1101                                                  summary);
1102     Node::ChildrenListType::iterator i;
1103     for (i  = alien_node->GetChildrenList().begin();
1104          i != alien_node->GetChildrenList().end();
1105          i++)
1106       {
1107         DBRecursiveGetOrCreateNode((*i),new_node,new_id,summary);
1108       }
1109   }
1110   //=====================================================================
1111
1112
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)
1119   {
1120     //   std::cout << "DBGetOrCreateNode('"<<alien_node->GetLabel()<<"','"
1121     //        << internal_parent << "','"<< parent_id<<"')"<<std::endl;
1122     if (internal_parent != 0) 
1123       {
1124         //      std::cout << " -- Parent = '"<<internal_parent->GetLabel()<<"'"<<std::endl;
1125       }
1126     // Node Exists ? return it 
1127     // First try among children of internal parent 
1128     Node* node = GetChildrenLike(internal_parent,alien_node);
1129     if (node>0)
1130       {
1131         node_id = node->UnsafeGetFieldValue("ID");
1132         return node;
1133       }
1134     // Second : try in DB 
1135    
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();
1143          i++)
1144       {
1145         j = alien_node->GetFieldValueMap().find(i->first);
1146         if (j != alien_node->GetFieldValueMap().end() )
1147           {
1148             i->second = j->second;
1149           }
1150       }
1151
1152     msw[2].Resume();
1153     if (node->GetType()!=Node::Patient) 
1154       node->SetFieldValue("PARENT_ID",parent_id);
1155
1156     // Insert in DB
1157     std::string val;
1158     BuildSQLFieldsValues(node,val);
1159     std::string insert("INSERT INTO ");
1160     insert += std::string(SQLiteTreeHandlerStructure::Table(node->GetType())) 
1161       + " " + val + ";";
1162     //    std::cout << "** SQL = '"<<insert<<"'"<<std::endl;
1163     UPDATEDB(insert);
1164     //    std::cout << "** SQL OK"<<std::endl;
1165
1166     // Store DB id of newly created node;
1167     long lastrow = mDB->lastRowId();
1168     std::stringstream ri;
1169     ri << mDB->lastRowId();
1170     node_id = ri.str();
1171     //    std::cout << "LastRowId='"<<mDB->lastRowId()<<"' vs '"<<created_id<<"'"<<std::endl;
1172
1173     node->SetFieldValue("ID",node_id);
1174     // Insert in TypeId map
1175     TypeId ti;
1176     ti.type = node->GetType();
1177     ti.id = node_id;
1178     mTypeIdToNodeMap[ti] = node;
1179     //    std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl; 
1180     // 
1181     msw[2].Pause();
1182
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++;
1187
1188     return node;
1189   }
1190   //=====================================================================
1191
1192   //=====================================================================
1193   Node* SQLiteTreeHandler::GetChildrenLike(Node* parent,
1194                                             Node* alien_node)
1195   {
1196     Node::ChildrenListType::iterator i;
1197     for (i  = parent->GetChildrenList().begin();
1198          i != parent->GetChildrenList().end();
1199          i++)
1200       {
1201         Node::Type type = alien_node->GetType();
1202         bool ok = true;
1203         for (int j=0;
1204              j<SQLiteTreeHandlerStructure::NbQueryFields(type);
1205              j++) 
1206           {
1207             if ( 
1208                 alien_node->GetFieldValue(SQLiteTreeHandlerStructure::
1209                                     QueryField(type,j).key )   !=
1210                 (*i)->GetFieldValue(SQLiteTreeHandlerStructure::
1211                                     QueryField(type,j).key ) )
1212               {
1213                 ok = false;
1214                 break;
1215               }
1216           }
1217         if (ok) 
1218           {
1219             return (*i);
1220           }
1221       }
1222     return 0;    
1223   }
1224   //=====================================================================
1225
1226   //=====================================================================
1227   std::string SQLiteTreeHandler::DBGetNodeId(Node* node, 
1228                                               const std::string& parent_id)
1229   {
1230     //    std::cout << "SQLiteTreeHandler::DBGetNodeId('"<<node->GetLabel()
1231     //        <<"','"<<parent_id<<"')"
1232     //        <<std::endl;
1233     msw[2].Resume();
1234     int type = node->GetType();
1235
1236     std::string table = SQLiteTreeHandlerStructure::Table(type);
1237     std::string where = "WHERE ";
1238     
1239     if (type!=Node::Patient)
1240       {
1241         where += "PARENT_ID='" + parent_id 
1242           //node->GetFieldValue("PARENT_ID") 
1243           + "' AND ";
1244       }
1245
1246     for (int i=0;i<SQLiteTreeHandlerStructure::NbQueryFields(type);i++) 
1247       {
1248         where += SQLiteTreeHandlerStructure::QueryField(type,i).key + "='"
1249           + node->GetFieldValue(SQLiteTreeHandlerStructure::QueryField(type,i).key) + "' ";
1250         if (i<SQLiteTreeHandlerStructure::NbQueryFields(type)-1)
1251           where += "AND ";
1252     }
1253
1254     std::string query = "SELECT ID FROM " + table + " " + where + ";";                                                    
1255     //    std::cout << "** SQL = '"<<query<<"'"<<std::endl;
1256     CppSQLite3Query q;
1257     QUERYDB(query,q);
1258
1259     if (!q.eof())
1260       {
1261         
1262         //      std::cout << " - Node exists " << std::endl;
1263         std::string id = q.getStringField(0);
1264         //      std::cout << " id = '"<<id<<"'"<<std::endl;
1265         msw[2].Pause();
1266         return id;
1267       }
1268     msw[2].Pause();
1269     return "";
1270   }
1271   //=====================================================================
1272
1273
1274
1275   //=====================================================================
1276   Node* SQLiteTreeHandler::GetNodeFromTypeId(Node::Type type,
1277                                        const std::string& id)
1278   {
1279     //    std::cout << "GetNodeFromTypeId("<<type<<","<<id<<")"<<std::endl;
1280
1281     TypeId ti;
1282     ti.type = type;
1283     ti.id = id;
1284     
1285     TypeIdToNodeMapType::iterator i = mTypeIdToNodeMap.find(ti);
1286     if (i == mTypeIdToNodeMap.end())
1287       {
1288
1289             std::cout << "Internal error : mTypeIdToNodeMap does not contain key"
1290                       << std::endl;
1291             creaError("Internal error : mTypeIdToNodeMap does not contain key");
1292             // }
1293       }
1294
1295     //    std::cout << " ** Node = "<<i->second<<std::endl;
1296     return i->second;
1297   }
1298  
1299   //=====================================================================
1300
1301   //=====================================================================
1302   bool SQLiteTreeHandler::Remove(Node* node)
1303   {
1304
1305     //DBRecursiveRemoveNode(node);
1306  
1307     //    std::cout << "DELETE"<<std::endl;
1308     if (node->GetParent())
1309       {
1310         node->GetParent()->RemoveChildrenFromList(node);
1311       }
1312     delete node;
1313     //    std::cout << "DELETE OK"<<std::endl;
1314     return true;
1315   }
1316   
1317   
1318   //========================================================================
1319
1320   //=====================================================================
1321   void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
1322   {
1323     //    std::cout << "SQLiteTreeHandler::DBRecursiveRemoveNode('"
1324     //        <<node->GetLabel()<<"')"<<std::endl;
1325
1326     std::string query = "DELETE FROM ";
1327     query += SQLiteTreeHandlerStructure::Table(node->GetType());
1328     query += " WHERE ID='"+ node->GetFieldValue("ID") + "';";
1329  
1330     UPDATEDB(query);
1331
1332     Node::ChildrenListType::iterator i;
1333     for (i  = node->GetChildrenList().begin();
1334          i != node->GetChildrenList().end();
1335          i++)
1336       {
1337         DBRecursiveRemoveNode((*i));
1338       }
1339   }
1340   
1341   //=====================================================================
1342   
1343   //=====================================================================
1344   int SQLiteTreeHandler::DBQueryNumberOfChildren(Node* node)
1345   {
1346     std::string query = "SELECT COUNT (ID) FROM ";
1347     query += SQLiteTreeHandlerStructure::Table(node->GetType()+1);
1348     if (node->GetType() != Node::Database) 
1349       {
1350         query += " WHERE PARENT_ID='"+ node->GetFieldValue("ID")+"'";
1351       }
1352     query  += ";";
1353     
1354     //   std::cout << "**SQL = "<< query << std::endl;
1355     
1356     CppSQLite3Query q;
1357     QUERYDB(query,q);
1358    
1359      //    std::cout << "**RES = "<< q.getIntField(0) <<std::endl;
1360
1361     return q.getIntField(0);
1362   }
1363   //=====================================================================
1364  
1365  
1366
1367 */
1368
1369
1370
1371 } // namespace creaImageIO