]> Creatis software - creaImageIO.git/blob - src2/creaImageIOSQLiteTreeHandler.cpp
Starting version 2
[creaImageIO.git] / src2 / creaImageIOSQLiteTreeHandler.cpp
1 #include <creaImageIOSQLiteTreeHandler.h>
2
3 #include "CppSQLite3.h"
4
5 #include <sys/stat.h>
6
7 //#include <creaImageIOSQLiteTreeHandlerStructure.h>
8
9 //#include <creaImageIOUtilities.h>
10
11 //#include <icons/database.xpm>
12
13 #include <deque>
14
15 #include "wx/wx.h"
16 #include <wx/dir.h>
17 #include <wx/filename.h>
18
19
20 //#include <icons/close.xpm>
21
22 #include <creaWx.h>
23 #include <creaMessageManager.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     /*
39     mSQLiteTreeHandler = this;
40     NodeTypeDescription::FieldDescriptionMapType& M = 
41       mNodeTypeDescription[Node::Database].GetFieldDescriptionMap();
42
43     boost::filesystem::path full_path(location);
44     mName = full_path.leaf();
45     Field::Description fname("Name",0,0,"Name",0);
46     M[fname.key] = fname;
47     UnsafeSetFieldValue(fname.key,mName);
48     Field::Description flocation("File name",0,0,"File name",0);
49     M[flocation.key] = flocation;
50     UnsafeSetFieldValue(flocation.key,location);
51     */
52     //    Field::Description ftype("Type",0,0,"Type",0);
53     //    M[ftype.key] = ftype;
54     //    UnsafeSetFieldValue(ftype.key,"Invalid location");
55
56     mDB = new CppSQLite3DB;
57     //    std::cout << "** SQLite Version: " << mDB->SQLiteVersion() << std::endl;
58
59
60   }
61   //=============================================================
62
63   //=============================================================
64   SQLiteTreeHandler::~SQLiteTreeHandler()
65   {
66     delete mDB;
67     /*
68       Already done in Node now that SQLiteTreeHandler inherits from it
69     ChildrenListType::iterator i;
70     for (i=GetChildrenList().begin(); i!=GetChildrenList().end(); i++)
71       {
72         delete *i;
73       }
74     */
75   }
76   //=============================================================
77   
78
79   //=============================================================
80   void SQLiteTreeHandler::BuildDefaultTreeDescription()
81   {
82     /*
83     for (int i = Node::Patient;
84          i <= Node::Image; 
85          ++i)
86       {
87         mNodeTypeDescription[i].BuildDefault(i);
88       }
89     */
90
91     // TODO : GetTree().GetDescription().LoadXML(FILE);
92   }
93   //=============================================================
94
95   //=============================================================
96   //  void SQLiteTreeHandler::Print() const 
97   //  {
98     /*
99     std::cout << "-> '"<<GetName()<< "' - '"
100               << GetFileName()<<"'"<<std::endl;
101     ChildrenListType::const_iterator i;
102     for (i=GetChildrenList().begin(); i!=GetChildrenList().end(); i++)
103       {
104         (*i)->Print();
105       }
106     */
107   //  }
108   //=============================================================
109   
110   //=====================================================================
111   /*
112   bool SQLiteTreeHandler::LocationIsValid()
113   {
114     // TO DO 
115     return true;
116   }
117   */
118   //=====================================================================
119
120   //=====================================================================
121   char* format_sql(const std::string& s)
122   { 
123     return sqlite3_mprintf("%q",s.c_str());
124   }
125   //=====================================================================
126
127   //  sqlite3_exec(db, zSQL, 0, 0, 0);
128   //  sqlite3_free(zSQL);
129   //    char* CHAIN = format_sql(QUER);         \
130 //  sqlite3_free(CHAIN);                                \
131
132   //=====================================================================
133 #define QUERYDB(QUER,RES)                                               \
134     try                                                                 \
135       {                                                                 \
136         RES = mDB->execQuery(QUER.c_str());                             \
137       }                                                                 \
138     catch (CppSQLite3Exception& e)                                      \
139       {                                                                 \
140         std::cout << "SQLite query '"<<QUER<<"' : "<< e.errorCode() << ":" \
141                   << e.errorMessage()<<std::endl;                       \
142         creaError("SQLite query '"<<QUER<<"' : "<< e.errorCode() << ":" \
143                    << e.errorMessage() );                               \
144       }                                                                 \
145     
146   //=====================================================================
147   
148   //=====================================================================
149 #define UPDATEDB(UP)                                                    \
150   try                                                                   \
151     {                                                                   \
152       mDB->execDML(UP.c_str());                                         \
153     }                                                                   \
154   catch (CppSQLite3Exception& e)                                        \
155     {                                                                   \
156       std::cout << "SQLite update '"<<UP<<"' Error : "<< e.errorCode() << ":" \
157                 << e.errorMessage()<<std::endl;                         \
158       creaError("SQLite update '"<<UP<<"' Error : "<< e.errorCode() << ":" \
159                  << e.errorMessage() );                                 \
160     }                                                                   
161   //=====================================================================
162
163   //=====================================================================
164   bool SQLiteTreeHandler::Open(bool writable)
165   {
166     //    std::cout << "***> SQLiteTreeHandler::Open('"<<GetFileName()<<"')"<<std::endl;
167     SetWritable(writable);
168     return DBOpen();
169   }
170
171   //=====================================================================
172   bool SQLiteTreeHandler::Create(bool writable)
173   {
174     //    std::cout << "***> SQLiteTreeHandler::New('"<<GetFileName()<<"')"<<std::endl;
175     SetWritable(writable);
176     return DBCreate();
177   }
178   //=====================================================================
179
180
181   //=====================================================================
182   bool SQLiteTreeHandler::Close()
183   {
184     return false;
185   }
186   //=====================================================================
187
188
189   //=====================================================================
190   bool SQLiteTreeHandler::Destroy()
191   {
192     return false;
193   }
194   //=====================================================================
195
196   //===================================================================== 
197   unsigned int SQLiteTreeHandler::GetNumberOfChildren(tree::Node* n) 
198   { 
199     return 0; 
200   }
201   //===================================================================== 
202
203   //===================================================================== 
204   int SQLiteTreeHandler::LoadChildren(tree::Node* parent, int maxlevel)
205   {
206     return 0;
207   }
208   //===================================================================== 
209
210
211
212
213   //===================================================================== 
214   void SQLiteTreeHandler::UnLoad(tree::Node* n)
215   {
216   }
217   //===================================================================== 
218
219
220   //===================================================================== 
221   int SQLiteTreeHandler::AddBranch( const std::map<std::string,std::string>& attr )
222   {
223     return -1;
224   }
225   //===================================================================== 
226  
227
228   //===================================================================== 
229    bool SQLiteTreeHandler::Remove(tree::Node*)
230    {
231      return false;
232    }
233   //===================================================================== 
234
235
236
237
238
239
240
241   //=====================================================================
242   bool SQLiteTreeHandler::DBOpen()
243   {
244     //    std::cout << "### Opening SQLite database '"<<GetFileName()<<std::endl;
245     // OPENING FILE
246     if (!boost::filesystem::exists(GetFileName())) 
247       {
248         return false;
249       }
250
251     try
252       {
253         mDB->open(GetFileName().c_str());
254       }
255     catch (CppSQLite3Exception& e)
256       {
257         std::cerr << "Opening '"<<GetFileName()<<"' : "
258                   << e.errorCode() << ":" 
259                   << e.errorMessage() << std::endl;
260         return false;
261       }
262     // TESTING STRUCTURE VALIDITY
263     if (!DBStructureIsValid())
264       {
265         std::cerr << "Opening '"<<GetFileName()<<"' : "
266                   << " invalid database structure" << std::endl;
267         return false;
268       }
269     // IMPORTING NODE TYPE DESCRIPTIONS
270     DBImportTreeDescription();
271     return true;
272   }
273   //=====================================================================
274
275   //=====================================================================
276   bool SQLiteTreeHandler::DBCreate()
277   {
278     //    std::cout << "### Creating SQLite database '"<<GetFileName()<<std::endl;
279
280     if (boost::filesystem::exists(GetFileName())) 
281       {
282         creaMessage("Gimmick!",1,
283                     "[Gimmick!] !! ERROR '"<<GetFileName()<<"' : "
284                     << "file already exists"<<std::endl);
285         return false;
286       }
287     
288     // OPENING
289     try
290       {
291         mDB->open(GetFileName().c_str());
292       }
293     catch (CppSQLite3Exception& e)
294       {
295         creaMessage("Gimmick!",1,
296                     "[Gimmick!] !! ERROR '"
297                     << e.errorCode() << ":" 
298                     << e.errorMessage() <<std::endl);
299         return false;
300       }
301     
302     // CREATING TABLES
303     try
304       {
305         std::string command;
306         // Level 0
307         command = "create table ";
308         command += GetTree().GetLevelDescriptor(0).GetName();
309         command += "\n(\nID INTEGER PRIMARY KEY,\n";
310         AppendAttributesSQLDefinition(0,command);
311         command += "\n)";
312         UPDATEDB(command);
313         
314         // Iterate the other Levels
315         for (int l=1; l<GetTree().GetNumberOfLevels(); ++l)
316           {
317             command = "create table ";
318             command += GetTree().GetLevelDescriptor(l).GetName();
319             command += "\n(\nID INTEGER PRIMARY KEY,\nPARENT_ID int not null,\n";       
320             AppendAttributesSQLDefinition(l,command);
321             command +=",\n";
322             command +="constraint FK_PARENT foreign key (PARENT_ID) references PATIENT(ID) on delete restrict on update restrict\n)";
323             UPDATEDB(command);
324           }
325         
326         // Create tables *_ATTRIBUTES
327         for (int l=1; l<GetTree().GetNumberOfLevels(); ++l)
328           {
329             command = "create table ";
330             command += GetTree().GetLevelDescriptor(l).GetName();
331             command += "_ATTRIBUTES\n(\n";
332             command += "Key text,\n";
333             command += "Group int,\n";
334             command += "Element int,\n";            
335             command += "Name text,\n";      
336             command += "Flags int\n";       
337             command += "\n)";
338             UPDATEDB(command);
339           }
340         // Fill the tables *_ATTRIBUTES
341         DBExportTreeDescription();
342         
343       }
344     catch (std::exception)
345       {
346         return false;
347       }
348     // LG : TEST
349     if (DBStructureIsValid())
350       {
351         //      std::cout << "*** DONE ***"<<std::endl;
352         //      mDBLoaded = true;
353         GetTree().SetChildrenLoaded(true);
354         return true;
355         
356       }
357     else 
358       {
359         //      std::cout << "*** AAAARRRRGGG ***"<<std::endl;
360         
361         return false;
362       }
363   }
364   //=====================================================================
365   
366   //=====================================================================
367   void SQLiteTreeHandler::AppendAttributesSQLDefinition(int level,
368                                                         std::string& s)
369   {
370     /*
371     std::vector<std::string*> keys;
372     NodeTypeDescription::FieldDescriptionMapType::iterator i;
373     for (i  = GetNodeTypeDescription(c).GetFieldDescriptionMap().begin();
374          i != GetNodeTypeDescription(c).GetFieldDescriptionMap().end();
375          ++i)
376       {
377         if (i->second.flags==1) continue;
378         keys.push_back(&(i->second.key));
379       }
380     std::vector<std::string*>::iterator j;
381     for (j=keys.begin();j!=keys.end();)
382       {
383         s += **j + " text";
384         ++j;
385         if (j!=keys.end())
386           s += ",\n";
387       }
388     */
389   }
390   //=====================================================================
391   
392   //=====================================================================
393   void SQLiteTreeHandler::DBExportTreeDescription()
394   {
395     /*
396     //    std::cout<<"ExportNodeTypeDescriptionsToDB()"<<std::endl;
397     for (Node::Type type=Node::Patient; 
398          type<=Node::Image; 
399          type++)
400       {
401         NodeTypeDescription::FieldDescriptionMapType::iterator i;
402         for (i = GetNodeTypeDescription(type).GetFieldDescriptionMap().begin();
403              i!= GetNodeTypeDescription(type).GetFieldDescriptionMap().end();
404              i++)
405           {
406             
407             std::stringstream insert;
408             insert << "INSERT INTO "
409                    << std::string(SQLiteTreeHandlerStructure::Table(type))
410                    << "_FIELDS (Key,DicomGroup,DicomElement,Name,Flags) "
411                    << "VALUES ('"
412                    << (*i).second.GetKey() << "',"
413                    << (*i).second.GetGroup() << ","
414                    << (*i).second.GetElement() << ",'"
415                    << (*i).second.GetName() << "',"
416                    << (*i).second.GetFlags() << ");";
417
418             //      std::cout << "** SQL = '"<<insert.str()<<"'"<<std::endl;
419             
420             UPDATEDB(insert.str());
421           }
422       }
423     */
424   }
425   //=====================================================================
426   
427   //=====================================================================
428   void SQLiteTreeHandler::DBImportTreeDescription()
429   {
430     //    std::cout<<"ImportNodeTypeDescriptionsFromDB()"<<std::endl;
431     /*
432     for (Node::Type type=Node::Patient; 
433          type<=Node::Image; 
434          type++)
435       {
436         std::string query = "SELECT * FROM ";
437         query += SQLiteTreeHandlerStructure::Table(type);
438         query += "_FIELDS";
439
440         //      std::cout << "** SQL = '"<<query<<"'"<<std::endl;
441         
442         CppSQLite3Query q;
443         QUERYDB(query,q);
444         
445
446         while (!q.eof())
447           {
448             Field::Description d(q.getStringField(0), // Key
449                                  q.getIntField(1), // Group
450                                  q.getIntField(2), // Element 
451                                  q.getStringField(3), // Name
452                                  q.getIntField(4) // Flags
453                                  );
454             GetNodeTypeDescription(type).GetFieldDescriptionMap()[d.key] = d;
455             //      std::cout << d << std::endl;
456             q.nextRow();
457           }
458       }
459     */
460   }
461   //=====================================================================
462
463
464     //=====================================================================
465   bool SQLiteTreeHandler::DBStructureIsValid()
466   {
467     bool success = false; //true;
468
469     // TO DO : TABLE WHICH STORES THE LEVELS
470     /*
471     
472     for (int i = SQLiteTreeHandlerStructure::TableBegin();
473          i    != SQLiteTreeHandlerStructure::TableEnd();++i)
474       {
475         bool ok = mDB->tableExists(SQLiteTreeHandlerStructure::Table(i));
476         if (ok) 
477           {
478             //      std::cout << "** Table "<<SQLiteTreeHandlerStructure::Table(i)
479             //                <<" exists"<<std::endl;
480             // TO DO : TEST MANDATORY FIELDS EXIST
481           }
482         else 
483           {
484             //      std::cout << "** Table "<<SQLiteTreeHandlerStructure::Table(i)
485             //                <<" does *NOT* exist"<<std::endl;
486             success = false;
487           }
488       }
489     */
490     return success;
491   }  
492   //=====================================================================
493
494   /*
495   //=====================================================================
496   int SQLiteTreeHandler::DBLoadChildren(Node* parent, 
497                                         int maxlevel)
498   {
499
500     //    std::cout << "SQLiteTreeHandler::DBLoadChildren("<<parent<<","<<maxlevel
501     //        << ")"<<std::endl;
502     int nbloaded = 0;
503     if (parent == GetTree()) { parent = 0; }
504     Node* xparent = parent;
505     if ( xparent==0 ) xparent = GetTree();
506     if ( xparent->ChildrenLoaded() ) 
507       {
508         //      std::cout << "--> Children already loaded"<<std::endl;
509         return nbloaded;
510       }
511     if ( xparent->GetType() == Node::Image ) 
512       {
513         return nbloaded;
514       }
515     if ( xparent->GetType() >= maxlevel ) 
516       {
517         return nbloaded;
518       }
519    
520     //    msw[2].Pause();
521     //    msw[2].Resume();
522
523     Node::Type type = xparent->GetType()+1;
524
525     // Query DB
526
527     std::string query = "SELECT * FROM ";
528     query += GetTree().GetDescriptor().GetLevelDescriptor(level).GetName();
529       //SQLiteTreeHandlerStructure::Table(type);
530     if (parent!=0)
531       {
532         query += " WHERE PARENT_ID='" + parent->GetFieldValue("ID") + "'";
533       }
534
535     //    std::cout << "** SQL = '"<<query<<"'"<<std::endl;
536
537     CppSQLite3Query q;
538     QUERYDB(query,q);
539
540     while (!q.eof())
541       {
542         nbloaded++;
543         Node* n = new Node(type,
544                            this,xparent);
545         for (int fld = 0; fld < q.numFields(); fld++)
546           {
547             n->SetFieldValue(q.fieldName(fld),q.getStringField(fld));       
548           }
549         // Index 
550         TypeId ti;
551         ti.type = type;
552         ti.id = n->GetFieldValue("ID");    
553         mTypeIdToNodeMap[ti] = n;
554         // recurse 
555         if ( type < maxlevel ) 
556           {
557             msw[2].Pause();
558             nbloaded += DBLoadChildren(n,maxlevel);
559             msw[2].Resume();
560           }
561         // next entry in db
562         q.nextRow();
563       }
564
565     xparent->SetChildrenLoaded(true);
566     
567     //    msw[2].Pause();
568     return nbloaded;
569   }
570   //=====================================================================
571
572
573
574
575
576
577   //=====================================================================
578   bool SQLiteTreeHandler::DBInsert(Node* alien_node,
579                                    UpdateSummary& summary)
580   {
581     //    std::cout << "SQLiteTreeHandler::Insert('"<<alien_node->GetLabel()
582     //        <<"')"<<std::endl;
583     
584     //    if (!ChildrenLoaded()) DBLoadChildren(this,Node::Database);
585     
586     // Find parent
587     Node* parent;
588     std::string parent_id; 
589     parent = DBGetOrCreateParent(alien_node,parent_id,summary);
590     
591     // Insert 
592     DBRecursiveGetOrCreateNode(alien_node,parent,parent_id,summary);
593    return true;
594   }
595   //=====================================================================
596
597
598   //=====================================================================
599   Node* SQLiteTreeHandler::DBGetOrCreateParent(Node* alien_node,
600                                                 std::string& parent_id,
601                                                 UpdateSummary& summary)
602   {
603     //    std::cout << "DBGetOrCreateParent '" << alien_node->GetLabel()<<"'"
604     //        << std::endl;
605     // Load the patients if not already done
606     DBLoadChildren(this,Node::Patient);
607
608     parent_id = "";
609     Node* parent = this;
610
611     // The chain of ancestors
612     std::deque<Node*> chain;
613     Node* cur = alien_node->GetParent();
614     for (int type=Node::Patient; 
615          type<alien_node->GetType();++type)
616       {
617         chain.push_front(cur);
618         cur = cur->GetParent();
619       }
620
621     // create the nodes if do not exist
622     std::deque<Node*>::iterator i;
623     for (i=chain.begin();i!=chain.end();++i)
624       {
625         //      std::cout << " cur = '"<<(*i)->GetLabel()<<"'"<<std::endl;
626         //      std::string cur_id = DBGetNodeId(*i,parent_id);
627         //      if (cur_id.size()==0)
628         //        {
629         // Node does not exist : create it
630         std::string cur_id;
631         parent = DBGetOrCreateNode(*i, 
632                                         parent,
633                                         parent_id,
634                                         cur_id,
635                                         summary
636                                         );
637         DBLoadChildren(parent,parent->GetType()+1);
638
639         parent_id = cur_id;
640       }
641     return parent;
642   }
643   //=====================================================================
644
645
646
647   //=====================================================================
648   void SQLiteTreeHandler::DBRecursiveGetOrCreateNode(Node* alien_node, 
649                                                       Node* parent, 
650                                                       const std::string& parent_id,
651                                                       UpdateSummary& summary)
652   {
653     //    std::cout << "SQLiteTreeHandler::RecursiveGetOrCreateNode('"
654     //        <<alien_node->GetLabel()
655     //        <<"','"<<parent<<"','"<<parent_id<<"')"<<std::endl;
656     if (parent != 0) 
657       {
658         //      std::cout << " -- Parent = '"<<parent->GetLabel()<<"'"<<std::endl;
659       }   
660     std::string new_id;
661     Node* new_node = DBGetOrCreateNode(alien_node, 
662                                                  parent,
663                                                  parent_id,
664                                                  new_id,
665                                                  summary);
666     Node::ChildrenListType::iterator i;
667     for (i  = alien_node->GetChildrenList().begin();
668          i != alien_node->GetChildrenList().end();
669          i++)
670       {
671         DBRecursiveGetOrCreateNode((*i),new_node,new_id,summary);
672       }
673   }
674   //=====================================================================
675
676
677   //=====================================================================
678   Node* SQLiteTreeHandler::DBGetOrCreateNode(Node* alien_node, 
679                                                    Node* internal_parent,
680                                                    std::string parent_id,
681                                                    std::string& node_id,
682                                                    UpdateSummary& summary)
683   {
684     //   std::cout << "DBGetOrCreateNode('"<<alien_node->GetLabel()<<"','"
685     //        << internal_parent << "','"<< parent_id<<"')"<<std::endl;
686     if (internal_parent != 0) 
687       {
688         //      std::cout << " -- Parent = '"<<internal_parent->GetLabel()<<"'"<<std::endl;
689       }
690     // Node Exists ? return it 
691     // First try among children of internal parent 
692     Node* node = GetChildrenLike(internal_parent,alien_node);
693     if (node>0)
694       {
695         node_id = node->UnsafeGetFieldValue("ID");
696         return node;
697       }
698     // Second : try in DB 
699    
700     // Does not exist : Create new one
701     node = new Node(alien_node->GetType(),this,internal_parent);
702     node->SetChildrenLoaded(true);
703     // Copy fields values from alien
704     Node::FieldValueMapType::iterator i,j;
705     for (i =  node->GetFieldValueMap().begin();
706          i != node->GetFieldValueMap().end();
707          i++)
708       {
709         j = alien_node->GetFieldValueMap().find(i->first);
710         if (j != alien_node->GetFieldValueMap().end() )
711           {
712             i->second = j->second;
713           }
714       }
715
716     msw[2].Resume();
717     if (node->GetType()!=Node::Patient) 
718       node->SetFieldValue("PARENT_ID",parent_id);
719
720     // Insert in DB
721     std::string val;
722     BuildSQLFieldsValues(node,val);
723     std::string insert("INSERT INTO ");
724     insert += std::string(SQLiteTreeHandlerStructure::Table(node->GetType())) 
725       + " " + val + ";";
726     //    std::cout << "** SQL = '"<<insert<<"'"<<std::endl;
727     UPDATEDB(insert);
728     //    std::cout << "** SQL OK"<<std::endl;
729
730     // Store DB id of newly created node;
731     long lastrow = mDB->lastRowId();
732     std::stringstream ri;
733     ri << mDB->lastRowId();
734     node_id = ri.str();
735     //    std::cout << "LastRowId='"<<mDB->lastRowId()<<"' vs '"<<created_id<<"'"<<std::endl;
736
737     node->SetFieldValue("ID",node_id);
738     // Insert in TypeId map
739     TypeId ti;
740     ti.type = node->GetType();
741     ti.id = node_id;
742     mTypeIdToNodeMap[ti] = node;
743     //    std::cout << "== Insert TypeId ("<<ti.type<<","<<ti.id<<")"<<std::endl; 
744     // 
745     msw[2].Pause();
746
747     if (node->GetType()==Node::Patient) summary.added_patients++;
748     if (node->GetType()==Node::Study) summary.added_studies++;
749     if (node->GetType()==Node::Series) summary.added_series++;
750     if (node->GetType()==Node::Image) summary.added_images++;
751
752     return node;
753   }
754   //=====================================================================
755
756   //=====================================================================
757   Node* SQLiteTreeHandler::GetChildrenLike(Node* parent,
758                                             Node* alien_node)
759   {
760     Node::ChildrenListType::iterator i;
761     for (i  = parent->GetChildrenList().begin();
762          i != parent->GetChildrenList().end();
763          i++)
764       {
765         Node::Type type = alien_node->GetType();
766         bool ok = true;
767         for (int j=0;
768              j<SQLiteTreeHandlerStructure::NbQueryFields(type);
769              j++) 
770           {
771             if ( 
772                 alien_node->GetFieldValue(SQLiteTreeHandlerStructure::
773                                     QueryField(type,j).key )   !=
774                 (*i)->GetFieldValue(SQLiteTreeHandlerStructure::
775                                     QueryField(type,j).key ) )
776               {
777                 ok = false;
778                 break;
779               }
780           }
781         if (ok) 
782           {
783             return (*i);
784           }
785       }
786     return 0;    
787   }
788   //=====================================================================
789
790   //=====================================================================
791   std::string SQLiteTreeHandler::DBGetNodeId(Node* node, 
792                                               const std::string& parent_id)
793   {
794     //    std::cout << "SQLiteTreeHandler::DBGetNodeId('"<<node->GetLabel()
795     //        <<"','"<<parent_id<<"')"
796     //        <<std::endl;
797     msw[2].Resume();
798     int type = node->GetType();
799
800     std::string table = SQLiteTreeHandlerStructure::Table(type);
801     std::string where = "WHERE ";
802     
803     if (type!=Node::Patient)
804       {
805         where += "PARENT_ID='" + parent_id 
806           //node->GetFieldValue("PARENT_ID") 
807           + "' AND ";
808       }
809
810     for (int i=0;i<SQLiteTreeHandlerStructure::NbQueryFields(type);i++) 
811       {
812         where += SQLiteTreeHandlerStructure::QueryField(type,i).key + "='"
813           + node->GetFieldValue(SQLiteTreeHandlerStructure::QueryField(type,i).key) + "' ";
814         if (i<SQLiteTreeHandlerStructure::NbQueryFields(type)-1)
815           where += "AND ";
816     }
817
818     std::string query = "SELECT ID FROM " + table + " " + where + ";";                                                    
819     //    std::cout << "** SQL = '"<<query<<"'"<<std::endl;
820     CppSQLite3Query q;
821     QUERYDB(query,q);
822
823     if (!q.eof())
824       {
825         
826         //      std::cout << " - Node exists " << std::endl;
827         std::string id = q.getStringField(0);
828         //      std::cout << " id = '"<<id<<"'"<<std::endl;
829         msw[2].Pause();
830         return id;
831       }
832     msw[2].Pause();
833     return "";
834   }
835   //=====================================================================
836
837
838
839   //=====================================================================
840   Node* SQLiteTreeHandler::GetNodeFromTypeId(Node::Type type,
841                                        const std::string& id)
842   {
843     //    std::cout << "GetNodeFromTypeId("<<type<<","<<id<<")"<<std::endl;
844
845     TypeId ti;
846     ti.type = type;
847     ti.id = id;
848     
849     TypeIdToNodeMapType::iterator i = mTypeIdToNodeMap.find(ti);
850     if (i == mTypeIdToNodeMap.end())
851       {
852
853             std::cout << "Internal error : mTypeIdToNodeMap does not contain key"
854                       << std::endl;
855             creaError("Internal error : mTypeIdToNodeMap does not contain key");
856             // }
857       }
858
859     //    std::cout << " ** Node = "<<i->second<<std::endl;
860     return i->second;
861   }
862   //=====================================================================
863
864   //=====================================================================
865   bool SQLiteTreeHandler::Remove(Node* node)
866   {
867     DBRecursiveRemoveNode(node);
868  
869     //    std::cout << "DELETE"<<std::endl;
870     if (node->GetParent())
871       {
872         node->GetParent()->RemoveChildrenFromList(node);
873       }
874     delete node;
875     //    std::cout << "DELETE OK"<<std::endl;
876     return true;
877   }
878   //========================================================================
879
880   //=====================================================================
881   void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
882   {
883     //    std::cout << "SQLiteTreeHandler::DBRecursiveRemoveNode('"
884     //        <<node->GetLabel()<<"')"<<std::endl;
885
886     std::string query = "DELETE FROM ";
887     query += SQLiteTreeHandlerStructure::Table(node->GetType());
888     query += " WHERE ID='"+ node->GetFieldValue("ID") + "';";
889  
890     UPDATEDB(query);
891
892     Node::ChildrenListType::iterator i;
893     for (i  = node->GetChildrenList().begin();
894          i != node->GetChildrenList().end();
895          i++)
896       {
897         DBRecursiveRemoveNode((*i));
898       }
899   }
900   //=====================================================================
901   
902   //=====================================================================
903   int SQLiteTreeHandler::DBQueryNumberOfChildren(Node* node)
904   {
905     std::string query = "SELECT COUNT (ID) FROM ";
906     query += SQLiteTreeHandlerStructure::Table(node->GetType()+1);
907     if (node->GetType() != Node::Database) 
908       {
909         query += " WHERE PARENT_ID='"+ node->GetFieldValue("ID")+"'";
910       }
911     query  += ";";
912     
913     //   std::cout << "**SQL = "<< query << std::endl;
914     
915     CppSQLite3Query q;
916     QUERYDB(query,q);
917    
918      //    std::cout << "**RES = "<< q.getIntField(0) <<std::endl;
919
920     return q.getIntField(0);
921   }
922   //=====================================================================
923  
924   //========================================================================
925   std::string& format_sql2(std::string& str)
926   {
927     // quote must be doubled
928     //    crea::Utils::Replace( str, "'", "''" );
929     boost::algorithm::replace_all(str,"'","''");
930     // Found strange strings which contained NULL char INSIDE string 
931     int i,size=str.size();
932     for (i=0;i<size;++i) 
933       {
934         if (str[i]==0) 
935           {
936             str = str.substr(0,i);
937             break;
938           }
939       }
940     //    if (i<str.size())
941     return str;
942   }
943    //========================================================================
944
945   //=====================================================================
946   void SQLiteTreeHandler::BuildSQLFieldsValues(Node* n,
947                                         std::string& str)
948   {
949     //    std::cout << "BuildSQLFieldsValues('"<<n->GetLabel()<<"')"<<std::endl;
950
951     std::string atts="";
952     std::string values="";
953     Node::FieldValueMapType::iterator i;
954     for (i =  n->GetFieldValueMap().begin();
955          i != n->GetFieldValueMap().end();
956          i++)
957       {
958         if (i->first=="ID") 
959           {
960             continue;
961           }
962         //      std::cout << "("<<i->first<<","<<i->second<<")"<<std::endl;
963         atts += "'" + i->first + "'";
964         values += "'" + format_sql2(i->second) + "'"; 
965         atts += ",";
966         values += ",";
967       }
968     atts[atts.size()-1]=' ';
969     values[values.size()-1]=' ';
970
971     str = "("+atts+") VALUES ("+values+")";
972
973   }
974   //=====================================================================
975 */
976
977
978
979 } // namespace creaImageIO