diff --git a/include/RequestManagerSystem.h b/include/RequestManagerSystem.h index 697221acac..08f55a4c38 100644 --- a/include/RequestManagerSystem.h +++ b/include/RequestManagerSystem.h @@ -97,6 +97,47 @@ public: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +class SystemSqlQuery: public RequestManagerSystem +{ +public: + SystemSqlQuery():RequestManagerSystem("one.system.sqlquery", + "Executes SQL queries on the DB backend","A:ss") + { + auth_op = AuthRequest::ADMIN; + }; + + ~SystemSqlQuery(){}; + + void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributes& att); +private: + + class select_cb : public Callbackable + { + public: + void set_callback() + { + oss.str(""); + + Callbackable::set_callback( + static_cast(&select_cb::callback)); + } + + std::string get_result() + { + return oss.str(); + } + + virtual int callback(void *nil, int num, char **values, char **names); + + private: + std::ostringstream oss; + }; +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + class UserQuotaInfo : public RequestManagerSystem { public: diff --git a/src/oca/ruby/opennebula/system.rb b/src/oca/ruby/opennebula/system.rb index 7a5c9ac104..45e77d05d0 100644 --- a/src/oca/ruby/opennebula/system.rb +++ b/src/oca/ruby/opennebula/system.rb @@ -30,7 +30,8 @@ module OpenNebula :groupquotaupdate => "groupquota.update", :version => "system.version", :config => "system.config", - :sql => "system.sql" + :sql => "system.sql", + :sqlquery => "system.sqlquery" } ####################################################################### @@ -57,6 +58,22 @@ module OpenNebula return @client.call(SYSTEM_METHODS[:sql], sql, federate) end + # Executes a SQL query command on OpenNebula DB + # @param [String] Sql string + # @return [String, OpenNebula::Error] Sql execution result in XML + # format in case of success, Error otherwise + # + # the query sent to oned + # + # + # + # column_value + # ... + # + # + def sql_query_command(sql) + return @client.call(SYSTEM_METHODS[:sqlquery], sql) + end # # Gets the oned version # diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 202e84352e..da6cdab644 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -447,6 +447,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr system_version(new SystemVersion()); xmlrpc_c::methodPtr system_config(new SystemConfig()); xmlrpc_c::methodPtr system_sql(new SystemSql()); + xmlrpc_c::methodPtr system_sqlquery(new SystemSqlQuery()); // Rename Methods xmlrpc_c::methodPtr vm_rename(new VirtualMachineRename()); @@ -1065,6 +1066,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.system.version", system_version); RequestManagerRegistry.addMethod("one.system.config", system_config); RequestManagerRegistry.addMethod("one.system.sql", system_sql); + RequestManagerRegistry.addMethod("one.system.sqlquery", system_sqlquery); }; /* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerSystem.cc b/src/rm/RequestManagerSystem.cc index 87bb51e5f0..7a958c78ae 100644 --- a/src/rm/RequestManagerSystem.cc +++ b/src/rm/RequestManagerSystem.cc @@ -114,6 +114,93 @@ void SystemSql::request_execute(xmlrpc_c::paramList const& paramList, /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +int SystemSqlQuery::select_cb::callback(void *nil, int num, char **values, + char **names) +{ + oss << ""; + + for ( int i = 0 ; i < num ; ++i ) + { + if (values[i] != 0 && values[i][0] == '<') + { + std::string val(values[i]); + std::string * val64 = one_util::base64_encode(val); + + if ( val64 != 0 ) + { + oss << "<" << names[i] << "64>" + << "" + << ""; + + delete val64; + } + } + else + { + oss << "<" << names[i] << ">" + << "" + << ""; + } + } + + oss << ""; + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +void SystemSqlQuery::request_execute(xmlrpc_c::paramList const& paramList, + RequestAttributes& att) +{ + std::string sql = xmlrpc_c::value_string(paramList.getString(1)); + + Nebula& nd = Nebula::instance(); + LogDB * logdb = nd.get_logdb(); + + SystemSqlQuery::select_cb cb; + + std::ostringstream oss(sql); + + std::string result; + + if ( att.uid != 0 ) + { + att.resp_id = -1; + + failure_response(AUTHORIZATION, att); + return; + } + + + cb.set_callback(); + + int rc = logdb->exec_rd(oss, &cb); + + result = cb.get_result(); + + cb.unset_callback(); + + if ( rc == 0 ) + { + oss.str(""); + + oss << "" + << "" << result << ""; + + success_response(oss.str(), att); + } + else + { + att.resp_id = rc; + failure_response(ACTION, att); + } + + return; +} +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + void UserQuotaInfo::request_execute(xmlrpc_c::paramList const& paramList, RequestAttributes& att) {