X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src2%2FcreaImageIOSQLiteTreeHandler.cpp;h=847160617de0cd275683427a047d9afcd8389a00;hb=44cea5b742db372c4dafcc3f5d0c1ca0d341779a;hp=e1a0307b3673093365844786789de7e0d589ac02;hpb=bae4df8a3e1ea669400c3a6c44ef4aa8d90fa1ed;p=creaImageIO.git diff --git a/src2/creaImageIOSQLiteTreeHandler.cpp b/src2/creaImageIOSQLiteTreeHandler.cpp index e1a0307..8471606 100644 --- a/src2/creaImageIOSQLiteTreeHandler.cpp +++ b/src2/creaImageIOSQLiteTreeHandler.cpp @@ -21,7 +21,6 @@ //#include #include -#include using namespace crea; #include @@ -37,6 +36,7 @@ namespace creaImageIO : mFileName(filename) { mDB = new CppSQLite3DB; + mIsAdding=false; GimmickMessage(1,"SQLite version : " <SQLiteVersion())<< std::endl); } @@ -107,19 +107,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 +127,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()); + 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" <GetAttributeMap().begin(); + i != n->GetAttributeMap().end(); + i++) + { + if (i->first=="ID") + { + continue; + } + // std::cout << "("<first<<","<second<<")"<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->UnsafeGetAttribute("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)); @@ -629,7 +741,7 @@ namespace creaImageIO mTypeIdToNodeMap[ti] = n; */ // recurse - if ( numberoflevels > 1 ) + if ( numberoflevels != 1 ) { // msw[2].Pause(); nbloaded += DBLoadChildren(n, numberoflevels-1); @@ -639,88 +751,362 @@ 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(); + //====================================================================== + void SQLiteTreeHandler::DBInsert(tree::Node* n) + { + GimmickMessage(2,"Inserting in DB '"<GetLabel() + <<"'"<GetLevel()).GetName(); + insert += " " + val + ";"; - Node::Type type = xparent->GetType()+1; + UPDATEDB(insert); + + // Store DB id of newly created node; + long lastrow = mDB->lastRowId(); + std::stringstream ri; + ri << mDB->lastRowId(); + n->SetAttribute("ID",ri.str()); + } + //====================================================================== - // Query DB + //====================================================================== + /// 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++) { - query += " WHERE PARENT_ID='" + parent->GetFieldValue("ID") + "'"; + // 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++; + */ } + } + //====================================================================== - // std::cout << "** SQL = '"<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); + } - while (!q.eof()) + //===================================================================== + /// 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) { - nbloaded++; - Node* n = new Node(type, - this,xparent); - for (int fld = 0; fld < q.numFields(); fld++) + std::string query = "SELECT NumberOfChildren FROM "; + query += GetTree().GetLevelDescriptor(level).GetName(); + if (level>0) { - n->SetFieldValue(q.fieldName(fld),q.getStringField(fld)); + query += " WHERE ID='" + n->UnsafeGetAttribute("ID") + + "'"; } - // Index - TypeId ti; - ti.type = type; - ti.id = n->GetFieldValue("ID"); - mTypeIdToNodeMap[ti] = n; - // recurse - if ( type < maxlevel ) + CppSQLite3Query q; + QUERYDB(query,q); + + + while (!q.eof()) { - msw[2].Pause(); - nbloaded += DBLoadChildren(n,maxlevel); - msw[2].Resume(); + for (int fld = 0; fld < q.numFields(); fld++) + { + nb=q.getIntField(fld); + } + q.nextRow(); } - // next entry in db - q.nextRow(); } - - xparent->SetChildrenLoaded(true); - - // msw[2].Pause(); - return nbloaded; + /* + 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()) @@ -1024,6 +1412,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+")"; + - } - //===================================================================== */