diff --git a/Ivory.pro b/Ivory.pro index 8769585..48c68fe 100644 --- a/Ivory.pro +++ b/Ivory.pro @@ -13,7 +13,7 @@ TEMPLATE = app INCLUDEPATH += C:\prog\include DEFINES += WIN32_LEAN_AND_MEAN -LIBS += c:\prog\lib\libpq.lib +LIBS += c:\prog\lib\libpq.lib User32.lib SOURCES += main.cpp\ mainwindow.cpp \ @@ -27,7 +27,8 @@ SOURCES += main.cpp\ explaintreemodelitem.cpp \ asyncdbconnection.cpp \ tsqueue.cpp \ - win32event.cpp + win32event.cpp \ + waithandlelist.cpp HEADERS += mainwindow.h \ serverproperties.h \ @@ -39,7 +40,8 @@ HEADERS += mainwindow.h \ explaintreemodelitem.h \ asyncdbconnection.h \ tsqueue.h \ - win32event.h + win32event.h \ + waithandlelist.h FORMS += mainwindow.ui \ serverproperties.ui diff --git a/PgsqlConn.h b/PgsqlConn.h index 45fdf88..9941df5 100644 --- a/PgsqlConn.h +++ b/PgsqlConn.h @@ -160,6 +160,12 @@ namespace Pgsql { } bool connectStart(const char *params); + + bool connectStart(const std::string ¶ms) + { + return connectStart(params.c_str()); + } + bool connectStart(const QString ¶ms) { return connectStart(params.toUtf8().data()); diff --git a/asyncdbconnection.cpp b/asyncdbconnection.cpp index 289775b..30ec76a 100644 --- a/asyncdbconnection.cpp +++ b/asyncdbconnection.cpp @@ -1,4 +1,6 @@ #include "asyncdbconnection.h" +#include "waithandlelist.h" +#include ASyncDBConnection::ASyncDBConnection() { @@ -6,14 +8,26 @@ ASyncDBConnection::ASyncDBConnection() } void ASyncDBConnection::setupConnection(const std::string &connstring) -{} +{ + m_threadData.m_initString = connstring; + m_thread = std::thread([this] () { m_threadData.run(); }); +} void ASyncDBConnection::closeConnection() -{} +{ + m_threadData.stop(); + m_thread.join(); +} void ASyncDBConnection::setStateCallback(on_state_callback state_callback) -{} +{ + std::lock_guard lg(m_threadData.m_stateCallbackMutex); + m_threadData.m_stateCallback = state_callback; +} +ASyncDBConnection::Thread::Thread() + : m_stopEvent(Win32Event::Reset::Manual, Win32Event::Initial::Clear) +{} void ASyncDBConnection::Thread::run() { @@ -21,6 +35,8 @@ void ASyncDBConnection::Thread::run() // make or recover connection if (makeConnection()) { + + // send commands and receive results communicate(); } @@ -32,14 +48,62 @@ void ASyncDBConnection::Thread::run() bool ASyncDBConnection::Thread::makeConnection() { + using namespace std::chrono_literals; + while (!terminateRequested) { // start connecting + bool ok = m_connection.connectStart(m_initString + " client_encoding=utf8"); + auto start = std::chrono::steady_clock::now(); + if (ok && m_connection.status() != CONNECTION_BAD) { + int sock = m_connection.socket(); + Win32Event socket_event(Win32Event::Reset::Auto, Win32Event::Initial::Clear); - // poll till complete or failed (we can get an abort command) + long fd = FD_WRITE; + while (true) { + // poll till complete or failed (we can get an abort command) + WSAEventSelect(sock, socket_event.handle(), fd); + WaitHandleList whl; + auto wait_result_socket_event = whl.add(socket_event); + auto wait_result_stop = whl.add(m_stopEvent); - // if connected return true - // else retry (unless we get a command to stop then return false) + auto nu = std::chrono::steady_clock::now(); + std::chrono::duration diff = -(nu-start); + diff += 30s; + DWORD timeout = diff.count(); + + DWORD res = MsgWaitForMultipleObjectsEx( + whl.count(), // _In_ DWORD nCount, + whl, // _In_ const HANDLE *pHandles, + timeout, // _In_ DWORD dwMilliseconds, + 0, // _In_ DWORD dwWakeMask, + 0 // _In_ DWORD dwFlags + ); + if (res == wait_result_socket_event) { + auto poll_state = m_connection.connectPoll(); + if (poll_state == PGRES_POLLING_OK) { + // if connected return true + doStateCallback(State::Connected); + return true; + } + else if (poll_state == PGRES_POLLING_FAILED) { + doStateCallback(State::NotConnected); + return false; + } + else if (poll_state == PGRES_POLLING_READING) { + doStateCallback(State::Connecting); + fd = FD_READ; + } + else if (poll_state == PGRES_POLLING_WRITING) { + doStateCallback(State::Connecting); + fd = FD_WRITE; + } + } + else if (res == wait_result_stop) { + + } + } // end while (true) + } } return false; } @@ -57,5 +121,32 @@ void ASyncDBConnection::Thread::communicate() // - return // - stop signal // - return + +// WSAEventSelect(sock, socket_event.handle(), fd); + WaitHandleList whl; +// auto wait_result_socket_event = whl.add(socket_event); + auto wait_result_stop = whl.add(m_stopEvent); + + DWORD res = MsgWaitForMultipleObjectsEx( + whl.count(), // _In_ DWORD nCount, + whl, // _In_ const HANDLE *pHandles, + INFINITE, // _In_ DWORD dwMilliseconds, + 0, // _In_ DWORD dwWakeMask, + 0 // _In_ DWORD dwFlags + ); + } +} + +void ASyncDBConnection::Thread::stop() +{ + terminateRequested = true; + m_stopEvent.set(); +} + +void ASyncDBConnection::Thread::doStateCallback(State state) +{ + std::lock_guard lg(m_stateCallbackMutex); + if (m_stateCallback) { + m_stateCallback(state); } } diff --git a/asyncdbconnection.h b/asyncdbconnection.h index 81c1800..6c64826 100644 --- a/asyncdbconnection.h +++ b/asyncdbconnection.h @@ -2,8 +2,11 @@ #define ASYNCDBCONNECTION_H #include "PgsqlConn.h" +#include "win32event.h" #include +#include #include +#include class ASyncDBConnection { public: @@ -45,24 +48,36 @@ private: /// Contains all the members accessed by the thread class Thread { public: - on_state_callback m_state_callback; - std::string m_init_string; + on_state_callback m_stateCallback; + std::mutex m_stateCallbackMutex; + + std::string m_initString; + + Thread(); /// Is started as a seperate thread by ASyncDBConnection void run(); /// Sends a cancel request to the DB server void cancel(); + + void stop(); + private: + Win32Event m_stopEvent; Pgsql::Connection m_connection; bool terminateRequested = false; ///< is set when the thread should stop + bool makeConnection(); void communicate(); + + void doStateCallback(State state); }; - Thread thread; + Thread m_threadData; + std::thread m_thread; }; #endif // ASYNCDBCONNECTION_H diff --git a/mainwindow.cpp b/mainwindow.cpp index 75e3d22..05e5506 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -26,10 +26,10 @@ const char * test_query = "GROUP BY f1.id" ; -MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), - ui(new Ui::MainWindow), - queryCancel(nullptr) +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +// , queryCancel(nullptr) { ui->setupUi(this); @@ -46,18 +46,27 @@ MainWindow::MainWindow(QWidget *parent) : action = ui->mainToolBar->addAction("connect"); connect(action, &QAction::triggered, this, &MainWindow::startConnect); - action = ui->mainToolBar->addAction("execute"); - connect(action, &QAction::triggered, this, &MainWindow::performQuery); +// action = ui->mainToolBar->addAction("execute"); +// connect(action, &QAction::triggered, this, &MainWindow::performQuery); - action = ui->mainToolBar->addAction("explain"); - connect(action, &QAction::triggered, this, &MainWindow::performExplain); +// action = ui->mainToolBar->addAction("explain"); +// connect(action, &QAction::triggered, this, &MainWindow::performExplain); - action = ui->mainToolBar->addAction("cancel"); - connect(action, &QAction::triggered, this, &MainWindow::cancel_query); +// action = ui->mainToolBar->addAction("cancel"); +// connect(action, &QAction::triggered, this, &MainWindow::cancel_query); + + m_dbConnection.setStateCallback([this](ASyncDBConnection::State st) + { + QueueTask([this, st]() { connectionStateChanged(st); }); + }); } MainWindow::~MainWindow() -{} +{ + m_dbConnection.closeConnection(); + m_dbConnection.setStateCallback(nullptr); + +} void MainWindow::QueueTask(TSQueue::t_Callable c) { @@ -78,198 +87,223 @@ void MainWindow::processCallableQueue() } } +void MainWindow::connectionStateChanged(ASyncDBConnection::State state) +{ + QString status_str; + switch (state) { + case ASyncDBConnection::State::NotConnected: + status_str = tr("Geen verbinding"); + break; + case ASyncDBConnection::State::Connecting: + status_str = tr("Verbinden"); + break; + case ASyncDBConnection::State::Connected: + status_str = tr("Verbonden"); + break; + case ASyncDBConnection::State::QuerySend: + status_str = tr("Query verstuurd"); + break; + case ASyncDBConnection::State::CancelSend: + status_str = tr("Query geannuleerd"); + break; + } + statusBar()->showMessage(status_str); +} + void MainWindow::startConnect() { - if (connection == nullptr) { - connection = std::make_unique(); - } - QString connstr = ui->connectionStringEdit->text(); - bool ok = connection->connectStart(connstr + " application_name=Ivory client_encoding=utf8"); - if (ok && connection->status() != CONNECTION_BAD) { - // Start polling - int s = connection->socket(); +// if (connection == nullptr) { +// connection = std::make_unique(); +// } +// QString connstr = ui->connectionStringEdit->text(); +// bool ok = connection->connectStart(connstr + " application_name=Ivory client_encoding=utf8"); +// if (ok && connection->status() != CONNECTION_BAD) { +// // Start polling +// int s = connection->socket(); - connectingState.notifier = std::make_unique(s, QSocketNotifier::Write); - connect(connectingState.notifier.get(), &QSocketNotifier::activated, this, &MainWindow::socket_activate_connect); +// connectingState.notifier = std::make_unique(s, QSocketNotifier::Write); +// connect(connectingState.notifier.get(), &QSocketNotifier::activated, this, &MainWindow::socket_activate_connect); - connectingState.poll_state = PGRES_POLLING_WRITING; - statusBar()->showMessage(tr("Connecting")); - } - else { - statusBar()->showMessage(tr("Connecting fail")); - } +// connectingState.poll_state = PGRES_POLLING_WRITING; +// statusBar()->showMessage(tr("Connecting")); +// } +// else { +// statusBar()->showMessage(tr("Connecting fail")); +// } + std::string connstr = ui->connectionStringEdit->text().toUtf8().data(); + m_dbConnection.setupConnection(connstr); } -void MainWindow::socket_activate_connect(int ) -{ - connectingState.poll_state = connection->connectPoll(); +//void MainWindow::socket_activate_connect(int ) +//{ +// connectingState.poll_state = connection->connectPoll(); - if (connectingState.poll_state == PGRES_POLLING_OK) { - connection->setNoticeReceiver( - std::bind(&MainWindow::processNotice, this, std::placeholders::_1)); - statusBar()->showMessage(tr("Connected")); - connectingState.notifier.reset(); - } - else if (connectingState.poll_state = PGRES_POLLING_FAILED) { - statusBar()->showMessage(tr("Connection failed")); - connectingState.notifier.reset(); - } - else if (connectingState.poll_state == PGRES_POLLING_READING) { - statusBar()->showMessage(tr("Connecting..")); - connectingState.notifier = std::make_unique(connection->socket(), QSocketNotifier::Read); - connect(connectingState.notifier.get(), &QSocketNotifier::activated, this, &MainWindow::socket_activate_connect); - } - else if (connectingState.poll_state == PGRES_POLLING_WRITING) { - statusBar()->showMessage(tr("Connecting...")); - connectingState.notifier = std::make_unique(connection->socket(), QSocketNotifier::Write); - connect(connectingState.notifier.get(), &QSocketNotifier::activated, this, &MainWindow::socket_activate_connect); - } -} +// if (connectingState.poll_state == PGRES_POLLING_OK) { +// connection->setNoticeReceiver( +// std::bind(&MainWindow::processNotice, this, std::placeholders::_1)); +// statusBar()->showMessage(tr("Connected")); +// connectingState.notifier.reset(); +// } +// else if (connectingState.poll_state == PGRES_POLLING_FAILED) { +// statusBar()->showMessage(tr("Connection failed")); +// connectingState.notifier.reset(); +// } +// else if (connectingState.poll_state == PGRES_POLLING_READING) { +// statusBar()->showMessage(tr("Connecting..")); +// connectingState.notifier = std::make_unique(connection->socket(), QSocketNotifier::Read); +// connect(connectingState.notifier.get(), &QSocketNotifier::activated, this, &MainWindow::socket_activate_connect); +// } +// else if (connectingState.poll_state == PGRES_POLLING_WRITING) { +// statusBar()->showMessage(tr("Connecting...")); +// connectingState.notifier = std::make_unique(connection->socket(), QSocketNotifier::Write); +// connect(connectingState.notifier.get(), &QSocketNotifier::activated, this, &MainWindow::socket_activate_connect); +// } +//} -void MainWindow::performQuery() -{ - ui->ResultView->setModel(nullptr); - resultModel.reset(); - ui->messagesEdit->clear(); +//void MainWindow::performQuery() +//{ +// ui->ResultView->setModel(nullptr); +// resultModel.reset(); +// ui->messagesEdit->clear(); - queryCancel = std::move(connection->getCancel()); +// queryCancel = std::move(connection->getCancel()); - QString command = ui->queryEdit->toPlainText(); +// QString command = ui->queryEdit->toPlainText(); - std::thread([this,command]() - { - auto res = std::make_shared(connection->query(command)); - QueueTask([this, res]() { query_ready(std::move(*res)); }); - }).detach(); -} +// std::thread([this,command]() +// { +// auto res = std::make_shared(connection->query(command)); +// QueueTask([this, res]() { query_ready(std::move(*res)); }); +// }).detach(); +//} -void MainWindow::query_ready(Pgsql::Result dbres) -{ - if (dbres) { - auto st = dbres.resultStatus(); - if (st == PGRES_TUPLES_OK) { - resultModel.reset(new QueryResultModel(nullptr , std::move(dbres))); - ui->ResultView->setModel(resultModel.get()); - statusBar()->showMessage(tr("Query ready.")); - } - else { - if (st == PGRES_EMPTY_QUERY) { - statusBar()->showMessage(tr("Empty query.")); - } - else if (st == PGRES_COMMAND_OK) { - statusBar()->showMessage(tr("Command OK.")); - } - else if (st == PGRES_COPY_OUT) { - statusBar()->showMessage(tr("COPY OUT.")); - } - else if (st == PGRES_COPY_IN) { - statusBar()->showMessage(tr("COPY IN.")); - } - else if (st == PGRES_BAD_RESPONSE) { - statusBar()->showMessage(tr("BEAD RESPONSE.")); - } - else if (st == PGRES_NONFATAL_ERROR) { - statusBar()->showMessage(tr("NON FATAL ERROR.")); - } - else if (st == PGRES_FATAL_ERROR) { - statusBar()->showMessage(tr("FATAL ERROR.")); - } - else if (st == PGRES_COPY_BOTH) { - statusBar()->showMessage(tr("COPY BOTH shouldn't happen is for replication.")); - } - else if (st == PGRES_SINGLE_TUPLE) { - statusBar()->showMessage(tr("SINGLE TUPLE result.")); - } - else { - statusBar()->showMessage(tr("No tuples returned, possibly an error...")); - } - receiveNotice(dbres.diagDetails()); - } - } - else { - statusBar()->showMessage(tr("Query cancelled.")); - } -} +//void MainWindow::query_ready(Pgsql::Result dbres) +//{ +// if (dbres) { +// auto st = dbres.resultStatus(); +// if (st == PGRES_TUPLES_OK) { +// resultModel.reset(new QueryResultModel(nullptr , std::move(dbres))); +// ui->ResultView->setModel(resultModel.get()); +// statusBar()->showMessage(tr("Query ready.")); +// } +// else { +// if (st == PGRES_EMPTY_QUERY) { +// statusBar()->showMessage(tr("Empty query.")); +// } +// else if (st == PGRES_COMMAND_OK) { +// statusBar()->showMessage(tr("Command OK.")); +// } +// else if (st == PGRES_COPY_OUT) { +// statusBar()->showMessage(tr("COPY OUT.")); +// } +// else if (st == PGRES_COPY_IN) { +// statusBar()->showMessage(tr("COPY IN.")); +// } +// else if (st == PGRES_BAD_RESPONSE) { +// statusBar()->showMessage(tr("BEAD RESPONSE.")); +// } +// else if (st == PGRES_NONFATAL_ERROR) { +// statusBar()->showMessage(tr("NON FATAL ERROR.")); +// } +// else if (st == PGRES_FATAL_ERROR) { +// statusBar()->showMessage(tr("FATAL ERROR.")); +// } +// else if (st == PGRES_COPY_BOTH) { +// statusBar()->showMessage(tr("COPY BOTH shouldn't happen is for replication.")); +// } +// else if (st == PGRES_SINGLE_TUPLE) { +// statusBar()->showMessage(tr("SINGLE TUPLE result.")); +// } +// else { +// statusBar()->showMessage(tr("No tuples returned, possibly an error...")); +// } +// receiveNotice(dbres.diagDetails()); +// } +// } +// else { +// statusBar()->showMessage(tr("Query cancelled.")); +// } +//} -void MainWindow::performExplain() -{ - ui->ResultView->setModel(nullptr); - resultModel.reset(); - ui->messagesEdit->clear(); +//void MainWindow::performExplain() +//{ +// ui->ResultView->setModel(nullptr); +// resultModel.reset(); +// ui->messagesEdit->clear(); - queryCancel = std::move(connection->getCancel()); +// queryCancel = std::move(connection->getCancel()); - QString command = "EXPLAIN (ANALYZE, VERBOSE, BUFFERS, FORMAT JSON) "; - command += ui->queryEdit->toPlainText(); -// explainFuture = std::async(std::launch::async, [this,command]()-> std::unique_ptr - std::thread([this,command]() - { - std::shared_ptr explain; - auto res = connection->query(command); - if (res.getCols() == 1 && res.getRows() == 1) { - std::string s = res.getVal(0, 0); - Json::Value root; // will contains the root value after parsing. - Json::Reader reader; - bool parsingSuccessful = reader.parse(s, root); - if (parsingSuccessful) { - explain = ExplainRoot::createFromJson(root); - } - } - QueueTask([this, explain]() { explain_ready(explain); }); - }).detach(); -} +// QString command = "EXPLAIN (ANALYZE, VERBOSE, BUFFERS, FORMAT JSON) "; +// command += ui->queryEdit->toPlainText(); +//// explainFuture = std::async(std::launch::async, [this,command]()-> std::unique_ptr +// std::thread([this,command]() +// { +// std::shared_ptr explain; +// auto res = connection->query(command); +// if (res.getCols() == 1 && res.getRows() == 1) { +// std::string s = res.getVal(0, 0); +// Json::Value root; // will contains the root value after parsing. +// Json::Reader reader; +// bool parsingSuccessful = reader.parse(s, root); +// if (parsingSuccessful) { +// explain = ExplainRoot::createFromJson(root); +// } +// } +// QueueTask([this, explain]() { explain_ready(explain); }); +// }).detach(); +//} -void MainWindow::explain_ready(ExplainRoot::SPtr explain) -{ - if (explain) { - explainModel.reset(new QueryExplainModel(nullptr, explain)); - ui->explainTreeView->setModel(explainModel.get()); - ui->explainTreeView->expandAll(); - ui->explainTreeView->setColumnWidth(0, 200); - ui->explainTreeView->setColumnWidth(1, 80); - ui->explainTreeView->setColumnWidth(2, 80); - ui->explainTreeView->setColumnWidth(3, 80); - ui->explainTreeView->setColumnWidth(4, 80); - ui->explainTreeView->setColumnWidth(5, 80); - ui->explainTreeView->setColumnWidth(6, 600); - statusBar()->showMessage(tr("Explain ready.")); - } - else { - statusBar()->showMessage(tr("Explain failed.")); - } -} +//void MainWindow::explain_ready(ExplainRoot::SPtr explain) +//{ +// if (explain) { +// explainModel.reset(new QueryExplainModel(nullptr, explain)); +// ui->explainTreeView->setModel(explainModel.get()); +// ui->explainTreeView->expandAll(); +// ui->explainTreeView->setColumnWidth(0, 200); +// ui->explainTreeView->setColumnWidth(1, 80); +// ui->explainTreeView->setColumnWidth(2, 80); +// ui->explainTreeView->setColumnWidth(3, 80); +// ui->explainTreeView->setColumnWidth(4, 80); +// ui->explainTreeView->setColumnWidth(5, 80); +// ui->explainTreeView->setColumnWidth(6, 600); +// statusBar()->showMessage(tr("Explain ready.")); +// } +// else { +// statusBar()->showMessage(tr("Explain failed.")); +// } +//} -void MainWindow::cancel_query() -{ - queryCancel.cancel(); -} +//void MainWindow::cancel_query() +//{ +// queryCancel.cancel(); +//} -void MainWindow::processNotice(const PGresult *result) -{ - qRegisterMetaType("Pgsql::ErrorDetails"); - pg::ErrorDetails details = pg::ErrorDetails::createErrorDetailsFromPGresult(result); - QMetaObject::invokeMethod(this, "receiveNotice", Qt::AutoConnection, Q_ARG(Pgsql::ErrorDetails, details)); // queues on main thread -} +//void MainWindow::processNotice(const PGresult *result) +//{ +// qRegisterMetaType("Pgsql::ErrorDetails"); +// pg::ErrorDetails details = pg::ErrorDetails::createErrorDetailsFromPGresult(result); +// QMetaObject::invokeMethod(this, "receiveNotice", Qt::AutoConnection, Q_ARG(Pgsql::ErrorDetails, details)); // queues on main thread +//} -void MainWindow::receiveNotice(Pgsql::ErrorDetails notice) -{ - QTextCursor cursor = ui->messagesEdit->textCursor(); - cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); +//void MainWindow::receiveNotice(Pgsql::ErrorDetails notice) +//{ +// QTextCursor cursor = ui->messagesEdit->textCursor(); +// cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); -// QString msg; -// cursor.insertText("TEST\r\n"); +//// QString msg; +//// cursor.insertText("TEST\r\n"); - QTextTable *table = cursor.insertTable(4, 2); - if (table) { - table->cellAt(1, 0).firstCursorPosition().insertText("State"); - table->cellAt(1, 1).firstCursorPosition().insertText(QString::fromStdString(notice.state)); - table->cellAt(2, 0).firstCursorPosition().insertText("Primary"); - table->cellAt(2, 1).firstCursorPosition().insertText(QString::fromStdString(notice.messagePrimary)); - table->cellAt(3, 0).firstCursorPosition().insertText("Detail"); - table->cellAt(3, 1).firstCursorPosition().insertText(QString::fromStdString(notice.messageDetail)); - } -} +// QTextTable *table = cursor.insertTable(4, 2); +// if (table) { +// table->cellAt(1, 0).firstCursorPosition().insertText("State"); +// table->cellAt(1, 1).firstCursorPosition().insertText(QString::fromStdString(notice.state)); +// table->cellAt(2, 0).firstCursorPosition().insertText("Primary"); +// table->cellAt(2, 1).firstCursorPosition().insertText(QString::fromStdString(notice.messagePrimary)); +// table->cellAt(3, 0).firstCursorPosition().insertText("Detail"); +// table->cellAt(3, 1).firstCursorPosition().insertText(QString::fromStdString(notice.messageDetail)); +// } +//} diff --git a/mainwindow.h b/mainwindow.h index 43c036c..efdd7b8 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -1,6 +1,7 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H +#include "asyncdbconnection.h" #include "tsqueue.h" #include #include @@ -52,36 +53,35 @@ private: std::unique_ptr ui; std::unique_ptr highlighter; - std::unique_ptr connection; - std::unique_ptr resultModel; - std::unique_ptr explainModel; + ASyncDBConnection m_dbConnection; - Pgsql::Canceller queryCancel; + void connectionStateChanged(ASyncDBConnection::State state); +// std::unique_ptr connection; +// std::unique_ptr resultModel; +// std::unique_ptr explainModel; + +// Pgsql::Canceller queryCancel; - struct { - std::unique_ptr notifier; - PostgresPollingStatusType poll_state; - } connectingState; // struct { -// std::unique_ptr notifierRead; -// std::unique_ptr notifierWrite; -// } queryState; +// std::unique_ptr notifier; +// PostgresPollingStatusType poll_state; +// } connectingState; - void processNotice(const PGresult *result); - void query_ready(Pgsql::Result res); - void explain_ready(std::shared_ptr explain); +// void processNotice(const PGresult *result); +// void query_ready(Pgsql::Result res); +// void explain_ready(std::shared_ptr explain); private slots: void startConnect(); - void performQuery(); - void performExplain(); - void socket_activate_connect(int socket); +// void performQuery(); +// void performExplain(); +// void socket_activate_connect(int socket); - void cancel_query(); - void receiveNotice(Pgsql::ErrorDetails notice); +// void cancel_query(); +// void receiveNotice(Pgsql::ErrorDetails notice); void processCallableQueue(); }; diff --git a/tsqueue.cpp b/tsqueue.cpp index 0c5b3d3..9200692 100644 --- a/tsqueue.cpp +++ b/tsqueue.cpp @@ -8,7 +8,7 @@ void TSQueue::add(t_Callable callable) { std::lock_guard g(m); futureQueue.push_back(std::move(callable)); - newData.Set(); + newData.set(); } bool TSQueue::empty() @@ -23,12 +23,12 @@ TSQueue::t_Callable TSQueue::pop() auto f = std::move(futureQueue.front()); futureQueue.pop_front(); if (futureQueue.empty()) { - newData.Reset(); + newData.reset(); } return f; } HANDLE TSQueue::getNewDataEventHandle() { - return newData.GetHandle(); + return newData.handle(); }