X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;ds=sidebyside;f=src2%2FcreaImageIOSQLiteTreeHandler.cpp;h=f29a8ce7ef4b7ced02410167684d1b1405cfef16;hb=9482bdab20cd58378b088085f8fa8731d7b7b416;hp=e1a0307b3673093365844786789de7e0d589ac02;hpb=bae4df8a3e1ea669400c3a6c44ef4aa8d90fa1ed;p=creaImageIO.git diff --git a/src2/creaImageIOSQLiteTreeHandler.cpp b/src2/creaImageIOSQLiteTreeHandler.cpp index e1a0307..f29a8ce 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,29 +45,6 @@ namespace creaImageIO //============================================================= - //============================================================= - // void SQLiteTreeHandler::Print() const - // { - /* - std::cout << "-> '"<Print(); - } - */ - // } - //============================================================= - - //===================================================================== - /* - bool SQLiteTreeHandler::LocationIsValid() - { - // TO DO - return true; - } - */ //===================================================================== @@ -107,19 +79,14 @@ namespace creaImageIO { return false; } - //===================================================================== - - //===================================================================== - unsigned int SQLiteTreeHandler::GetNumberOfChildren(tree::Node* n) - { - return 0; - } + //===================================================================== //===================================================================== int SQLiteTreeHandler::LoadChildren(tree::Node* parent, int maxlevel) { - return 0; + if (parent==0) parent = GetTree().GetTree(); + return DBLoadChildren(parent,maxlevel); } //===================================================================== @@ -132,69 +99,79 @@ namespace creaImageIO } //===================================================================== - //===================================================================== int SQLiteTreeHandler::AddBranch( const AttributeMapType& attr ) { tree::Node* parent = DBGetParent(attr); - for (int level = parent->GetLevel()+1; - level < GetTree().GetNumberOfLevels(); - level++) - { - // Create Node - parent = new tree::Node(parent,attr); - - // Insert into DB - if (node->GetType()!=Node::Patient) - node->SetFieldValue("PARENT_ID",parent_id); - - // Insert in DB - std::string val; - BuildSQLFieldsValues(node,val); - std::string insert("INSERT INTO "); - insert += std::string(SQLiteTreeHandlerStructure::Table(node->GetType())) - + " " + val + ";"; - // std::cout << "** SQL = '"<lastRowId(); - std::stringstream ri; - ri << mDB->lastRowId(); - node_id = ri.str(); - // std::cout << "LastRowId='"<lastRowId()<<"' vs '"<SetFieldValue("ID",node_id); - /* - // 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++; - */ - } - return -1; + 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) \ { \ - std::cout << "SQLite query '"<execDML(UP.c_str()); \ } \ catch (CppSQLite3Exception& e) \ { \ - std::cout << "SQLite update '"<0, i.e. not Root) + if (l>=0) { - command = "INSERT INTO LEVELS (Name) VALUES ('"; + command = "CREATE TABLE "; command += GetTree().GetLevelDescriptor(l).GetName(); - command += "')"; + 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); - // Create table of level (for level>0, i.e. not Root) - if (l>0) + + // Add Attribute 'ID' to Description + GetTree().GetDescriptor().Add + (AttributeDescriptor( "ID", + "Database Identifier", + 0,0, + AttributeDescriptor::PRIVATE + ),l); + + if (l>1) { - command = "CREATE TABLE "; - command += GetTree().GetLevelDescriptor(l).GetName(); - command += "\n(\nID INTEGER PRIMARY KEY"; - if (l>1) - { - command += ",\nPARENT_ID int not null"; - } - AppendAttributesSQLDefinition(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().GetAttributeDescriptorList(l).push_back - (AttributeDescriptor( "ID", - "Database Identifier", + // Add Attribute 'PARENT_ID' to Description + GetTree().GetDescriptor().Add + (AttributeDescriptor( "PARENT_ID", + "Database Parent Identifier", 0,0, AttributeDescriptor::PRIVATE - )); - - if (l>1) - { - // Add Attribute 'PARENT_ID' to Description - GetTree().GetAttributeDescriptorList(l).push_back - (AttributeDescriptor( "PARENT_ID", - "Database Parent Identifier", - 0,0, - AttributeDescriptor::PRIVATE - )); - } - + ),l); } - // Create table *_ATTRIBUTES + } + + // Create table *_ATTRIBUTES + + command = "CREATE TABLE "; + command += GetTree().GetLevelDescriptor(l).GetName(); + command += "_Attributes\n(\n"; + command += "Key text,\n"; + command += "Name text,\n"; + command += "DicomGroup int,\n"; + command += "DicomElement int,\n"; + command += "Flags int\n"; + command += "\n)"; + UPDATEDB(command); + + + // Fill the table *_ATTRIBUTES + LevelDescriptor::AttributeDescriptorListType::const_iterator i; + for (i = GetTree().GetAttributeDescriptorList(l).begin(); + i != GetTree().GetAttributeDescriptorList(l).end(); + ++i) + { - command = "CREATE TABLE "; - command += GetTree().GetLevelDescriptor(l).GetName(); - command += "_Attributes\n(\n"; - command += "Key text,\n"; - command += "Name text,\n"; - command += "DicomGroup int,\n"; - command += "DicomElement int,\n"; - command += "Flags int\n"; - command += "\n)"; - UPDATEDB(command); - - - // Fill the table *_ATTRIBUTES - LevelDescriptor::AttributeDescriptorListType::const_iterator i; - for (i = GetTree().GetAttributeDescriptorList(l).begin(); - i != GetTree().GetAttributeDescriptorList(l).end(); - ++i) - { - - std::stringstream insert; - insert << "INSERT INTO " - << GetTree().GetLevelDescriptor(l).GetName() - << "_Attributes (Key,Name,DicomGroup,DicomElement,Flags) " - << "VALUES ('" - << i->GetKey() << "','" - << i->GetName() << "'," - << i->GetGroup() << "," - << i->GetElement() << "," - << i->GetFlags() << ");"; - - UPDATEDB(insert.str()); - } + std::stringstream insert; + insert << "INSERT INTO " + << GetTree().GetLevelDescriptor(l).GetName() + << "_Attributes (Key,Name,DicomGroup,DicomElement,Flags) " + << "VALUES ('" + << i->GetKey() << "','" + << i->GetName() << "'," + << i->GetGroup() << "," + << i->GetElement() << "," + << i->GetFlags() << ");"; + UPDATEDB(insert.str()); } - } - catch (std::exception) - { - return false; - } + } // 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 '"<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" + <GetAttributeMap().begin(); + i != n->GetAttributeMap().end(); + i++) + { + if (i->first=="ID") + { + continue; + } + atts += "'" + i->first + "'"; + values += "'" + SQLformat(i->second) + "'"; + atts += ","; + values += ","; + GimmickMessage(4,"'"<first<<"' = '"<second<<"'"<GetLevel()+1 >= node->GetTree()->GetNumberOfLevels() ) + return 0; + + GimmickMessage(2,"Loading children of '"<GetLabel() + <<"'"<GetChildrenLoaded()) return nbloaded; + // If children loaded we do not have to do it but we need to recurse + // in order to load the children's children if necessary, and so on... + if (node->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; + + } + else + { + /// If children not loaded : do it and recurse // Query DB - int level = parent->GetLevel(); + int level = node->GetLevel(); std::string query = "SELECT * FROM "; + query += GetTree().GetLevelDescriptor(level+1).GetName(); - if (level>1) + if (level>0) { - query += " WHERE PARENT_ID='" + parent->UnsafeGetAttribute("ID") + query += " WHERE PARENT_ID='" + node->GetAttribute("ID") + "'"; } CppSQLite3Query q; QUERYDB(query,q); + int p=0; while (!q.eof()) { + + // std::cout << "DBLoadCh : creating node level "<UnsafeSetAttribute(q.fieldName(fld),q.getStringField(fld)); } - /* - // Index - TypeId ti; - ti.type = type; - ti.id = n->GetFieldValue("ID"); - mTypeIdToNodeMap[ti] = n; - */ + // recurse - if ( numberoflevels > 1 ) + if ( numberoflevels != 1 ) { // msw[2].Pause(); nbloaded += DBLoadChildren(n, numberoflevels-1); @@ -639,490 +689,333 @@ namespace creaImageIO q.nextRow(); } - parent->SetChildrenLoaded(true); + node->SetChildrenLoaded(true); + // msw[2].Pause(); return nbloaded; + } + } + //===================================================================== - // std::cout << "SQLiteTreeHandler::DBLoadChildren("<ChildrenLoaded() ) - { - // std::cout << "--> Children already loaded"<GetType() == Node::Image ) - { - return nbloaded; - } - if ( xparent->GetType() >= maxlevel ) - { - return nbloaded; - } - - // msw[2].Pause(); - // msw[2].Resume(); - - Node::Type type = xparent->GetType()+1; - - // Query DB - - std::string query = "SELECT * FROM "; - query += GetTree().GetDescriptor().GetLevelDescriptor(level).GetName(); - //SQLiteTreeHandlerStructure::Table(type); - if (parent!=0) - { - query += " WHERE PARENT_ID='" + parent->GetFieldValue("ID") + "'"; - } + //====================================================================== + void SQLiteTreeHandler::DBInsert(tree::Node* n) + { + GimmickMessage(2,"Inserting in DB '"<GetLabel() + <<"'"<GetLevel()).GetName(); + insert += " " + val + ";"; - // std::cout << "** SQL = '"<lastRowId(); + std::stringstream ri; + ri << mDB->lastRowId(); + n->SetAttribute("ID",ri.str()); + } + //====================================================================== - CppSQLite3Query q; - QUERYDB(query,q); + //====================================================================== + /// 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++) { - nbloaded++; - Node* n = new Node(type, - this,xparent); - for (int fld = 0; fld < q.numFields(); fld++) - { - n->SetFieldValue(q.fieldName(fld),q.getStringField(fld)); - } - // Index - TypeId ti; - ti.type = type; - ti.id = n->GetFieldValue("ID"); - mTypeIdToNodeMap[ti] = n; - // recurse - if ( type < maxlevel ) + // Create Node + tree::Node* child = new tree::Node(parent,attr); + child->SetChildrenLoaded(true); + if (level>1) { - msw[2].Pause(); - nbloaded += DBLoadChildren(n,maxlevel); - msw[2].Resume(); + int nc = GetNumberOfChildren(parent)+1; + + // std::cout<<"Number of children "<GetNumberOfChildren()<SetChildrenLoaded(true); - - // msw[2].Pause(); - return nbloaded; - */ + // Set PARENT_ID if necessary + if ( parent->GetLevel()>0 ) + child->SetAttribute("PARENT_ID",parent->GetAttribute("ID")); + + // Insert in DB + DBInsert(child); + + // Down one level + parent = child; + } } - //===================================================================== - - + //====================================================================== - - /* - //===================================================================== - bool SQLiteTreeHandler::DBInsert(Node* alien_node, - UpdateSummary& summary) + //===================================================================== + /// Sets an attribute of a Node + bool SQLiteTreeHandler::DBSetAttribute(tree::Node* n, + const std::string& key, + const std::string& value) { - // std::cout << "SQLiteTreeHandler::Insert('"<GetLabel() - // <<"')"<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; } - //===================================================================== - - //===================================================================== - Node* SQLiteTreeHandler::DBGetOrCreateParent(Node* alien_node, - std::string& parent_id, - UpdateSummary& summary) + //===================================================================== + /// 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::cout << "DBGetOrCreateParent '" << alien_node->GetLabel()<<"'" - // << std::endl; - // Load the patients if not already done - DBLoadChildren(this,Node::Patient); - - parent_id = ""; - Node* parent = this; - - // The chain of ancestors - std::deque chain; - Node* cur = alien_node->GetParent(); - for (int type=Node::Patient; - typeGetType();++type) - { - chain.push_front(cur); - cur = cur->GetParent(); - } - // create the nodes if do not exist - std::deque::iterator i; - for (i=chain.begin();i!=chain.end();++i) - { - // std::cout << " cur = '"<<(*i)->GetLabel()<<"'"<GetType()+1); - - parent_id = cur_id; - } - return parent; + std::string sql = "UPDATE "; + sql += levelDescriptor; + sql += " SET "; + sql += key; + sql += " = '"; + sql += value; + sql += "' WHERE "; + sql += searchParam; + sql += " = '"; + sql += searchVal; + sql += "'"; + std::cout<GetLabel() - // <<"','"<GetChildrenList().begin(); - i != alien_node->GetChildrenList().end(); - i++) - { - DBRecursiveGetOrCreateNode((*i),new_node,new_id,summary); - } - } - //===================================================================== - - - //===================================================================== - Node* SQLiteTreeHandler::DBGetOrCreateNode(Node* alien_node, - Node* internal_parent, - std::string parent_id, - std::string& node_id, - UpdateSummary& summary) + //===================================================================== + void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node) { - // std::cout << "DBGetOrCreateNode('"<GetLabel()<<"','" - // << internal_parent << "','"<< parent_id<<"')"<0) - { - node_id = node->UnsafeGetFieldValue("ID"); - return node; - } - // Second : try in DB + + std::string query = "DELETE FROM "; - // Does not exist : Create new one - node = new Node(alien_node->GetType(),this,internal_parent); - node->SetChildrenLoaded(true); - // Copy fields values from alien - Node::FieldValueMapType::iterator i,j; - for (i = node->GetFieldValueMap().begin(); - i != node->GetFieldValueMap().end(); - i++) - { - j = alien_node->GetFieldValueMap().find(i->first); - if (j != alien_node->GetFieldValueMap().end() ) - { - i->second = j->second; - } - } - - msw[2].Resume(); - if (node->GetType()!=Node::Patient) - node->SetFieldValue("PARENT_ID",parent_id); - - // Insert in DB - std::string val; - BuildSQLFieldsValues(node,val); - std::string insert("INSERT INTO "); - insert += std::string(SQLiteTreeHandlerStructure::Table(node->GetType())) - + " " + val + ";"; - // std::cout << "** SQL = '"<lastRowId(); - std::stringstream ri; - ri << mDB->lastRowId(); - node_id = ri.str(); - // std::cout << "LastRowId='"<lastRowId()<<"' vs '"<SetFieldValue("ID",node_id); - // 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++; - - return node; + query += GetTree().GetLevelDescriptor(node->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")); + } } - //===================================================================== //===================================================================== - Node* SQLiteTreeHandler::GetChildrenLike(Node* parent, - Node* alien_node) + void SQLiteTreeHandler::DBRecursiveRemoveNode(int level, std::string parentId) { - Node::ChildrenListType::iterator i; - for (i = parent->GetChildrenList().begin(); - i != parent->GetChildrenList().end(); - i++) - { - Node::Type type = alien_node->GetType(); - bool ok = true; - for (int j=0; - jGetFieldValue(SQLiteTreeHandlerStructure:: - QueryField(type,j).key ) != - (*i)->GetFieldValue(SQLiteTreeHandlerStructure:: - QueryField(type,j).key ) ) + for (int fld = 0; fld < q.numFields(); fld++) { - ok = false; - break; + result<GetLabel() - // <<"','"<GetType(); - - std::string table = SQLiteTreeHandlerStructure::Table(type); - std::string where = "WHERE "; - - if (type!=Node::Patient) - { - where += "PARENT_ID='" + parent_id - //node->GetFieldValue("PARENT_ID") - + "' AND "; - } - - for (int i=0;iGetParent()) - { - node->GetParent()->RemoveChildrenFromList(node); - } - delete node; - // std::cout << "DELETE OK"<GetLabel()<<"')"<GetType()); - query += " WHERE ID='"+ node->GetFieldValue("ID") + "';"; - - UPDATEDB(query); - Node::ChildrenListType::iterator i; - for (i = node->GetChildrenList().begin(); - i != node->GetChildrenList().end(); - i++) - { - DBRecursiveRemoveNode((*i)); - } + //===================================================================== + void SQLiteTreeHandler::GetAttribute(std::string levelDescriptor, + std::string searchParam, + std::string searchVal, + std::string key, + std::string& result) + { + std::stringstream out; + std::stringstream results; + out<<"SELECT "<GetType()+1); - if (node->GetType() != Node::Database) - { - query += " WHERE PARENT_ID='"+ node->GetFieldValue("ID")+"'"; - } - query += ";"; - - // std::cout << "**SQL = "<< query << std::endl; - - CppSQLite3Query q; - QUERYDB(query,q); - - // std::cout << "**RES = "<< q.getIntField(0) <GetLevel(); - return q.getIntField(0); - } - //===================================================================== - - //======================================================================== - std::string& format_sql2(std::string& str) - { - // quote must be doubled - // crea::Utils::Replace( str, "'", "''" ); - boost::algorithm::replace_all(str,"'","''"); - // Found strange strings which contained NULL char INSIDE string - int i,size=str.size(); - for (i=0;i0) { - if (str[i]==0) + std::string query = "SELECT NumberOfChildren FROM "; + query += GetTree().GetLevelDescriptor(level).GetName(); + if (level>0) { - str = str.substr(0,i); - break; + query += " WHERE ID='" + n->GetAttribute("ID") + + "'"; + } + CppSQLite3Query q; + QUERYDB(query,q); + + + while (!q.eof()) + { + for (int fld = 0; fld < q.numFields(); fld++) + { + nb=q.getIntField(fld); + } + q.nextRow(); } } - // if (iGetLabel()<<"')"<GetFieldValueMap().begin(); - i != n->GetFieldValueMap().end(); - i++) - { - if (i->first=="ID") + while(level>1) { - continue; + std::stringstream out; + std::stringstream results; + out<<"SELECT PARENT_ID FROM "<first<<","<second<<")"<first + "'"; - values += "'" + format_sql2(i->second) + "'"; - atts += ","; - values += ","; - } - atts[atts.size()-1]=' '; - values[values.size()-1]=' '; - - str = "("+atts+") VALUES ("+values+")"; + parent_id=sv; } - //===================================================================== -*/ - + //===================================================================== + void SQLiteTreeHandler::RemoveEntries(const std::string i_table, + const std::string i_attribute, + const std::string i_operand, + const std::string i_val) + { + std::stringstream query; + query<<"DELETE FROM "<