#ifndef ASYNCDBCONNECTION_H #define ASYNCDBCONNECTION_H #include "PgsqlConn.h" #include "Pgsql_Params.h" #include "ConnectionConfig.h" #include // #include // #include #include // #include // #include // #include #include #include /** \brief Class that handles asynchronous execution of queries. * * Queries are passed to this class with a routine to call on completion * when the result is on that routine is called. */ class ASyncDBConnection { public: enum class State { NotConnected, Connecting, Connected, QuerySend, CancelSend, Terminating }; using on_result_callback = std::function, qint64)>; using on_state_callback = std::function; using on_notice_callback = std::function; ASyncDBConnection(boost::asio::io_service &ios); State state() const; // void setupConnection(const std::string &connstring); void setupConnection(const ConnectionConfig &config); void closeConnection(); void setStateCallback(on_state_callback state_callback); void setNoticeCallback(on_notice_callback notice_callback); /** Sends command to the server. When the result is in on_result will be called directly within the thread. If the command gives multiple results on_result will be called for each result. */ bool send(const std::string &command, on_result_callback on_result); bool send(const std::string &command, Pgsql::Params params, on_result_callback on_result); bool cancel(); private: Pgsql::Connection m_connection; boost::asio::ip::tcp::socket m_asioSock; ConnectionConfig m_config; State m_state = State::NotConnected; struct { std::mutex m_mutex; on_state_callback m_func; } m_stateCallback; struct { std::mutex m_mutex; on_notice_callback m_func; } m_noticeCallback; QElapsedTimer m_timer; void async_connect_handler(boost::system::error_code ec, std::size_t s); void async_query_handler(boost::system::error_code ec, std::size_t s, on_result_callback on_result); void doStateCallback(State state); void processNotice(const PGresult *result); // class Command { // public: // std::string command; // Pgsql::Params params; // on_result_callback on_result; // // Command() = default; // Command(const std::string &cmd, on_result_callback cb) // : command(cmd), on_result(cb) // {} // Command(const std::string &cmd, Pgsql::Params &&p, on_result_callback cb) // : command(cmd), params(p), on_result(cb) // {} // }; // // /// Contains all the members accessed by the thread // class Thread { // public: // using t_CommandQueue = std::queue; // struct { // std::mutex m_mutex; // on_state_callback m_func; // } m_stateCallback; // struct { // std::mutex m_mutex; // on_notice_callback m_func; // } m_noticeCallback; // // struct t_Command { // std::mutex m_mutex; // t_CommandQueue m_queue; // std::condition_variable m_newEvent; // t_Command() // {} // } m_commandQueue; // // // std::string m_initString; // ConnectionConfig m_config; // State m_state = State::NotConnected; // // Thread(); // // /// Is started as a seperate thread by ASyncDBConnection // void run(); // // /// Sends a cancel request to the DB server // bool cancel(); // // void stop(); // // private: // // /// \todo Implement new method to stop the thread // //Win32Event m_stopEvent; // Pgsql::Connection m_connection; // bool terminateRequested = false; ///< is set when the thread should stop // bool m_terminated = true; // Pgsql::Canceller m_canceller; // QElapsedTimer m_timer; // // // bool makeConnection(); // void communicate(); // // void doStateCallback(State state); // /// Wait's for a command to come in and send's it to the server // void waitForAndSendCommand(); // void doNewCommand(); // void waitForResult(); // // // void processNotice(const PGresult *result); // /** Function to call when after sending a command the socket is ready for reading. // * // * It might take several consumes before all data is read. // */ // bool consumeResultInput(); // }; // // Thread m_threadData; // std::thread m_thread; }; #endif // ASYNCDBCONNECTION_H