X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src2%2FcreaImageIOSQLiteTreeHandler.cpp;h=4363e7c0a99de19d39fc44b4e0570f0598a9496d;hb=8d73d5f58d80abb928a7f60037837c2933b16bbd;hp=509aa90429e4c1f3e9e4447bc7f5f522a88f9e2d;hpb=cbf693fa62cd51f4ca5c881838bbb609edc447b0;p=creaImageIO.git diff --git a/src2/creaImageIOSQLiteTreeHandler.cpp b/src2/creaImageIOSQLiteTreeHandler.cpp index 509aa90..4363e7c 100644 --- a/src2/creaImageIOSQLiteTreeHandler.cpp +++ b/src2/creaImageIOSQLiteTreeHandler.cpp @@ -1,4 +1,5 @@ #include +#include #include "CppSQLite3.h" @@ -20,7 +21,6 @@ //#include #include -#include using namespace crea; #include @@ -35,28 +35,9 @@ namespace creaImageIO SQLiteTreeHandler::SQLiteTreeHandler(const std::string& filename) : mFileName(filename) { - /* - mSQLiteTreeHandler = this; - NodeTypeDescription::FieldDescriptionMapType& M = - mNodeTypeDescription[Node::Database].GetFieldDescriptionMap(); - - boost::filesystem::path full_path(location); - mName = full_path.leaf(); - Field::Description fname("Name",0,0,"Name",0); - M[fname.key] = fname; - UnsafeSetFieldValue(fname.key,mName); - Field::Description flocation("File name",0,0,"File name",0); - M[flocation.key] = flocation; - UnsafeSetFieldValue(flocation.key,location); - */ - // Field::Description ftype("Type",0,0,"Type",0); - // M[ftype.key] = ftype; - // UnsafeSetFieldValue(ftype.key,"Invalid location"); - mDB = new CppSQLite3DB; - // std::cout << "** SQLite Version: " << mDB->SQLiteVersion() << std::endl; - - + GimmickMessage(1,"SQLite version : " + <SQLiteVersion())<< std::endl); } //============================================================= @@ -64,34 +45,10 @@ namespace creaImageIO SQLiteTreeHandler::~SQLiteTreeHandler() { delete mDB; - /* - Already done in Node now that SQLiteTreeHandler inherits from it - ChildrenListType::iterator i; - for (i=GetChildrenList().begin(); i!=GetChildrenList().end(); i++) - { - delete *i; - } - */ } //============================================================= - //============================================================= - 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 // { @@ -117,48 +74,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 \ - { \ - RES = mDB->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()) + { + node->GetParent()->RemoveChildrenFromList(node); + } + delete node; + // 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 = "create table "; + command = "CREATE TABLE "; command += GetTree().GetLevelDescriptor(l).GetName(); - command += "_ATTRIBUTES\n(\n"; - command += "Key text,\n"; - command += "Group int,\n"; - command += "Element int,\n"; - command += "Name text,\n"; - command += "Flags int\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); + } + } - // Fill the tables *_ATTRIBUTES - DBExportTreeDescription(); - } - catch (std::exception) - { - return false; - } - // LG : TEST - if (DBStructureIsValid()) - { - // std::cout << "*** DONE ***"<GetKey() << "','" + << i->GetName() << "'," + << 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 '"< keys; - NodeTypeDescription::FieldDescriptionMapType::iterator i; - for (i = GetNodeTypeDescription(c).GetFieldDescriptionMap().begin(); - i != GetNodeTypeDescription(c).GetFieldDescriptionMap().end(); + LevelDescriptor::AttributeDescriptorListType::const_iterator i; + for (i = GetTree().GetAttributeDescriptorList(level).begin(); + i != GetTree().GetAttributeDescriptorList(level).end(); ++i) { - if (i->second.flags==1) continue; - keys.push_back(&(i->second.key)); + // if (i->second.flags==1) continue; + s += ",\n"; + s += i->GetKey(); + s += " text"; } - std::vector::iterator j; - for (j=keys.begin();j!=keys.end();) - { - s += **j + " text"; - ++j; - if (j!=keys.end()) - s += ",\n"; - } - */ } //===================================================================== - //===================================================================== - void SQLiteTreeHandler::DBExportTreeDescription() - { - /* - // std::cout<<"ExportNodeTypeDescriptionsToDB()"<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); + }*/ return nbloaded; - } - - // msw[2].Pause(); - // msw[2].Resume(); - Node::Type type = xparent->GetType()+1; + } + + /// 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) + { + GimmickMessage(2,"Grafting to parent '"<GetLabel() + <<"'"<GetLevel()+1; + level < GetTree().GetNumberOfLevels(); + level++) + { + // Create Node + tree::Node* child = new tree::Node(parent,attr); + + // Set PARENT_ID if necessary + if ( parent->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 += " LIMIT 1"; + UPDATEDB(sql); + } + //===================================================================== + //===================================================================== + void SQLiteTreeHandler::DBRecursiveRemoveNode(Node* node) + { + + std::string query = "DELETE FROM "; + + 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() + <GetChildrenList().begin(); + i != node->GetChildrenList().end(); + i++) + { + DBRecursiveRemoveNode((*i)); + } + } + + //===================================================================== + unsigned int SQLiteTreeHandler::GetNumberOfChildren(tree::Node* n) + { + // Query DB + int nb=0; + int level = n->GetLevel(); + if(GetTree().GetNumberOfLevels()!=(level+1)) + { + std::string query = "SELECT * FROM "; + query += GetTree().GetLevelDescriptor(level+1).GetName(); + if (level>0) + { + query += " WHERE PARENT_ID='" + n->UnsafeGetAttribute("ID") + + "'"; + } + + CppSQLite3Query q; + QUERYDB(query,q); + + + while (!q.eof()) + { + nb++; + q.nextRow(); + } + } + return nb; + } + + /* //===================================================================== bool SQLiteTreeHandler::DBInsert(Node* alien_node, UpdateSummary& summary) @@ -859,12 +1165,14 @@ namespace creaImageIO // std::cout << " ** Node = "<second<second; } + //===================================================================== //===================================================================== bool SQLiteTreeHandler::Remove(Node* node) { - DBRecursiveRemoveNode(node); + + //DBRecursiveRemoveNode(node); // std::cout << "DELETE"<GetParent()) @@ -875,6 +1183,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+")"; + - } - //===================================================================== */