#ifndef ASYNCDBCONNECTION_H #define ASYNCDBCONNECTION_H #include "Pgsql_Connection.h" #include "Pgsql_Params.h" #include "Pgsql_Result.h" #include "Expected.h" #include "ConnectionConfig.h" #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 received that routine is called. The asynchronous * processing is done using boost::asio. * * You can cancel a running query but even then you have to wait for the result. */ class ASyncDBConnection { public: enum class State { NotConnected, Connecting, Connected, ///< connected and idle QuerySend, ///< connected query send expecting result CancelSend, ///< cancel send expecting result Terminating ///< shutting down }; using on_result_callback = std::function>, qint64)>; explicit ASyncDBConnection(boost::asio::io_service &ios); ~ASyncDBConnection(); State state() const; void setupConnection(const ConnectionConfig &config); void closeConnection(); /** \defgroup send These function send queries to the server. * * The query string can actually contain multiple queries. * These functions report their results through a callback function. * If the command gives multiple results on_result will be called for each result. * * \note when the io_service that was passed to the constructor is running * on a different thread the callback also will be done on that thread. Forward * the call to your own thread if needed. * * \note while you can pass multiple queries to a single send call it is not allowed to * send new queries while not all results have been received. */ /** \ingroup send * \brief Function to send a command without parameters to the server. */ bool send(const std::string &command, on_result_callback on_result); /** \ingroup send * \brief Function to send a a command with parameters to the server. */ bool send(const std::string &command, Pgsql::Params params, on_result_callback on_result); bool cancel(); using StateChangeReceiver = std::function; void setStateChangeReceiver(StateChangeReceiver state_change_receiver); using NoticeReceiver = std::function; void setNoticeReceiver(NoticeReceiver notice_receiver); private: Pgsql::Connection m_connection; boost::asio::ip::tcp::socket m_asioSock; ConnectionConfig m_config; State m_state = State::NotConnected; Pgsql::Canceller m_canceller; StateChangeReceiver m_stateChangeReceiver; NoticeReceiver m_noticeReceiver; 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); }; #endif // ASYNCDBCONNECTION_H