#include #include #include "CppSQLite3.h" #include //#include //#include //#include #include #include "wx/wx.h" #include #include //#include #include #include using namespace crea; #include #include namespace creaImageIO { using namespace tree; //============================================================= SQLiteTreeHandler::SQLiteTreeHandler(const std::string& filename) : mFileName(filename) { mDB = new CppSQLite3DB; GimmickMessage(1,"SQLite version : " <SQLiteVersion())<< std::endl); } //============================================================= //============================================================= SQLiteTreeHandler::~SQLiteTreeHandler() { delete mDB; } //============================================================= //============================================================= 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 // { /* std::cout << "-> '"<Print(); } */ // } //============================================================= //===================================================================== /* bool SQLiteTreeHandler::LocationIsValid() { // TO DO return true; } */ //===================================================================== //===================================================================== 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 '"< SQLiteTreeHandler::Open('"< SQLiteTreeHandler::New('"<& attr ) { return -1; } //===================================================================== //===================================================================== bool SQLiteTreeHandler::Remove(tree::Node*) { return false; } //===================================================================== //===================================================================== bool SQLiteTreeHandler::DBOpen() { GimmickMessage(2,"Opening SQLite database '"<open(GetFileName().c_str()); } catch (CppSQLite3Exception& e) { std::cerr << "Opening '"<open(GetFileName().c_str()); } catch (CppSQLite3Exception& e) { creaMessage("Gimmick!",1, "[Gimmick!] !! ERROR '" << e.errorCode() << ":" << e.errorMessage() <second.flags==1) continue; s += ",\n"; s += i->GetKey(); s += " text"; } } //===================================================================== //===================================================================== void SQLiteTreeHandler::DBExportTreeDescription() { for (int level=0; levelGetKey() << "','" << i->GetName() << "'," << i->GetGroup() << "," << i->GetElement() << "," << i->GetFlags() << ");"; UPDATEDB(insert.str()); } } } //===================================================================== //===================================================================== void SQLiteTreeHandler::DBImportTreeDescription() { GimmickMessage(3,"ImportTreeDescription"<tableExists(SQLiteTreeHandlerStructure::Table(i)); if (ok) { // std::cout << "** Table "<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") + "'"; } // std::cout << "** SQL = '"<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 ) { msw[2].Pause(); nbloaded += DBLoadChildren(n,maxlevel); msw[2].Resume(); } // next entry in db q.nextRow(); } xparent->SetChildrenLoaded(true); // msw[2].Pause(); return nbloaded; } //===================================================================== //===================================================================== bool SQLiteTreeHandler::DBInsert(Node* alien_node, UpdateSummary& summary) { // std::cout << "SQLiteTreeHandler::Insert('"<GetLabel() // <<"')"<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; } //===================================================================== //===================================================================== void SQLiteTreeHandler::DBRecursiveGetOrCreateNode(Node* alien_node, Node* parent, const std::string& parent_id, UpdateSummary& summary) { // std::cout << "SQLiteTreeHandler::RecursiveGetOrCreateNode('" // <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) { // std::cout << "DBGetOrCreateNode('"<GetLabel()<<"','" // << internal_parent << "','"<< parent_id<<"')"<0) { node_id = node->UnsafeGetFieldValue("ID"); return node; } // Second : try in DB // 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; } //===================================================================== //===================================================================== Node* SQLiteTreeHandler::GetChildrenLike(Node* parent, Node* alien_node) { 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 ) ) { ok = false; break; } } if (ok) { return (*i); } } return 0; } //===================================================================== //===================================================================== std::string SQLiteTreeHandler::DBGetNodeId(Node* node, const std::string& parent_id) { // std::cout << "SQLiteTreeHandler::DBGetNodeId('"<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)); } } //===================================================================== //===================================================================== int SQLiteTreeHandler::DBQueryNumberOfChildren(Node* node) { std::string query = "SELECT COUNT (ID) FROM "; query += SQLiteTreeHandlerStructure::Table(node->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) <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+")"; } //===================================================================== */ } // namespace creaImageIO