X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src2%2FcreaImageIOSQLiteTreeHandler.cpp;h=3d3fe70c1639ad2357a75f628ff63462020a2e9f;hb=2df647c186de559388c62bfebba8795b860ee8ae;hp=4d0d49eae165825a158b77f9788857c54d07a3a1;hpb=f4bdead5143dc3d816f1c2f2bd9786a21c843760;p=creaImageIO.git diff --git a/src2/creaImageIOSQLiteTreeHandler.cpp b/src2/creaImageIOSQLiteTreeHandler.cpp index 4d0d49e..3d3fe70 100644 --- a/src2/creaImageIOSQLiteTreeHandler.cpp +++ b/src2/creaImageIOSQLiteTreeHandler.cpp @@ -13,15 +13,9 @@ #include -#include "wx/wx.h" -#include -#include - - //#include #include -#include using namespace crea; #include @@ -37,6 +31,7 @@ namespace creaImageIO : mFileName(filename) { mDB = new CppSQLite3DB; + mIsAdding=false; GimmickMessage(1,"SQLite version : " <SQLiteVersion())<< std::endl); } @@ -50,22 +45,6 @@ namespace creaImageIO //============================================================= - //============================================================= - void SQLiteTreeHandler::BuildDefaultTreeDescription() - { - /* - for (int i = Node::Patient; - i <= Node::Image; - ++i) - { - mNodeTypeDescription[i].BuildDefault(i); - } - */ - - // TODO : GetTree().GetDescription().LoadXML(FILE); - } - //============================================================= - //============================================================= // void SQLiteTreeHandler::Print() const // { @@ -91,54 +70,6 @@ namespace creaImageIO */ //===================================================================== - //===================================================================== - char* format_sql(const std::string& s) - { - return sqlite3_mprintf("%q",s.c_str()); - } - //===================================================================== - - // sqlite3_exec(db, zSQL, 0, 0, 0); - // sqlite3_free(zSQL); - // char* CHAIN = format_sql(QUER); \ -// sqlite3_free(CHAIN); \ - - //===================================================================== -#define QUERYDB(QUER,RES) \ - try \ - { \ - GimmickMessage(2,"SQL: '"<execQuery(QUER.c_str()); \ - } \ - catch (CppSQLite3Exception& e) \ - { \ - std::cout << "SQLite query '"<execDML(UP.c_str()); \ - } \ - catch (CppSQLite3Exception& e) \ - { \ - std::cout << "SQLite update '"<& attr ) + int SQLiteTreeHandler::AddBranch( const AttributeMapType& attr ) { - return -1; + tree::Node* parent = DBGetParent(attr); + DBGraftToParent(parent,attr); + return (parent->GetLevel()+1); + } //===================================================================== //===================================================================== - bool SQLiteTreeHandler::Remove(tree::Node*) + bool SQLiteTreeHandler::Remove(tree::Node* node) { - return false; + DBRecursiveRemoveNode(node); + + // std::cout << "DELETE"<GetParent(); + if (parent) + { + int nC = parent->RemoveChildrenFromList(node); + if(nC>0 && parent->GetLevel()>0) + { + std::stringstream out; + out <GetLevel()>0) + { + Remove(parent); + } + // std::cout << "DELETE OK"<execQuery(QUER.c_str()); \ + } \ + catch (CppSQLite3Exception& e) \ + { \ + GimmickError("SQLite query '"<execDML(UP.c_str()); \ + } \ + catch (CppSQLite3Exception& e) \ + { \ + GimmickError("SQLite update '"<0, i.e. not Root) + if (l>=0) { - command = "INSERT INTO LEVELS (Name) VALUES ('"; - command += GetTree().GetLevelDescriptor(l).GetName(); - command += "')"; - UPDATEDB(command); - command = "CREATE TABLE "; command += GetTree().GetLevelDescriptor(l).GetName(); - command += "\n(\nID INTEGER PRIMARY KEY,\nPARENT_ID int not null"; - AppendAttributesSQLDefinition(l,command); - command +=",\n"; - command +="constraint FK_PARENT foreign key (PARENT_ID) references PATIENT(ID) on delete restrict on update restrict\n)"; + command += "\n(\nID INTEGER PRIMARY KEY"; + if (l>1) + { + command += ",\nPARENT_ID int not null"; + } + SQLAppendAttributesDefinition(l,command); + if (l>1) + { + command += ",\nconstraint FK_PARENT foreign key (PARENT_ID) references "; + command += GetTree().GetLevelDescriptor(l-1).GetName(); + command += "(ID) on delete restrict on update restrict"; + } + command += "\n)"; UPDATEDB(command); + + + // Add Attribute 'ID' to Description + GetTree().GetDescriptor().Add + (AttributeDescriptor( "ID", + "Database Identifier", + 0,0, + AttributeDescriptor::PRIVATE + ),l); + + if (l>1) + { + // Add Attribute 'PARENT_ID' to Description + GetTree().GetDescriptor().Add + (AttributeDescriptor( "PARENT_ID", + "Database Parent Identifier", + 0,0, + AttributeDescriptor::PRIVATE + ),l); + } + } - // Create tables *_ATTRIBUTES - // and fill the tables *_ATTRIBUTES - DBExportTreeDescription(); - - } - catch (std::exception) - { - return false; - } - // LG : TEST - if (DBStructureIsValid()) - { - // std::cout << "*** DONE ***"<second.flags==1) continue; - s += ",\n"; - s += i->GetKey(); - s += " text"; - } - } - //===================================================================== - - //===================================================================== - void SQLiteTreeHandler::DBExportTreeDescription() - { - for (int level=0; levelGetKey() << "','" @@ -395,167 +408,703 @@ namespace creaImageIO << i->GetGroup() << "," << i->GetElement() << "," << i->GetFlags() << ");"; - UPDATEDB(insert.str()); } - } + + } // For l=0... + + // Initialize the root attributes + GetTree().InitializeAttributeMap(); + // Insert the root in the level 0 table + DBInsert(GetTree().GetTree()); + + GetTree().SetChildrenLoaded(true); + GimmickMessage(1,"Creating SQLite database '"<second.flags==1) continue; + s += ",\n"; + s += i->GetKey(); + s += " text"; + } + } + //===================================================================== + + + //===================================================================== + bool SQLiteTreeHandler::DBImportTreeDescription() + { + GimmickMessage(1,"Importing tree description from database ..." + <tableExists("LEVELS") ) { - std::string query = "SELECT * FROM "; - query += SQLiteTreeHandlerStructure::Table(type); - query += "_FIELDS"; + GimmickMessage(1,"!! ERROR : Table 'LEVELS' does not exist" + <tableExists(table.c_str()) ) + { + GimmickMessage(1,"!! ERROR : Table '"<GetKey()); + if ( i != attr.end() ) + { + v = i->second; + } + */ + GetTree().UnsafeSetAttribute( a->GetKey(), "" ); + } + + // Reading Root attributes + // Query DB + query = "SELECT * FROM "; + query += GetTree().GetLevelDescriptor(0).GetName(); + QUERYDB(query,q); + + for (int fld = 0; fld < q.numFields(); fld++) + { + GetTree().UnsafeSetAttribute(q.fieldName(fld), + q.getStringField(fld)); + } + + GimmickMessage(1,"Importing tree description from database ... OK" + <tableExists(SQLiteTreeHandlerStructure::Table(i)); - if (ok) + if (str[i]==0) { - // std::cout << "** Table "<GetAttributeMap().begin(); + i != n->GetAttributeMap().end(); + i++) + { + if (i->first=="ID") { - // std::cout << "** Table "<first<<","<second<<")"<first + "'"; + values += "'" + SQLformat(i->second) + "'"; + atts += ","; + values += ","; + GimmickMessage(4,"'"<first<<"' = '"<second<<"'"<ChildrenLoaded() ) + Node* parent = GetTree().GetTree(); + bool go_down; + do { - // std::cout << "--> Children already loaded"<GetType() == Node::Image ) - { - return nbloaded; + go_down = false; + // Load the children of the current parent + DBLoadChildren(parent); + // Iterate the children + tree::Node::ChildrenListType::const_iterator i; + for (i = parent->GetChildrenList().begin(); + i!= parent->GetChildrenList().end(); + ++i) + { + if ( (*i)->Matches( attr ) ) + { + go_down = true; + parent = *i; + break; + } + } } - if ( xparent->GetType() >= maxlevel ) + while (go_down); + return parent; + } + //===================================================================== + + + //===================================================================== + int SQLiteTreeHandler::DBLoadChildren(tree::Node* node, + int numberoflevels) + { + if (node->GetLevel()+1 >= node->GetTree()->GetNumberOfLevels() ) + return 0; + + GimmickMessage(2,"Loading children of '"<GetLabel() + <<"'"<GetChildrenLoaded()) { + // Iterate the children + + tree::Node::ChildrenListType::iterator i; + for (i = node->GetChildrenList().begin(); + i!= node->GetChildrenList().end(); + ++i) + { + nbloaded += DBLoadChildren(*i,numberoflevels-1); + } + node->SetChildrenLoaded(true); return nbloaded; - } - - // msw[2].Pause(); - // msw[2].Resume(); - Node::Type type = xparent->GetType()+1; + } + else + { + /// If children not loaded : do it and recurse // Query DB - + int level = node->GetLevel(); std::string query = "SELECT * FROM "; - query += GetTree().GetDescriptor().GetLevelDescriptor(level).GetName(); - //SQLiteTreeHandlerStructure::Table(type); - if (parent!=0) + + query += GetTree().GetLevelDescriptor(level+1).GetName(); + if (level>0) { - query += " WHERE PARENT_ID='" + parent->GetFieldValue("ID") + "'"; + query += " WHERE PARENT_ID='" + node->UnsafeGetAttribute("ID") + + "'"; } - - // std::cout << "** SQL = '"<SetFieldValue(q.fieldName(fld),q.getStringField(fld)); + n->UnsafeSetAttribute(q.fieldName(fld),q.getStringField(fld)); } + /* // Index TypeId ti; ti.type = type; ti.id = n->GetFieldValue("ID"); mTypeIdToNodeMap[ti] = n; + */ // recurse - if ( type < maxlevel ) + if ( numberoflevels != 1 ) { - msw[2].Pause(); - nbloaded += DBLoadChildren(n,maxlevel); - msw[2].Resume(); + // msw[2].Pause(); + nbloaded += DBLoadChildren(n, numberoflevels-1); + // msw[2].Resume(); } // next entry in db q.nextRow(); } - xparent->SetChildrenLoaded(true); + node->SetChildrenLoaded(true); + // msw[2].Pause(); return nbloaded; + } + } + //===================================================================== + + //====================================================================== + void SQLiteTreeHandler::DBInsert(tree::Node* n) + { + GimmickMessage(2,"Inserting in DB '"<GetLabel() + <<"'"<GetLevel()).GetName(); + insert += " " + val + ";"; + + UPDATEDB(insert); + + // Store DB id of newly created node; + long lastrow = mDB->lastRowId(); + std::stringstream ri; + ri << mDB->lastRowId(); + n->SetAttribute("ID",ri.str()); + } + //====================================================================== + + //====================================================================== + /// Graft the branch defined by the attributes to the parent + void SQLiteTreeHandler::DBGraftToParent( tree::Node* parent, + const AttributeMapType& attr) + { + // std::cout <<"Grafting to parent '"<GetLabel() + // <<"'"<GetLevel()+1; + level < GetTree().GetNumberOfLevels(); + level++) + { + // Create Node + tree::Node* child = new tree::Node(parent,attr); + child->SetChildrenLoaded(true); + if (level>1) + { + int nc = GetNumberOfChildren(parent)+1; + + // std::cout<<"Number of children "<GetNumberOfChildren()<GetLevel()>0 ) + child->SetAttribute("PARENT_ID",parent->GetAttribute("ID")); + + // Insert in DB + DBInsert(child); + /* + std::string val; + SQLAppendAttributesValues(child,val); + std::string insert("INSERT INTO "); + insert += GetTree().GetLevelDescriptor(child->GetLevel()).GetName(); + insert += " " + val + ";"; + UPDATEDB(insert); + + // Store DB id of newly created node; + long lastrow = mDB->lastRowId(); + std::stringstream ri; + ri << mDB->lastRowId(); + child->SetAttribute("ID",ri.str()); + */ + // Down one level + parent = child; + + /* + // Insert in TypeId map + TypeId ti; + ti.type = node->GetType(); + ti.id = node_id; + mTypeIdToNodeMap[ti] = node; + // std::cout << "== Insert TypeId ("<GetType()==Node::Patient) summary.added_patients++; + if (node->GetType()==Node::Study) summary.added_studies++; + if (node->GetType()==Node::Series) summary.added_series++; + if (node->GetType()==Node::Image) summary.added_images++; + */ + } + } + //====================================================================== + + + //===================================================================== + /// Sets an attribute of a Node + bool SQLiteTreeHandler::DBSetAttribute(tree::Node* n, + const std::string& key, + const std::string& value) + { + GimmickMessage(3,"Setting Attribute of '"<GetLabel()<< + "' "<SetAttribute(key,value); + std::string sql = "UPDATE "; + sql += GetTree().GetLevelDescriptor(n->GetLevel()).GetName(); + sql += " SET "; + sql += key; + sql += " = '"; + sql += value; + sql += "' WHERE ID = '"; + sql += n->GetAttribute("ID"); + sql +="'"; + // sql += " LIMIT 1"; + UPDATEDB(sql); + return true; + } + + //===================================================================== + /// Sets an attribute of a Node + void SQLiteTreeHandler::DBSetAttribute(const std::string& levelDescriptor, + const std::string& key, + const std::string& value, + const std::string& searchParam, + const std::string& searchVal) + { + + std::string sql = "UPDATE "; + sql += levelDescriptor; + sql += " SET "; + sql += key; + sql += " = '"; + sql += value; + sql += "' WHERE "; + sql += searchParam; + sql += " = '"; + sql += searchVal; + sql += "'"; + std::cout<GetLevel()).GetName(); + query += " WHERE ID='"+ node->GetAttribute("ID") + "';"; + + UPDATEDB(query); + GimmickDebugMessage(2, + " Deleting '" + <GetLabel()<<"' with ID '" + <GetAttribute("ID") + <<"' in level "<< GetTree().GetLevelDescriptor(node->GetLevel()).GetName() + <GetNumberOfChildren()!=0) + { + Node::ChildrenListType::iterator i; + for (i = node->GetChildrenList().begin(); + i != node->GetChildrenList().end(); + i++) + { + DBRecursiveRemoveNode((*i)); + } + } + else if(node->GetLevel()GetLevel()+1,node->GetAttribute("ID")); + } } + + //===================================================================== + void SQLiteTreeHandler::DBRecursiveRemoveNode(int level, std::string parentId) + { + std::stringstream out; + std::stringstream result; + out<<"SELECT ID FROM "<GetLevel(); + + if(level0) + { + std::string query = "SELECT NumberOfChildren FROM "; + query += GetTree().GetLevelDescriptor(level).GetName(); + if (level>0) + { + query += " WHERE ID='" + n->UnsafeGetAttribute("ID") + + "'"; + } + CppSQLite3Query q; + QUERYDB(query,q); + + + while (!q.eof()) + { + for (int fld = 0; fld < q.numFields(); fld++) + { + nb=q.getIntField(fld); + } + q.nextRow(); + } + } + /* + if(nb==0) + { + nb=1; + } + */ + return nb; + } + //===================================================================== + void SQLiteTreeHandler::GetTopLevelNodeId(const std::string& searchParam, const std::string& searchValue, std::string& parent_id) + { + int level=GetTree().GetNumberOfLevels()-1; + std::string sp=searchParam.c_str(); + std::string sv=searchValue.c_str(); + while(level>1) + { + std::stringstream out; + std::stringstream results; + out<<"SELECT PARENT_ID FROM "<GetParent()) @@ -857,6 +1408,8 @@ namespace creaImageIO // std::cout << "DELETE OK"<GetLabel()<<"')"<GetFieldValueMap().begin(); - i != n->GetFieldValueMap().end(); - i++) - { - if (i->first=="ID") - { - continue; - } - // std::cout << "("<first<<","<second<<")"<first + "'"; - values += "'" + format_sql2(i->second) + "'"; - atts += ","; - values += ","; - } - atts[atts.size()-1]=' '; - values[values.size()-1]=' '; - - str = "("+atts+") VALUES ("+values+")"; + - } - //===================================================================== */