diff options
-rw-r--r-- | src/modules/UserBackendMysql/UserBackendMysql.cpp | 172 | ||||
-rw-r--r-- | src/modules/UserBackendMysql/UserBackendMysql.h | 28 |
2 files changed, 77 insertions, 123 deletions
diff --git a/src/modules/UserBackendMysql/UserBackendMysql.cpp b/src/modules/UserBackendMysql/UserBackendMysql.cpp index 0619409..6cabc16 100644 --- a/src/modules/UserBackendMysql/UserBackendMysql.cpp +++ b/src/modules/UserBackendMysql/UserBackendMysql.cpp @@ -140,6 +140,41 @@ void UserBackendMysql::configFinished() { } +UserBackendMysql::Result UserBackendMysql::query(const std::string &query, const ArgumentMap &args) throw(Core::Exception) { + if(!mysql || mysql_ping(mysql)) + throw Core::Exception(Core::Exception::NOT_AVAILABLE); + + if(args.empty()) { + mysql_real_query(mysql, query.c_str(), query.length()); + } + else { + std::string queryStr = query; + + for(ArgumentMap::const_iterator arg = args.begin(); arg != args.end(); ++arg) { + std::string argStr; + + try { + argStr = boost::get<std::string>(arg->second); + } + catch(...) { + std::ostringstream stream; + stream << arg->second; + argStr = stream.str(); + } + + boost::scoped_array<char> escaped(new char[argStr.length()*2+1]); + mysql_real_escape_string(mysql, escaped.get(), argStr.c_str(), argStr.length()); + + queryStr = boost::regex_replace(queryStr, boost::regex("\\{" + arg->first + "\\}"), "\"" + std::string(escaped.get()) + "\"", boost::match_default); + } + + mysql_real_query(mysql, queryStr.c_str(), queryStr.length()); + } + + return Result(mysql); +} + + boost::shared_ptr<const std::map<unsigned long, Common::UserInfo> > UserBackendMysql::getUserList(boost::posix_time::ptime *timestamp) throw(Core::Exception) { application->getThreadManager()->detach(); @@ -152,11 +187,7 @@ boost::shared_ptr<const std::map<unsigned long, Common::UserInfo> > UserBackendM return boost::shared_ptr<const std::map<unsigned long, Common::UserInfo> >(); } - if(!mysql || mysql_ping(mysql)) - throw Core::Exception(Core::Exception::NOT_AVAILABLE); - - mysql_real_query(mysql, queryListUsers.c_str(), queryListUsers.length()); - Result result(mysql); + Result result = query(queryListUsers); lock.unlock(); @@ -189,20 +220,10 @@ boost::shared_ptr<const Common::UserInfo> UserBackendMysql::getUserInfo(unsigned return boost::shared_ptr<const Common::UserInfo>(); } - if(!mysql || mysql_ping(mysql)) - throw Core::Exception(Core::Exception::NOT_AVAILABLE); - - std::string query = queryUserById; - - std::ostringstream tmp; - tmp << '"'; - tmp << uid; - tmp << '"'; + ArgumentMap args; + args.insert(std::make_pair("UID", uid)); - query = boost::regex_replace(query, boost::regex("\\{UID\\}"), tmp.str(), boost::match_default); - - mysql_real_query(mysql, query.c_str(), query.length()); - Result result(mysql); + Result result = query(queryUserById, args); lock.unlock(); @@ -235,17 +256,10 @@ boost::shared_ptr<const Common::UserInfo> UserBackendMysql::getUserInfoByName(co return boost::shared_ptr<const Common::UserInfo>(); } - if(!mysql || mysql_ping(mysql)) - throw Core::Exception(Core::Exception::NOT_AVAILABLE); - - boost::scoped_array<char> escapedName(new char[name.length()*2+1]); + ArgumentMap args; + args.insert(std::make_pair("USER", name)); - mysql_real_escape_string(mysql, escapedName.get(), name.c_str(), name.length()); - - std::string query = boost::regex_replace(queryUserByName, boost::regex("\\{USER\\}"), "\""+std::string(escapedName.get())+"\"", boost::match_default); - - mysql_real_query(mysql, query.c_str(), query.length()); - Result result(mysql); + Result result = query(queryUserByName, args); lock.unlock(); @@ -278,18 +292,10 @@ boost::shared_ptr<const std::set<unsigned long> > UserBackendMysql::getUserGroup return boost::shared_ptr<const std::set<unsigned long> >(); } - if(!mysql || mysql_ping(mysql)) - throw Core::Exception(Core::Exception::NOT_AVAILABLE); - - std::ostringstream tmp; - tmp << '"'; - tmp << uid; - tmp << '"'; + ArgumentMap args; + args.insert(std::make_pair("UID", uid)); - std::string query = boost::regex_replace(queryListUserGroups, boost::regex("\\{UID\\}"), tmp.str(), boost::match_default); - - mysql_real_query(mysql, query.c_str(), query.length()); - Result result(mysql); + Result result = query(queryListUserGroups, args); lock.unlock(); @@ -317,11 +323,7 @@ boost::shared_ptr<const std::map<unsigned long, Common::GroupInfo> > UserBackend return boost::shared_ptr<const std::map<unsigned long, Common::GroupInfo> >(); } - if(!mysql || mysql_ping(mysql)) - throw Core::Exception(Core::Exception::NOT_AVAILABLE); - - mysql_real_query(mysql, queryListGroups.c_str(), queryListGroups.length()); - Result result(mysql); + Result result = query(queryListGroups); lock.unlock(); @@ -351,20 +353,10 @@ boost::shared_ptr<const Common::GroupInfo> UserBackendMysql::getGroupInfo(unsign return boost::shared_ptr<const Common::GroupInfo>(); } - if(!mysql || mysql_ping(mysql)) - throw Core::Exception(Core::Exception::NOT_AVAILABLE); + ArgumentMap args; + args.insert(std::make_pair("GID", gid)); - std::string query = queryGroupById; - - std::ostringstream tmp; - tmp << '"'; - tmp << gid; - tmp << '"'; - - query = boost::regex_replace(query, boost::regex("\\{GID\\}"), tmp.str(), boost::match_default); - - mysql_real_query(mysql, query.c_str(), query.length()); - Result result(mysql); + Result result = query(queryGroupById, args); lock.unlock(); @@ -391,17 +383,10 @@ boost::shared_ptr<const Common::GroupInfo> UserBackendMysql::getGroupInfoByName( return boost::shared_ptr<const Common::GroupInfo>(); } - if(!mysql || mysql_ping(mysql)) - throw Core::Exception(Core::Exception::NOT_AVAILABLE); - - boost::scoped_array<char> escapedName(new char[name.length()*2+1]); - - mysql_real_escape_string(mysql, escapedName.get(), name.c_str(), name.length()); + ArgumentMap args; + args.insert(std::make_pair("GROUP", name)); - std::string query = boost::regex_replace(queryGroupByName, boost::regex("\\{GROUP\\}"), "\""+std::string(escapedName.get())+"\"", boost::match_default); - - mysql_real_query(mysql, query.c_str(), query.length()); - Result result(mysql); + Result result = query(queryGroupByName, args); lock.unlock(); @@ -428,18 +413,10 @@ boost::shared_ptr<const std::set<unsigned long> > UserBackendMysql::getGroupUser return boost::shared_ptr<const std::set<unsigned long> >(); } - if(!mysql || mysql_ping(mysql)) - throw Core::Exception(Core::Exception::NOT_AVAILABLE); - - std::ostringstream tmp; - tmp << '"'; - tmp << gid; - tmp << '"'; + ArgumentMap args; + args.insert(std::make_pair("GID", gid)); - std::string query = boost::regex_replace(queryListGroupUsers, boost::regex("\\{GID\\}"), tmp.str(), boost::match_default); - - mysql_real_query(mysql, query.c_str(), query.length()); - Result result(mysql); + Result result = query(queryListGroupUsers, args); lock.unlock(); @@ -466,11 +443,7 @@ boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > UserBacken return boost::shared_ptr<const std::multimap<unsigned long, unsigned long> >(); } - if(!mysql || mysql_ping(mysql)) - throw Core::Exception(Core::Exception::NOT_AVAILABLE); - - mysql_real_query(mysql, queryUserGroupTable.c_str(), queryUserGroupTable.length()); - Result result(mysql); + Result result = query(queryUserGroupTable); lock.unlock(); @@ -493,34 +466,13 @@ void UserBackendMysql::addUser(const Common::UserInfo &userInfo) throw(Core::Exc if(!mysql || mysql_ping(mysql)) throw Core::Exception(Core::Exception::NOT_AVAILABLE); - std::ostringstream tmp; - tmp << '"'; - tmp << userInfo.getUid(); - tmp << '"'; - - std::string query = boost::regex_replace(queryAddUser, boost::regex("\\{UID\\}"), tmp.str(), boost::match_default); - - tmp.str(std::string()); - tmp << '"'; - tmp << userInfo.getGid(); - tmp << '"'; - - query = boost::regex_replace(query, boost::regex("\\{GID\\}"), tmp.str(), boost::match_default); - - const std::string &username = userInfo.getUsername(); - boost::scoped_array<char> escapedUsername(new char[username.length()*2+1]); - mysql_real_escape_string(mysql, escapedUsername.get(), username.c_str(), username.length()); - - query = boost::regex_replace(query, boost::regex("\\{USER\\}"), "\"" + std::string(escapedUsername.get()) + "\"", boost::match_default); - - const std::string &fullName = userInfo.getFullName(); - boost::scoped_array<char> escapedFullName(new char[fullName.length()*2+1]); - mysql_real_escape_string(mysql, escapedFullName.get(), fullName.c_str(), fullName.length()); - - query = boost::regex_replace(query, boost::regex("\\{FULL_NAME\\}"), "\"" + std::string(escapedFullName.get()) + "\"", boost::match_default); + ArgumentMap args; + args.insert(std::make_pair("UID", userInfo.getUid())); + args.insert(std::make_pair("GID", userInfo.getGid())); + args.insert(std::make_pair("USER", userInfo.getUsername())); + args.insert(std::make_pair("FULL_NAME", userInfo.getFullName())); - mysql_real_query(mysql, query.c_str(), query.length()); - Result result(mysql); + Result result = query(queryAddUser, args); if(result.getErrno()) { if(result.getErrno() == ER_DUP_ENTRY) diff --git a/src/modules/UserBackendMysql/UserBackendMysql.h b/src/modules/UserBackendMysql/UserBackendMysql.h index 25c3837..5c62072 100644 --- a/src/modules/UserBackendMysql/UserBackendMysql.h +++ b/src/modules/UserBackendMysql/UserBackendMysql.h @@ -29,6 +29,7 @@ #include <mysql/mysql.h> #include <boost/thread/mutex.hpp> +#include <boost/variant.hpp> namespace Mad { namespace Modules { @@ -36,27 +37,28 @@ namespace UserBackendMysql { class UserBackendMysql : public Common::UserBackend, private Core::Configurable, private boost::noncopyable { private: - class Result : private boost::noncopyable { + typedef std::map<std::string, boost::variant<std::string, unsigned long> > ArgumentMap; + + class Result; + Result query(const std::string &query, const ArgumentMap &args = ArgumentMap()) throw(Core::Exception); + + class Result { private: - MYSQL_RES *result; + friend Result UserBackendMysql::query(const std::string &query, const ArgumentMap &args) throw(Core::Exception); + + boost::shared_ptr<MYSQL_RES> result; unsigned int mysqlErrno; const char *error; - public: Result(MYSQL *mysql) { - result = mysql_store_result(mysql); + result = boost::shared_ptr<MYSQL_RES>(mysql_store_result(mysql), mysql_free_result); mysqlErrno = mysql_errno(mysql); error = mysql_error(mysql); } - ~Result() { - if(result) { - mysql_free_result(result); - } - } - + public: operator bool() const { return result; } @@ -70,15 +72,15 @@ class UserBackendMysql : public Common::UserBackend, private Core::Configurable, } unsigned int getFieldNumber() const { - return mysql_num_fields(result); + return mysql_num_fields(result.get()); } my_ulonglong getRowNumber() const { - return mysql_num_rows(result); + return mysql_num_rows(result.get()); } MYSQL_ROW getNextRow() { - return mysql_fetch_row(result); + return mysql_fetch_row(result.get()); } }; |