00001 #include <creaImageIOSQLiteTreeHandler.h>
00002 #include <creaImageIOSystem.h>
00003 #include <creaImageIOGimmick.h>
00004
00005 #include "CppSQLite3.h"
00006
00007 #include <sys/stat.h>
00008
00009 #include <deque>
00010
00011 #include <creaWx.h>
00012 #include <boost/algorithm/string.hpp>
00013 using namespace crea;
00014
00015
00016
00017 namespace creaImageIO
00018 {
00019 using namespace tree;
00020
00021
00022
00023 SQLiteTreeHandler::SQLiteTreeHandler(const std::string& filename)
00024 : mFileName(filename)
00025 {
00026 mDB = new CppSQLite3DB;
00027 mIsAdding=false;
00028
00029 }
00030
00031
00032
00033 SQLiteTreeHandler::~SQLiteTreeHandler()
00034 {
00035 delete mDB;
00036 }
00037
00038
00039
00040
00041
00042
00043
00044 bool SQLiteTreeHandler::Open(bool writable)
00045 {
00046
00047
00048 SetWritable(writable);
00049 return DBOpen();
00050 }
00051
00052
00053 bool SQLiteTreeHandler::Create(bool writable)
00054 {
00055
00056 SetWritable(writable);
00057 return DBCreate();
00058 }
00059
00060
00061
00062
00063 bool SQLiteTreeHandler::Close()
00064 {
00065 return true;
00066 }
00067
00068
00069
00070
00071 bool SQLiteTreeHandler::Destroy()
00072 {
00073 return false;
00074 }
00075
00076
00077
00078
00079 int SQLiteTreeHandler::LoadChildren(tree::Node* parent, int maxlevel)
00080 {
00081
00082 if (parent==0) parent = GetTree().GetTree();
00083 return DBLoadChildren(parent,maxlevel);
00084 }
00085
00086
00087
00088
00089
00090
00091 void SQLiteTreeHandler::UnLoad(tree::Node* n)
00092 {
00093 }
00094
00095
00096
00097 int SQLiteTreeHandler::AddBranch( const AttributeMapType& attr )
00098 {
00099 tree::Node* parent = DBGetParent(attr);
00100 DBGraftToParent(parent,attr);
00101 return (parent->GetLevel()+1);
00102
00103 }
00104
00105
00106
00107
00108 bool SQLiteTreeHandler::Remove(tree::Node* node)
00109 {
00110 DBRecursiveRemoveNode(node);
00111
00112
00113 bool remove=false;
00114 tree::Node* parent=node->GetParent();
00115 if (parent)
00116 {
00117 int nC = parent->RemoveChildrenFromList(node);
00118 if(nC>0 && parent->GetLevel()>0)
00119 {
00120 std::stringstream out;
00121 out <<nC;
00122 SetAttribute(parent,"NumberOfChildren",out.str());
00123 }
00124 else
00125 {
00126 remove=true;
00127 }
00128
00129 }
00130 delete node;
00131 if(remove&&parent->GetLevel()>0)
00132 {
00133 Remove(parent);
00134 }
00135
00136 return true;
00137 }
00138
00139
00140
00141
00143 bool SQLiteTreeHandler::SetAttribute(tree::Node* n,
00144 const std::string& key,
00145 const std::string& value)
00146 {
00147 if (n==0) n=GetTree().GetTree();
00148 return DBSetAttribute(n,key,value);
00149 }
00150
00151
00153 void SQLiteTreeHandler::SetAttribute(const std::string& levelDescriptor,
00154 const std::string& key,
00155 const std::string& value,
00156 const std::string& searchParam,
00157 const std::string& searchVal)
00158 {
00159 DBSetAttribute(levelDescriptor,key,value,searchParam, searchVal);
00160 }
00161
00163 void SQLiteTreeHandler::DeleteTuple(std::string levelDescriptor,
00164 std::string key, std::string value)
00165 {
00166 DBDelete(levelDescriptor,key,value);
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 char* format_sql(const std::string& s)
00191 {
00192 return sqlite3_mprintf("%q",s.c_str());
00193 }
00194
00195
00196
00197
00198 #define QUERYDB(QUER,RES) \
00199 try \
00200 { \
00201 GimmickMessage(2,"SQL query: '"<<QUER<<"'"<<std::endl); \
00202 RES = mDB->execQuery(QUER.c_str()); \
00203 } \
00204 catch (CppSQLite3Exception& e) \
00205 { \
00206 GimmickError("SQLite query '"<<QUER<<"' : " \
00207 << e.errorCode() << ":" \
00208 << e.errorMessage() ); \
00209 } \
00210
00211
00212
00213
00214 #define UPDATEDB(UP) \
00215 try \
00216 { \
00217 GimmickMessage(2,"SQL update: '"<<UP<<"'"<<std::endl); \
00218 mDB->execDML(UP.c_str()); \
00219 } \
00220 catch (CppSQLite3Exception& e) \
00221 { \
00222 GimmickError("SQLite update '"<<UP<<"' Error : " \
00223 << e.errorCode() << ":" \
00224 << e.errorMessage() ); \
00225 }
00226
00227
00228
00229
00230 bool SQLiteTreeHandler::DBOpen()
00231 {
00232 GimmickMessage(1,"Opening SQLite database '"<<GetFileName()
00233 <<"' ... "<<std::endl);
00234
00235 if (!boost::filesystem::exists(GetFileName()))
00236 {
00237 return false;
00238 }
00239
00240 try
00241 {
00242 mDB->open(GetFileName().c_str());
00243 mDB->execDML("pragma synchronous=off;");
00244 }
00245 catch (CppSQLite3Exception& e)
00246 {
00247 GimmickError("Opening '"<<GetFileName()<<"' : "
00248 << e.errorCode() << ":"
00249 << e.errorMessage());
00250 return false;
00251 }
00252
00253 if (!DBImportTreeDescription())
00254 {
00255 return false;
00256 }
00257
00258 GimmickDebugMessage(1,"Opening SQLite database '"<<GetFileName()
00259 <<"' ... OK"<<std::endl);
00260 return true;
00261 }
00262
00263
00264
00265 bool SQLiteTreeHandler::DBCreate()
00266 {
00267 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
00268 <<"' ... "<<std::endl);
00269
00270 if (boost::filesystem::exists(GetFileName()))
00271 {
00272 GimmickError(GetFileName()<<"' : "
00273 << "file already exists");
00274 return false;
00275 }
00276
00277
00278 try
00279 {
00280 mDB->open(GetFileName().c_str());
00281 }
00282 catch (CppSQLite3Exception& e)
00283 {
00284 GimmickError(e.errorCode() << ":"
00285 << e.errorMessage() <<std::endl);
00286 return false;
00287 }
00288 mDB->execDML("pragma synchronous=off;");
00289
00290
00291
00292 std::string command;
00293
00294 command = "create table LEVELS\n";
00295 command += "( Name text )\n";
00296 UPDATEDB(command);
00297 int l;
00298
00299 for (l=0; l<GetTree().GetNumberOfLevels(); l++)
00300 {
00301 command = "INSERT INTO LEVELS (Name) VALUES ('";
00302 command += GetTree().GetLevelDescriptor(l).GetName();
00303 command += "')";
00304 UPDATEDB(command);
00305
00306
00307 if (l>=0)
00308 {
00309 command = "CREATE TABLE ";
00310 command += GetTree().GetLevelDescriptor(l).GetName();
00311 command += "\n(\nID INTEGER PRIMARY KEY";
00312 if (l>1)
00313 {
00314 command += ",\nPARENT_ID int not null";
00315 }
00316 SQLAppendAttributesDefinition(l,command);
00317 if (l>1)
00318 {
00319 command += ",\nconstraint FK_PARENT foreign key (PARENT_ID) references ";
00320 command += GetTree().GetLevelDescriptor(l-1).GetName();
00321 command += "(ID) on delete restrict on update restrict";
00322 }
00323 command += "\n)";
00324 UPDATEDB(command);
00325
00326 GetTree().CopyAttributeDescriptorList(l);
00327
00328
00329 GetTree().GetDescriptor().Add
00330 (AttributeDescriptor( "ID",
00331 "Database Identifier",
00332 0,0,
00333 AttributeDescriptor::PRIVATE
00334 ),l);
00335
00336 if (l>1)
00337 {
00338
00339 GetTree().GetDescriptor().Add
00340 (AttributeDescriptor( "PARENT_ID",
00341 "Database Parent Identifier",
00342 0,0,
00343 AttributeDescriptor::PRIVATE
00344 ),l);
00345 }
00346
00347 }
00348
00349
00350
00351 command = "CREATE TABLE ";
00352 command += GetTree().GetLevelDescriptor(l).GetName();
00353 command += "_Attributes\n(\n";
00354 command += "Key text,\n";
00355 command += "Name text,\n";
00356 command += "DicomGroup int,\n";
00357 command += "DicomElement int,\n";
00358 command += "Flags int\n";
00359 command += "\n)";
00360 UPDATEDB(command);
00361
00362
00363 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
00364 for (i = GetTree().GetAttributeDescriptorList(l).begin();
00365 i != GetTree().GetAttributeDescriptorList(l).end();
00366 ++i)
00367 {
00368
00369 std::stringstream insert;
00370 insert << "INSERT INTO "
00371 << GetTree().GetLevelDescriptor(l).GetName()
00372 << "_Attributes (Key,Name,DicomGroup,DicomElement,Flags) "
00373 << "VALUES ('"
00374 << i->GetKey() << "','"
00375 << i->GetName() << "',"
00376 << i->GetGroup() << ","
00377 << i->GetElement() << ","
00378 << i->GetFlags() << ");";
00379 UPDATEDB(insert.str());
00380 }
00381
00382 }
00383
00384
00385 GetTree().InitializeAttributeMap();
00386
00387 DBInsert(GetTree().GetTree());
00388
00389
00390 GetTree().SetChildrenLoaded(true);
00391 GimmickMessage(1,"Creating SQLite database '"<<GetFileName()
00392 <<"' ... OK"<<std::endl);
00393 return true;
00394 }
00395
00396
00397
00398 void SQLiteTreeHandler::SQLAppendAttributesDefinition(int level,
00399 std::string& s)
00400 {
00401 LevelDescriptor::AttributeDescriptorListType::const_iterator i;
00402 for (i = GetTree().GetAttributeDescriptorList(level).begin();
00403 i != GetTree().GetAttributeDescriptorList(level).end();
00404 ++i)
00405 {
00406
00407 s += ",\n";
00408 s += i->GetKey();
00409 s += " text";
00410 }
00411 }
00412
00413
00414
00415
00416 bool SQLiteTreeHandler::DBImportTreeDescription()
00417 {
00418 GimmickMessage(1,"Importing tree description for database ..."
00419 <<std::endl);
00420
00421
00422 if ( ! mDB->tableExists("LEVELS") )
00423 {
00424 GimmickMessage(1,"!! ERROR : Table 'LEVELS' does not exist"
00425 <<std::endl);
00426 return false;
00427 }
00428
00429 tree::Descriptor& desc = GetTree().GetDescriptor();
00430
00431 desc.Clear();
00432
00433 int nblevel = 0;
00434 std::string query = "SELECT * FROM LEVELS";
00435 CppSQLite3Query q;
00436 QUERYDB(query,q);
00437
00438 while (!q.eof())
00439 {
00440 std::string name = q.getStringField(0);
00441 GimmickMessage(2," * Importing level '"<<name<<"'"<<std::endl);
00442 desc.Add(LevelDescriptor(name));
00443 nblevel++;
00444 q.nextRow();
00445 }
00446
00447 for (int level = 0; level < nblevel; ++level )
00448 {
00449 std::string table = GetTree().GetLevelDescriptor(level).GetName();
00450 table += "_Attributes";
00451
00452 if ( ! mDB->tableExists(table.c_str()) )
00453 {
00454 GimmickMessage(1,"!! ERROR : Table '"<<table<<"' does not exist"
00455 <<std::endl);
00456 return false;
00457 }
00458
00459 std::string query = "SELECT * FROM ";
00460 query += table;
00461 CppSQLite3Query q;
00462 QUERYDB(query,q);
00463
00464 GimmickMessage(2," * Level '"
00465 <<GetTree().GetLevelDescriptor(level).GetName()
00466 <<"'"<<std::endl);
00467
00468
00469 bool ID_found = false;
00470 bool PARENT_ID_found = false;
00471 if (level==0) ID_found = true;
00472 if (level<=1) PARENT_ID_found = true;
00473
00474 while (!q.eof())
00475 {
00476 std::string key(q.getStringField(0));
00477 std::string name(q.getStringField(1));
00478 GimmickMessage(2," - Importing attribute '"<<key<<"' '"<<name
00479 <<"'"<<std::endl);
00480 desc.Add
00481 (AttributeDescriptor( key,
00482 name,
00483 q.getIntField(2),
00484 q.getIntField(3),
00485 q.getIntField(4)
00486 ),level);
00487 if ( key == "ID" )
00488 {
00489 ID_found = true;
00490 }
00491 if ( key == "PARENT_ID" )
00492 {
00493 PARENT_ID_found = true;
00494 }
00495 q.nextRow();
00496 }
00497
00498 if ( ! (ID_found || PARENT_ID_found ) )
00499 {
00500 GimmickMessage(1,"!! ERROR : Table '"<<table
00501 <<"' does not contain mandatory attribute ID or PARENT_ID"
00502 <<std::endl);
00503 return false;
00504
00505 }
00506 GetTree().CopyAttributeDescriptorList(level);
00507 }
00508
00509
00510
00511 LevelDescriptor::AttributeDescriptorListType::const_iterator a;
00512 for (a = GetTree().GetAttributeDescriptorList(0).begin();
00513 a!= GetTree().GetAttributeDescriptorList(0).end();
00514 ++a)
00515 {
00516
00517 GetTree().UnsafeSetAttribute( a->GetKey(), "" );
00518 }
00519
00520
00521
00522 query = "SELECT * FROM ";
00523 query += GetTree().GetLevelDescriptor(0).GetName();
00524 QUERYDB(query,q);
00525
00526 for (int fld = 0; fld < q.numFields(); fld++)
00527 {
00528 GetTree().UnsafeSetAttribute(q.fieldName(fld),
00529 q.getStringField(fld));
00530 }
00531
00532 GimmickMessage(1,"Importing tree description from database ... OK"
00533 <<std::endl);
00534 return true;
00535 }
00536
00537
00538
00540 void SQLformat(std::string i_str, std::string &o_str)
00541 {
00542
00543 boost::algorithm::replace_all(i_str,"'","''");
00544
00545 int i,size=i_str.size();
00546 for (i=0;i<size;++i)
00547 {
00548 if (i_str[i]==0)
00549 {
00550 i_str = i_str.substr(0,i);
00551 break;
00552 }
00553 }
00554 o_str = i_str;
00555 }
00556
00557
00558
00559 void SQLiteTreeHandler::SQLAppendAttributesValues(tree::Node* n,
00560 std::string& str)
00561 {
00562 GimmickMessage(4,"SQLAppendAttributesValues"<<std::endl);
00563 std::string atts="";
00564 std::string values="";
00565 std::string out ="";
00566 tree::Node::AttributeMapType::iterator i;
00567 for (i = n->GetAttributeMap().begin();
00568 i != n->GetAttributeMap().end();
00569 i++)
00570 {
00571 if (i->first=="ID")
00572 {
00573 continue;
00574 }
00575
00576 atts += "'" + i->first + "'";
00577 SQLformat(i->second, out);
00578 values += "'" + out + "'";
00579 atts += ",";
00580 values += ",";
00581 GimmickMessage(4,"'"<<i->first<<"' = '"<<i->second<<"'"<<std::endl);
00582 }
00583 atts[atts.size()-1]=' ';
00584 values[values.size()-1]=' ';
00585
00586 str = "("+atts+") VALUES ("+values+")";
00587 GimmickMessage(4,"Result = '"<<str<<"'"<<std::endl);
00588 }
00589
00590
00591
00592 tree::Node* SQLiteTreeHandler::DBGetParent( const AttributeMapType& attr)
00593 {
00594 Node* parent = GetTree().GetTree();
00595 bool go_down;
00596 do
00597 {
00598 go_down = false;
00599
00600 DBLoadChildren(parent);
00601
00602 tree::Node::ChildrenListType::const_iterator i;
00603 for (i = parent->GetChildrenList().begin();
00604 i!= parent->GetChildrenList().end();
00605 ++i)
00606 {
00607 if ( (*i)->Matches( attr ) )
00608 {
00609 go_down = true;
00610 parent = *i;
00611 break;
00612 }
00613 }
00614 }
00615 while (go_down);
00616 return parent;
00617 }
00618
00619
00620
00621 int SQLiteTreeHandler::DBLoadChildren(tree::Node* node,
00622 int numberoflevels)
00623 {
00624 if (node->GetLevel()+1 >= node->GetTree()->GetNumberOfLevels() )
00625 return 0;
00626
00627 GimmickMessage(2,"Loading children of '"<<node->GetLabel()
00628 <<"'"<<std::endl);
00629
00630 int nbloaded = 0;
00631
00632
00633 if (node->GetChildrenLoaded())
00634 {
00635
00636
00637 tree::Node::ChildrenListType::iterator i;
00638 for (i = node->GetChildrenList().begin();
00639 i!= node->GetChildrenList().end();
00640 ++i)
00641 {
00642 nbloaded += DBLoadChildren(*i,numberoflevels-1);
00643 }
00644 node->SetChildrenLoaded(true);
00645 return nbloaded;
00646
00647 }
00648 else
00649 {
00651
00652
00653 int level = node->GetLevel();
00654 std::string query = "SELECT * FROM ";
00655
00656 query += GetTree().GetLevelDescriptor(level+1).GetName();
00657 if (level>0)
00658 {
00659 query += " WHERE PARENT_ID='" + node->GetAttribute("ID")
00660 + "'";
00661 }
00662 GimmickDebugMessage(1, "query : '" <<query <<std::endl);
00663 CppSQLite3Query q;
00664 QUERYDB(query,q);
00665
00666 int p=0;
00667 while (!q.eof())
00668 {
00669
00670
00671
00672 nbloaded++;
00673 Node* n = new Node(node);
00674 for (int fld = 0; fld < q.numFields(); fld++)
00675 {
00676 n->UnsafeSetAttribute(q.fieldName(fld),q.getStringField(fld));
00677 }
00678
00679
00680 if ( numberoflevels != 1 )
00681 {
00682
00683 nbloaded += DBLoadChildren(n, numberoflevels-1);
00684
00685 }
00686
00687 q.nextRow();
00688 }
00689
00690 node->SetChildrenLoaded(true);
00691
00692
00693
00694 return nbloaded;
00695 }
00696 }
00697
00698
00699
00700 void SQLiteTreeHandler::DBInsert(tree::Node* n)
00701 {
00702 GimmickMessage(2,"Inserting in DB '"<<n->GetLabel()
00703 <<"'"<<std::endl);
00704 std::string val;
00705 SQLAppendAttributesValues(n,val);
00706 std::string insert("INSERT INTO ");
00707 insert += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
00708 insert += " " + val + ";";
00709
00710 UPDATEDB(insert);
00711
00712
00713 long lastrow = mDB->lastRowId();
00714 std::stringstream ri;
00715 ri << mDB->lastRowId();
00716 n->SetAttribute("ID",ri.str());
00717 }
00718
00719
00720
00722 void SQLiteTreeHandler::DBGraftToParent( tree::Node* parent,
00723 const AttributeMapType& attr)
00724 {
00725
00726
00727
00728 for (int level = parent->GetLevel()+1;
00729 level < GetTree().GetNumberOfLevels();
00730 level++)
00731 {
00732
00733 tree::Node* child = new tree::Node(parent,attr);
00734 child->SetChildrenLoaded(true);
00735 if (level>1)
00736 {
00737 int nc = GetNumberOfChildren(parent)+1;
00738
00739
00740 std::stringstream out;
00741 out << nc;
00742 SetAttribute(parent,"NumberOfChildren",out.str());
00743 }
00744
00745
00746 if ( parent->GetLevel()>0 )
00747 child->SetAttribute("PARENT_ID",parent->GetAttribute("ID"));
00748
00749
00750 DBInsert(child);
00751
00752
00753 parent = child;
00754 }
00755 }
00756
00757
00758
00759
00761 bool SQLiteTreeHandler::DBSetAttribute(tree::Node* n,
00762 const std::string& key,
00763 const std::string& value)
00764 {
00765 GimmickMessage(3,"Setting Attribute of '"<<n->GetLabel()<<
00766 "' "<<key<<"='"<<value<<"'"<<std::endl);
00767
00768 n->SetAttribute(key,value);
00769 std::string sql = "UPDATE ";
00770 sql += GetTree().GetLevelDescriptor(n->GetLevel()).GetName();
00771 sql += " SET ";
00772 sql += key;
00773 sql += " = '";
00774 sql += convert(value);
00775 sql += "' WHERE ID = '";
00776 sql += n->GetAttribute("ID");
00777 sql +="'";
00778
00779 UPDATEDB(sql);
00780 return true;
00781 }
00782
00783
00785 void SQLiteTreeHandler::DBSetAttribute(const std::string& levelDescriptor,
00786 const std::string& key,
00787 const std::string& value,
00788 const std::string& searchParam,
00789 const std::string& searchVal)
00790 {
00791
00792 std::string sql = "UPDATE ";
00793 sql += levelDescriptor;
00794 sql += " SET ";
00795 sql += key;
00796 sql += " = '";
00797 sql += value;
00798 sql += "' WHERE ";
00799 sql += searchParam;
00800 sql += " = '";
00801 sql += searchVal;
00802 sql += "'";
00803 std::cout<<sql<<std::endl;
00804 UPDATEDB(sql);
00805 }
00806
00807 void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node)
00808 {
00809
00810 std::string query = "DELETE FROM ";
00811 query += GetTree().GetLevelDescriptor(node->GetLevel()).GetName();
00812 query += " WHERE ID='"+ node->GetAttribute("ID") + "';";
00813 UPDATEDB(query);
00814
00815 if(node->GetNumberOfChildren()!=0)
00816 {
00817 Node::ChildrenListType::iterator i;
00818 for (i = node->GetChildrenList().begin();
00819 i != node->GetChildrenList().end();
00820 i++)
00821 {
00822 DBRecursiveRemoveNode((*i));
00823 }
00824 }
00825 else if(node->GetLevel()<GetTree().GetNumberOfLevels()-1)
00826 {
00827 DBRecursiveRemoveNode(node->GetLevel()+1,node->GetAttribute("ID"));
00828 }
00829 }
00830
00831
00832 void SQLiteTreeHandler::DBRecursiveRemoveNode(int level, std::string parentId)
00833 {
00834 std::stringstream out;
00835 std::stringstream result;
00836 out<<"SELECT ID FROM "<<GetTree().GetLevelDescriptor(level).GetName()<<" WHERE PARENT_ID='"<<parentId<<"'";
00837
00838 CppSQLite3Query q;
00839 QUERYDB(out.str(),q);
00840
00841 while (!q.eof())
00842 {
00843 for (int fld = 0; fld < q.numFields(); fld++)
00844 {
00845 result<<q.getStringField(fld)<<"#";
00846 }
00847 q.nextRow();
00848 }
00849 std::string res=result.str();
00850 size_t ini=0;
00851 size_t fin=0;
00852 while(fin<res.size()-1)
00853 {
00854 fin=res.find('#',ini);
00855 DBDelete(GetTree().GetLevelDescriptor(level).GetName(),"ID",res.substr(ini,fin-ini));
00856 if(level<GetTree().GetNumberOfLevels()-1)
00857 {
00858 DBRecursiveRemoveNode(level+1,res.substr(ini,fin-ini));
00859 }
00860 ini=fin+1;
00861 }
00862
00863
00864 }
00865
00866
00867 void SQLiteTreeHandler::DBDelete(std::string levelDescriptor, std::string key, std::string value)
00868 {
00869
00870 std::stringstream query;
00871 query<<"DELETE FROM "<<levelDescriptor<<" WHERE "<<key<<"='"<<value<<"';";
00872
00873 UPDATEDB(query.str());
00874 GimmickDebugMessage(2," Deleting: Query: "<<query.str()<<std::endl);
00875 }
00876
00877
00878
00879 void SQLiteTreeHandler::GetAttribute(std::string levelDescriptor,
00880 std::string searchParam,
00881 std::string searchVal,
00882 std::string key,
00883 std::string& result)
00884 {
00885 std::stringstream out;
00886 std::stringstream results;
00887 out<<"SELECT "<<key<<" FROM "<<levelDescriptor;
00888 if(searchParam!="")
00889 {
00890 out<<" WHERE "<<searchParam<<"='"<<searchVal<<"'";
00891 }
00892
00893 CppSQLite3Query q;
00894 QUERYDB(out.str(),q);
00895
00896
00897 while (!q.eof())
00898 {
00899 for (int fld = 0; fld < q.numFields(); fld++)
00900 {
00901 results<<q.getStringField(fld);
00902 if(searchParam=="")
00903 {
00904 results<<"#";
00905 }
00906 }
00907 q.nextRow();
00908 }
00909 result=results.str();
00910
00911 }
00912
00913 unsigned int SQLiteTreeHandler::GetNumberOfChildren(tree::Node* n)
00914 {
00915
00916 int nb=0;
00917 int level = n->GetLevel();
00918
00919 if(level<GetTree().GetNumberOfLevels()&& level>0)
00920 {
00921 std::string query = "SELECT NumberOfChildren FROM ";
00922 query += GetTree().GetLevelDescriptor(level).GetName();
00923 if (level>0)
00924 {
00925 query += " WHERE ID='" + n->GetAttribute("ID")
00926 + "'";
00927 }
00928 CppSQLite3Query q;
00929 QUERYDB(query,q);
00930
00931
00932 while (!q.eof())
00933 {
00934 for (int fld = 0; fld < q.numFields(); fld++)
00935 {
00936 nb=q.getIntField(fld);
00937 }
00938 q.nextRow();
00939 }
00940 }
00941
00942
00943
00944
00945
00946
00947 return nb;
00948 }
00949
00950
00951
00952 void SQLiteTreeHandler::getAllAttributes(std::string i_filename, std::map<std::string, std::string> &i_results)
00953 {
00954 int level=GetTree().GetNumberOfLevels()-1;
00955
00956 std::string search = i_filename;
00957 std::string param = "FullFileName";
00958 std::string name;
00959
00960 std::string id;
00961 std::set<std::string> pid;
00962 std::vector<AttributeDescriptor> attr;
00963 std::vector<AttributeDescriptor>::iterator it_attr;
00964 std::vector<std::string> values;
00965 std::vector<std::string>::iterator it_val;
00966
00967
00968
00969
00970 while(level>1)
00971 {
00972 attr = GetTree().GetAttributeDescriptorList(level,1);
00973
00974 name = GetTree().GetLevelDescriptor(level).GetName();
00975 std::vector<std::string> values;
00976 GetUpLevelNodeId(level, param,search,id);
00977 GetAttributes(name, param,search,attr, values);
00978 for(it_attr = attr.begin(), it_val = values.begin(); it_attr != attr.end(); it_attr++, it_val++)
00979 {
00980 i_results[(*it_attr).GetKey()] = (*it_val).c_str();
00981 }
00982 search = id;
00983 param = "ID";
00984 level --;
00985 }
00986 }
00987
00988
00989
00990
00991 void SQLiteTreeHandler::GetAttributes(std::string name, std::string i_id, std::string i_value, tree::LevelDescriptor::AttributeDescriptorListType i_attr, std::vector<std::string> &i_results)
00992 {
00993
00994 std::stringstream out;
00995 std::stringstream results;
00996 out<<"SELECT ";
00997 tree::LevelDescriptor::AttributeDescriptorListType::iterator it = i_attr.begin();
00998 std::string query ="";
00999 for(; it != i_attr.end(); it++)
01000 {
01001 query += (*it).GetKey();
01002 query +=" ,";
01003 }
01004 query = query.substr(0, query.size()-1);
01005 out << query;
01006 out << "FROM "<<name;
01007 out<<" WHERE "<<i_id <<"='"<<i_value<<"'";
01008 CppSQLite3Query q;
01009 QUERYDB(out.str(),q);
01010 while (!q.eof())
01011 {
01012 for (int fld = 0; fld < q.numFields(); fld++)
01013 {
01014 i_results.push_back(q.getStringField(fld));
01015 }
01016 q.nextRow();
01017 }
01018 }
01019
01020 void SQLiteTreeHandler::GetUpLevelNodeId(int level, const std::string& searchParam, const std::string& searchValue, std::string& parent_id)
01021 {
01022 std::string sp=searchParam.c_str();
01023 std::string sv=searchValue.c_str();
01024 std::stringstream out;
01025 std::stringstream results;
01026 out<<"SELECT PARENT_ID FROM "<<GetTree().GetLevelDescriptor(level).GetName();
01027 out<<" WHERE "<<sp<<"='"<<sv<<"'";
01028 CppSQLite3Query q;
01029 QUERYDB(out.str(),q);
01030 while (!q.eof())
01031 {
01032 for (int fld = 0; fld < q.numFields(); fld++)
01033 {
01034 results<<q.getStringField(fld);
01035 }
01036 q.nextRow();
01037 }
01038 parent_id = results.str();
01039
01040 }
01041
01042
01043
01044 void SQLiteTreeHandler::GetTopLevelNodeId(const std::string& searchParam, const std::string& searchValue, std::string& parent_id)
01045 {
01046 int level=GetTree().GetNumberOfLevels()-1;
01047 std::string sp=searchParam.c_str();
01048 std::string sv=searchValue.c_str();
01049
01050 while(level>1)
01051 {
01052 GetUpLevelNodeId(level, sp, sv, parent_id);
01053 level--;
01054 sp = "ID";
01055 sv = parent_id;
01056 }
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080 }
01081
01082
01083 void SQLiteTreeHandler::RemoveEntries(const std::string i_table,
01084 const std::string i_attribute,
01085 const std::string i_operand,
01086 const std::string i_val)
01087 {
01088 std::stringstream query;
01089 query<<"DELETE FROM "<<i_table<<" WHERE "<<i_attribute<<" "<<i_operand<<" '"<<i_val<<"'";
01090 UPDATEDB(query.str());
01091 }
01092
01093
01094 void SQLiteTreeHandler::BeginTransaction()
01095 {
01096 std::stringstream out;
01097 out<<"begin transaction;";
01098 UPDATEDB(out.str());
01099 }
01100
01101
01102 void SQLiteTreeHandler::EndTransaction()
01103 {
01104 std::stringstream out;
01105 out<<"commit transaction;";
01106 UPDATEDB(out.str());
01107 }
01108 const std::string SQLiteTreeHandler::convert(const std::string &i_word)
01109 {
01110 std::string temp = i_word;
01111 boost::algorithm::replace_all(temp,"'","''");
01112 return temp.c_str();
01113 }
01114
01115 }