From bae4df8a3e1ea669400c3a6c44ef4aa8d90fa1ed Mon Sep 17 00:00:00 2001 From: guigues Date: Wed, 11 Feb 2009 07:32:16 +0000 Subject: [PATCH] *** empty log message *** --- appli/gimmick/main.cxx | 9 + src2/creaImageIOSQLiteTreeHandler.cpp | 571 ++++++++++++++-------- src2/creaImageIOSQLiteTreeHandler.h | 38 +- src2/creaImageIOTree.h | 2 + src2/creaImageIOTreeAttributeDescriptor.h | 13 +- src2/creaImageIOTreeDescriptor.cpp | 2 +- src2/creaImageIOTreeHandler.h | 6 +- src2/creaImageIOTreeNode.cpp | 39 +- src2/creaImageIOTreeNode.h | 10 +- src2/doxygen/CMakeLists.txt | 2 +- 10 files changed, 462 insertions(+), 230 deletions(-) diff --git a/appli/gimmick/main.cxx b/appli/gimmick/main.cxx index 7f21a16..d90f0b8 100644 --- a/appli/gimmick/main.cxx +++ b/appli/gimmick/main.cxx @@ -1,8 +1,17 @@ #include +#include int main(int argc, char* argv[]) { + bool debug = false; + if(argc>1) + { + debug = true; + } + creaImageIO::Gimmick g; + g.SetDebugMode(debug); + if (!g.Initialize()) return 1; if (!g.Finalize()) return 1; return 0; diff --git a/src2/creaImageIOSQLiteTreeHandler.cpp b/src2/creaImageIOSQLiteTreeHandler.cpp index 4d0d49e..e1a0307 100644 --- a/src2/creaImageIOSQLiteTreeHandler.cpp +++ b/src2/creaImageIOSQLiteTreeHandler.cpp @@ -50,22 +50,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 +75,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 ) { + 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; } //===================================================================== @@ -218,10 +200,76 @@ namespace creaImageIO + + + + + + + + + //===================================================================== + // SQLite DB specific methods + //===================================================================== + + + + + //===================================================================== + 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 '"<0, i.e. not Root) + if (l>0) + { + 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", + 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 + )); + } + + } + + // Create table *_ATTRIBUTES + 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 += "_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()); + } } - - // Create tables *_ATTRIBUTES - // and 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()); - } - } - - } - //===================================================================== //===================================================================== - void SQLiteTreeHandler::DBImportTreeDescription() + bool SQLiteTreeHandler::DBImportTreeDescription() { - GimmickMessage(3,"ImportTreeDescription"<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 '"<GetChildrenList().begin(); + i!= parent->GetChildrenList().end(); + ++i) + { + if ( (*i)->Matches( attr ) ) + { + go_down = true; + parent = *i; + } + } + } + while (go_down); + return parent; + } + //===================================================================== - // TO DO : TABLE WHICH STORES THE LEVELS - /* - - for (int i = SQLiteTreeHandlerStructure::TableBegin(); - i != SQLiteTreeHandlerStructure::TableEnd();++i) + + //===================================================================== + int SQLiteTreeHandler::DBLoadChildren(tree::Node* parent, + int numberoflevels) + { + int nbloaded = 0; + if (parent->GetChildrenLoaded()) return nbloaded; + + // Query DB + int level = parent->GetLevel(); + std::string query = "SELECT * FROM "; + query += GetTree().GetLevelDescriptor(level+1).GetName(); + if (level>1) { - bool ok = mDB->tableExists(SQLiteTreeHandlerStructure::Table(i)); - if (ok) + query += " WHERE PARENT_ID='" + parent->UnsafeGetAttribute("ID") + + "'"; + } + CppSQLite3Query q; + QUERYDB(query,q); + + while (!q.eof()) + { + nbloaded++; + Node* n = new Node(parent); + for (int fld = 0; fld < q.numFields(); fld++) { - // std::cout << "** Table "<UnsafeSetAttribute(q.fieldName(fld),q.getStringField(fld)); } - else + /* + // Index + TypeId ti; + ti.type = type; + ti.id = n->GetFieldValue("ID"); + mTypeIdToNodeMap[ti] = n; + */ + // recurse + if ( numberoflevels > 1 ) { - // std::cout << "** Table "<SetChildrenLoaded(true); + + // msw[2].Pause(); + return nbloaded; // std::cout << "SQLiteTreeHandler::DBLoadChildren("<& attr ); + virtual int AddBranch( const AttributeMapType& attr ); /// Removes the node and its descendants virtual bool Remove(tree::Node*); - ///==================================================================== - - + //==================================================================== + + protected: - // Open + //====================================================================== + /// Open the database bool DBOpen(); - void DBImportTreeDescription(); - + /// Import the Tree::Description from database (verifies the structure) + bool DBImportTreeDescription(); + //====================================================================== + //====================================================================== // Creation /// Creates a new database on disk and the tables bool DBCreate(); - /// Creates the default tree description for a new database - void BuildDefaultTreeDescription(); /// Appends to string s the SQL command to create the attributes of a given level void AppendAttributesSQLDefinition(int level, std::string& s); - void DBExportTreeDescription(); - // + //====================================================================== - // Test - bool DBStructureIsValid(); + //====================================================================== + tree::Node* DBGetParent( const AttributeMapType& attr); + //====================================================================== + //====================================================================== + int DBLoadChildren( tree::Node* parent, int numberoflevels = 1); + //====================================================================== + + /* + /// int DBQueryNumberOfChildren(tree::Node* n); // Insertion @@ -154,7 +160,7 @@ namespace creaImageIO tree::Node* GetChildrenLike(tree::Node* internal_parent, tree::Node* alien_node); - + */ private: /// The DB CppSQLite3DB* mDB; @@ -165,6 +171,7 @@ namespace creaImageIO void SetWritable(bool w) { mWritable; } bool GetWritable() const { return mWritable; } + /* struct TypeId { int type; @@ -178,6 +185,7 @@ namespace creaImageIO typedef std::map TypeIdToNodeMapType; TypeIdToNodeMapType mTypeIdToNodeMap; + */ }; // EO class SQLiteTreeHandler //======================================================================= diff --git a/src2/creaImageIOTree.h b/src2/creaImageIOTree.h index 854693d..3a4ba05 100644 --- a/src2/creaImageIOTree.h +++ b/src2/creaImageIOTree.h @@ -20,6 +20,8 @@ namespace creaImageIO //===================================================================== /// An attributed tree structure + /** + */ class Tree : public Node { public: diff --git a/src2/creaImageIOTreeAttributeDescriptor.h b/src2/creaImageIOTreeAttributeDescriptor.h index dc734bd..1a68bfa 100644 --- a/src2/creaImageIOTreeAttributeDescriptor.h +++ b/src2/creaImageIOTreeAttributeDescriptor.h @@ -16,7 +16,7 @@ namespace creaImageIO public: /// Flags /// The attribute is hidden (not visible to user) - static const unsigned int HIDDEN; + static const unsigned int PRIVATE; /// The attribute enters in unique identifier constitution (KEY) static const unsigned int KEY; /// The attribute enters in label constitution (for printing) @@ -27,6 +27,17 @@ namespace creaImageIO : mKey(""), mName(""), mGroup(0), mElement(0), mFlags(0) { } + /// Ctor with all explicitely + AttributeDescriptor(const std::string& key, + const std::string& name, + unsigned short group, + unsigned short element, + unsigned int flags) + : mKey(key), mName(name), mGroup(group), mElement(element), + mFlags(flags) + { + } + // Ctor with key, name and flags AttributeDescriptor(const std::string& key, const std::string& name, diff --git a/src2/creaImageIOTreeDescriptor.cpp b/src2/creaImageIOTreeDescriptor.cpp index 6c253ba..c9a4e00 100644 --- a/src2/creaImageIOTreeDescriptor.cpp +++ b/src2/creaImageIOTreeDescriptor.cpp @@ -9,7 +9,7 @@ namespace creaImageIO //================================================================== /// The attribute is hidden (not visible to user) - const unsigned int AttributeDescriptor::HIDDEN = 1; + const unsigned int AttributeDescriptor::PRIVATE = 1; /// The attribute enters in unique identifier constitution (KEY) const unsigned int AttributeDescriptor::KEY = 2; const unsigned int AttributeDescriptor::LABEL = 4; diff --git a/src2/creaImageIOTreeHandler.h b/src2/creaImageIOTreeHandler.h index c88bbc9..368c519 100644 --- a/src2/creaImageIOTreeHandler.h +++ b/src2/creaImageIOTreeHandler.h @@ -87,12 +87,12 @@ namespace creaImageIO ///==================================================================== /// WRITE METHODS : WORK ONLY IN WRITE MODE ///==================================================================== - /// Adds a branch in the tree with the attributes provided + typedef tree::Node::AttributeMapType AttributeMapType; + /// Adds a branch in the tree with the attributes provided /// returns the Level in the tree where the branch was connected /// (-1 for error, 0 for top level, etc. ) /// Of course the branch is loaded on exit - virtual int AddBranch - ( const std::map& attr ) { return -1; } + virtual int AddBranch( const AttributeMapType& ) { return -1; } /// Removes the node and its descendants bool Remove(tree::Node*) { return false; } ///==================================================================== diff --git a/src2/creaImageIOTreeNode.cpp b/src2/creaImageIOTreeNode.cpp index 8f03924..6bb7d3a 100644 --- a/src2/creaImageIOTreeNode.cpp +++ b/src2/creaImageIOTreeNode.cpp @@ -25,12 +25,35 @@ namespace creaImageIO a!= GetTree()->GetAttributeDescriptorList(GetLevel()).end(); ++a) { - UnsafeSetAttribute( a->GetName(), "" ); + UnsafeSetAttribute( a->GetKey(), "" ); } } } //============================================================= + //============================================================= + /// Ctor with parent and attributes map + Node::Node(Node* parent, const AttributeMapType& attr) + : mParent(parent), + mData(0), + mChildrenLoaded(false) + { + if (parent) + { + // Insert into parent's children list + parent->GetChildrenList().push_back(this); + // Initialize attributes + LevelDescriptor::AttributeDescriptorListType::const_iterator a; + for (a = GetTree()->GetAttributeDescriptorList(GetLevel()).begin(); + a!= GetTree()->GetAttributeDescriptorList(GetLevel()).end(); + ++a) + { + UnsafeSetAttribute( a->GetKey(), attr[a->GetKey()] ); + } + } + + } + //============================================================= //============================================================= @@ -85,16 +108,22 @@ namespace creaImageIO AttributeMapType::iterator i = mAttributeMap.find(k); if (i==mAttributeMap.end()) { - std::cout<<"[Gimmick!] Node::SetAttribute : no attribute with name '" + std::cout<<"[Gimmick!] Node::SetAttribute : no attribute with key '" <second = v; } - //============================================================= - + //============================================================= + //============================================================= + bool Node::Matches( const AttributeMapType& ) const + { + // TO DO + return false; + } + //============================================================= } } diff --git a/src2/creaImageIOTreeNode.h b/src2/creaImageIOTreeNode.h index 07b46cf..a97925e 100644 --- a/src2/creaImageIOTreeNode.h +++ b/src2/creaImageIOTreeNode.h @@ -31,8 +31,13 @@ namespace creaImageIO class Node { public: + typedef std::map AttributeMapType; + + /// Ctor with parent Node(Node* parent); + /// Ctor with parent and attributes map + Node(Node* parent, const AttributeMapType& ); /// Virtual destructor virtual ~Node(); @@ -73,7 +78,6 @@ namespace creaImageIO /// Remove the given children from the children list void RemoveChildrenFromList(Node*); - typedef std::map AttributeMapType; AttributeMapType& GetAttributeMap() { return mAttributeMap; } const AttributeMapType& GetAttributeMap() const { return mAttributeMap; } @@ -90,7 +94,9 @@ namespace creaImageIO // { return GetTypeDescription().GetFieldDescription(k); } - + /// Returns true iff the KEY attributes of the node match those of the map provided + bool Matches( const AttributeMapType& ) const; + /// Returns the node data casted into the type T template T GetData() const { if (mData!=0) return dynamic_cast(mData); return 0; } diff --git a/src2/doxygen/CMakeLists.txt b/src2/doxygen/CMakeLists.txt index 6d19d78..e216352 100644 --- a/src2/doxygen/CMakeLists.txt +++ b/src2/doxygen/CMakeLists.txt @@ -85,7 +85,7 @@ CONFIGURE_FILE( SET(INPUT ${CMAKE_CURRENT_BINARY_DIR}/DoxyMainPage.txt - ${PROJECT_SOURCE_DIR}/src + ${PROJECT_SOURCE_DIR}/src2 # ${PROJECT_SOURCE_DIR}/appli ) -- 2.45.1