diff --git a/include/ConcurrentQueue.hpp b/include/ConcurrentQueue.hpp index 9190a38..3b2da6e 100644 --- a/include/ConcurrentQueue.hpp +++ b/include/ConcurrentQueue.hpp @@ -2,6 +2,7 @@ #define CONCURRENTQUEUE_HPP #include +#include #include "Mutex.hpp" #include "ConditionVariable.hpp" @@ -14,91 +15,90 @@ class CancelledException {}; template -class ConcurrentQueue { - - public: - - - ConcurrentQueue() - : m_queue() - , m_cancelled(false) - , m_mutex() - , m_condVar(m_mutex) - { - TRACE; - } - - ~ConcurrentQueue() - { - TRACE; - } - - - void push(const T value) - { - TRACE; - ScopedLock sl(m_mutex); - if (m_cancelled) throw CancelledException(); - m_queue.push( value ); - m_condVar.signal(); - } - - - bool tryPop(T &popped_value) - { - TRACE; - ScopedLock sl(m_mutex); - if (m_cancelled) throw CancelledException(); - if ( m_queue.empty() ) return false; - - popped_value = m_queue.front(); - m_queue.pop(); - return true; +class ConcurrentQueue +{ +public: + + ConcurrentQueue() + : m_queue() + , m_cancelled(false) + , m_mutex() + , m_condVar(m_mutex) + { + TRACE; + } + + ~ConcurrentQueue() + { + TRACE; + } + + + void push(const T value) + { + TRACE; + ScopedLock sl(m_mutex); + if (m_cancelled) throw CancelledException(); + m_queue.push( value ); + m_condVar.signal(); + } + + + bool tryPop(T &popped_value) + { + TRACE; + ScopedLock sl(m_mutex); + if (m_cancelled) throw CancelledException(); + if ( m_queue.empty() ) return false; + + popped_value = m_queue.front(); + m_queue.pop(); + return true; + } + + + T waitAndPop() + { + TRACE; + ScopedLock sl(m_mutex); + + while ( m_queue.empty() and not m_cancelled) { + m_condVar.wait(); } + if (m_cancelled) throw CancelledException(); + T retVal = m_queue.front(); // cctor + m_queue.pop(); + return retVal; + } - T waitAndPop() - { - TRACE; - ScopedLock sl(m_mutex); - while ( m_queue.empty() and not m_cancelled) { - m_condVar.wait(); - } - if (m_cancelled) throw CancelledException(); - - T retVal = m_queue.front(); // cctor - m_queue.pop(); - return retVal; - } + bool empty() const + { + TRACE; + ScopedLock sl(m_mutex); + if (m_cancelled) throw CancelledException(); + return m_queue.empty(); + } - bool empty() const - { - TRACE; - ScopedLock sl(m_mutex); - if (m_cancelled) throw CancelledException(); - return m_queue.empty(); - } - - - void cancel() - { - TRACE; - ScopedLock sl(m_mutex); - m_cancelled = true; - m_condVar.broadcast(); - } + void cancel() + { + TRACE; + ScopedLock sl(m_mutex); + m_cancelled = true; + m_condVar.broadcast(); + } - private: +private: - ConcurrentQueue& operator=( const ConcurrentQueue& ); - ConcurrentQueue( const ConcurrentQueue& ); + ConcurrentQueue& operator=( const ConcurrentQueue& ); + ConcurrentQueue( const ConcurrentQueue& ); - std::queue m_queue; - bool m_cancelled; - mutable Mutex m_mutex; - ConditionVariable m_condVar; + std::queue m_queue; + bool m_cancelled; + mutable Mutex m_mutex; + ConditionVariable m_condVar; }; diff --git a/include/MysqlConnectionPool.hpp b/include/MysqlConnectionPool.hpp index 0577311..9b3f069 100644 --- a/include/MysqlConnectionPool.hpp +++ b/include/MysqlConnectionPool.hpp @@ -9,18 +9,27 @@ class MysqlConnectionPool : public ObjectPool { public: - MysqlConnectionPool(); - ~MysqlConnectionPool(); - - MysqlClient* create( const char *host = NULL, + MysqlConnectionPool( const char *host = NULL, const char *user = NULL, const char *passwd = NULL, - const char *db = NULL, - unsigned int port = 0, - const char *unix_socket = NULL, - unsigned long clientflag = 0 ); + const char *db = NULL ); + ~MysqlConnectionPool(); + + void create(); + + /// @note Shall this be a specialized ObjectPool::clear? + void clear(); + +private: + + MysqlConnectionPool(const MysqlConnectionPool&); + MysqlConnectionPool& operator=(const MysqlConnectionPool&); + + const char *m_host; + const char *m_user; + const char *m_passwd; + const char *m_db; - bool reset(const MysqlClient* client); }; diff --git a/include/ObjectPool.hpp b/include/ObjectPool.hpp index 0085bf4..af6ed6b 100644 --- a/include/ObjectPool.hpp +++ b/include/ObjectPool.hpp @@ -2,28 +2,46 @@ #define OBJECT_POOL_HPP #include "ConcurrentQueue.hpp" +#include "Logger.hpp" template class ObjectPool { public: - ObjectPool(); - virtual ~ObjectPool(); + ObjectPool() : m_pool() + { + TRACE; + } - void add(const T object); - void remove(const T object); - void clear(); + virtual ~ObjectPool() + { + TRACE; + } - T get(); - virtual void reset(const T object) = 0; - void release(const T object); + + T acquire() + { + TRACE; + return m_pool.waitAndPop(); + } + + void release(const T object) + { + TRACE; + m_pool.push(object); + } + + bool empty() const + { + TRACE; + return m_pool.empty(); + } private: ConcurrentQueue m_pool; - }; #endif // OBJECT_POOL_HPP diff --git a/other/mysqlclient_main.cpp b/other/mysqlclient_main.cpp index a3ea231..dae693b 100644 --- a/other/mysqlclient_main.cpp +++ b/other/mysqlclient_main.cpp @@ -6,6 +6,8 @@ #include "ArgParse.hpp" #include "MysqlClient.hpp" +#include "MysqlConnectionPool.hpp" + #include #include @@ -15,9 +17,12 @@ void setUpArgs(ArgParse &argParse) { + TRACE_STATIC; + argParse.addArgument("--host", "Hostname/IP", - ArgParse::STRING ); + ArgParse::STRING, + ArgParse::REQUIRED ); argParse.addArgument("-u, --user", "Username", ArgParse::STRING, @@ -30,14 +35,9 @@ void setUpArgs(ArgParse &argParse) "Password", ArgParse::STRING, ArgParse::REQUIRED ); - argParse.addArgument("-port", - "Port", - ArgParse::INT ); - argParse.addArgument("-s, --unix-socket", - "Unix socket", - ArgParse::STRING ); - argParse.addArgument("-f, --client-flags", - "Client flags", + + argParse.addArgument("-n, --number-of-connections", + "Number of connections. Default is 5", ArgParse::INT ); } @@ -48,24 +48,59 @@ void getArgs( int argc, char* argv[], std::string &user, std::string &db, std::string &pass, - std::string &unixsocket, - int &port, - int &clientflags ) + int &numberOfConnections ) { + TRACE_STATIC; + argParse.parseArgs(argc, argv); argParse.argAsString("--host", host); argParse.argAsString("-u, --user", user); argParse.argAsString("-db, --database", db); argParse.argAsString("-p, --password", pass); - argParse.argAsInt("-port", port); - argParse.argAsString("-s, --unix-socket", unixsocket); - argParse.argAsInt("-f, --client-flags", clientflags); + + argParse.argAsInt("-n, --number-of-connections", numberOfConnections); +} + + +bool checkArgs( int argc, char* argv[], + ArgParse &argParse, + std::string &host, + std::string &user, + std::string &db, + std::string &pass, + int &numberOfConnections ) +{ + TRACE_STATIC; + + try { + getArgs( argc, argv, + argParse, + host, user, db, pass, + numberOfConnections ); + } catch (std::runtime_error e) { + if ( argParse.foundArg("-h, --help") ) { + std::cout << argParse.usage() << std::endl; + return false; + } + std::cerr << e.what() << std::endl + << "Check usage: " << argv[0] << " --help" << std::endl; + return false; + } + + if ( argParse.foundArg("-h, --help") ) { + std::cout << argParse.usage() << std::endl; + return false; + } + + return true; } void printResults(std::list &results) { + TRACE_STATIC; + LOG ( Logger::DEBUG, std::string("Got query result number of rows: "). append(TToStr(results.size())).c_str() ); @@ -83,55 +118,44 @@ int main(int argc, char* argv[] ) Logger::init(std::cout); Logger::setLogLevel(Logger::FINEST); + + // args ArgParse argParse("Simple MySQL client", "Report bugs to: denes.matetelki@gmail.com"); - setUpArgs(argParse); - std::string host, user, db, pass, unixsocket; - int port, clientflags; - - try { - getArgs( argc, argv, - argParse, - host, user, db, pass, unixsocket, - port, clientflags ); - } catch (std::runtime_error e) { - if ( argParse.foundArg("-h, --help") ) { - std::cout << argParse.usage() << std::endl; - return 1; - } - std::cerr << e.what() << std::endl - << "Check usage: " << argv[0] << " --help" << std::endl; - return 1; - } - + std::string host, user, db, pass; + int numberOfConnections(5); - if ( argParse.foundArg("-h, --help") ) { - std::cout << argParse.usage() << std::endl; + if ( !checkArgs(argc, argv, argParse, + host, user, db, pass, numberOfConnections ) ) return 1; - } + // init init_client_errs(); + MysqlConnectionPool cp ( + argParse.foundArg("--host") ? host.c_str() : NULL, + argParse.foundArg("-u, --user") ? user.c_str() : NULL, + argParse.foundArg("-p, --password") ? pass.c_str() : NULL, + argParse.foundArg("-db, --database") ? db .c_str() : NULL ); + + for ( int i = 0; i < numberOfConnections; ++i ) + cp.create(); - MysqlClient mysqlClient ( - argParse.foundArg("--host") ? host.c_str() : NULL, - argParse.foundArg("-u, --user") ? user.c_str() : NULL, - argParse.foundArg("-p, --password") ? pass.c_str() : NULL, - argParse.foundArg("-db, --database") ? db .c_str() : NULL, - argParse.foundArg("-port") ? port : 0, - argParse.foundArg("-s, --unix-socket") ? unixsocket.c_str() : NULL, - argParse.foundArg("-f, --client-flags") ? clientflags : 0 ); + // work std::list results; - if ( !mysqlClient.querty("SELECT * FROM seats", results) ) { + MysqlClient *c = cp.acquire(); + if ( !c->querty("SELECT * FROM seats", results) ) { LOG ( Logger::ERR, "Could not execute query." ); } else { printResults(results); } + cp.release(c); + // end + cp.clear(); finish_client_errs(); - Logger::destroy(); return 0; } diff --git a/src/MysqlConnectionPool.cpp b/src/MysqlConnectionPool.cpp index 0e1e098..07259bb 100644 --- a/src/MysqlConnectionPool.cpp +++ b/src/MysqlConnectionPool.cpp @@ -3,45 +3,36 @@ #include "Logger.hpp" -MysqlConnectionPool::MysqlConnectionPool() +MysqlConnectionPool::MysqlConnectionPool( const char *host, + const char *user, + const char *passwd, + const char *db ) + : m_host(host) + , m_user(user) + , m_passwd(passwd) + , m_db(db) { TRACE; } - MysqlConnectionPool::~MysqlConnectionPool() { TRACE; } -MysqlClient* MysqlConnectionPool::create( const char* host, - const char* user, - const char* passwd, - const char* db, - unsigned int port, - const char* unix_socket, - long unsigned int clientflag ) +void MysqlConnectionPool::create() { TRACE; - MysqlClient *client = new MysqlClient(host, - user, - passwd, - db, - port, - unix_socket, - clientflag); - - return client; + MysqlClient *client = new MysqlClient ( m_host, m_user, m_passwd, m_db ); + client->connect(); + release(client); } - -bool MysqlConnectionPool::reset(const MysqlClient* client) +void MysqlConnectionPool::clear() { TRACE; - - // The MysqlClient is stateless - - return true; -} \ No newline at end of file + while ( !empty() ) + delete acquire(); +} diff --git a/src/ObjectPool.cpp b/src/ObjectPool.cpp deleted file mode 100644 index f108379..0000000 --- a/src/ObjectPool.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "ObjectPool.hpp" - -#include "Logger.hpp" - - -template -ObjectPool::ObjectPool() - : m_pool() -{ - TRACE; -} - - -template -ObjectPool::~ObjectPool() -{ - TRACE; -} - - -template -void ObjectPool::add(const T object) -{ - TRACE; - m_pool.push(object); -} - - -template -void ObjectPool::remove(const T object) -{ - TRACE; - -// m_pool.tryPop(object); -} - - -template -void ObjectPool::clear() -{ - TRACE; - -// while ( !m_pool.empty() ) -// m_pool. -} - - -template -T ObjectPool::get() -{ - TRACE; - - return m_pool.waitAndPop(); -} - - -template -void ObjectPool::release(const T object) -{ - TRACE; - - m_pool.push(object); -}