pgLab/asyncdbconnection.h
Eelke Klein d19741f111 Connection manager can now open a query window for selected connection.
Query window has now buttons with icons made in the designer for better looks.
Depending on received responses from the database the tabcontrol with the message, data and explain tab
now switches to the appropriate tab.
2017-01-15 21:01:40 +01:00

123 lines
2.6 KiB
C++

#ifndef ASYNCDBCONNECTION_H
#define ASYNCDBCONNECTION_H
#include "PgsqlConn.h"
#include "win32event.h"
#include "connectionconfig.h"
#include <functional>
#include <mutex>
#include <queue>
#include <vector>
#include <thread>
class ASyncDBConnection {
public:
enum class State {
NotConnected,
Connecting,
Connected,
QuerySend,
CancelSend,
Terminating
};
using on_result_callback = std::function<void(std::shared_ptr<Pgsql::Result>)>;
using on_state_callback = std::function<void(State)>;
using on_notice_callback = std::function<void(Pgsql::ErrorDetails)>;
ASyncDBConnection();
// 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 cancel();
private:
class Command {
public:
std::string command;
on_result_callback on_result;
Command() = default;
Command(const std::string &cmd, on_result_callback cb)
: command(cmd), on_result(cb)
{}
};
/// Contains all the members accessed by the thread
class Thread {
public:
using t_CommandQueue = std::queue<Command>;
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;
Win32Event m_newEvent;
t_Command()
: m_newEvent(Win32Event::Reset::Auto, Win32Event::Initial::Clear)
{}
} m_commandQueue;
// std::string m_initString;
ConnectionConfig m_config;
Thread();
/// Is started as a seperate thread by ASyncDBConnection
void run();
/// Sends a cancel request to the DB server
bool cancel();
void stop();
private:
State m_state = State::NotConnected;
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;
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);
};
Thread m_threadData;
std::thread m_thread;
};
#endif // ASYNCDBCONNECTION_H