Can use the parameter list in the query window now.
Still requires extensive testing for all possible types.
This commit is contained in:
parent
aefc9eb7ba
commit
3af26d915e
14 changed files with 461 additions and 242 deletions
|
|
@ -51,6 +51,16 @@ bool ASyncDBConnection::send(const std::string &command, on_result_callback on_r
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ASyncDBConnection::send(const std::string &command, Pgsql::Params params, on_result_callback on_result)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lg(m_threadData.m_commandQueue.m_mutex);
|
||||
m_threadData.m_commandQueue.m_queue.emplace(command, std::move(params), on_result);
|
||||
m_threadData.m_commandQueue.m_newEvent.set();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ASyncDBConnection::cancel()
|
||||
{
|
||||
return m_threadData.cancel();
|
||||
|
|
@ -243,21 +253,29 @@ void ASyncDBConnection::Thread::doNewCommand()
|
|||
{
|
||||
// todo: send command
|
||||
// get command from top of queue (but leave it in the queue, we need the callback)
|
||||
std::string command;
|
||||
{
|
||||
std::lock_guard<std::mutex> lg(m_commandQueue.m_mutex);
|
||||
if (! m_commandQueue.m_queue.empty()) {
|
||||
command = m_commandQueue.m_queue.front().command;
|
||||
const Command &command = m_commandQueue.m_queue.front();
|
||||
if (!command.command.empty()) {
|
||||
bool query_send = false;
|
||||
if (command.params.empty())
|
||||
query_send = m_connection.sendQuery(command.command.c_str());
|
||||
else
|
||||
query_send = m_connection.sendQueryParams(command.command.c_str(), command.params);
|
||||
|
||||
if (query_send) {
|
||||
m_timer.start();
|
||||
doStateCallback(State::QuerySend);
|
||||
}
|
||||
else {
|
||||
std::string error = m_connection.getErrorMessage();
|
||||
// todo: need to report the error
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!command.empty() && m_connection.sendQuery(command)) {
|
||||
m_timer.start();
|
||||
doStateCallback(State::QuerySend);
|
||||
}
|
||||
else {
|
||||
std::string error = m_connection.getErrorMessage();
|
||||
// todo: need to report the error
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ASyncDBConnection::Thread::waitForResult()
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define ASYNCDBCONNECTION_H
|
||||
|
||||
#include "PgsqlConn.h"
|
||||
#include "Pgsql_Params.h"
|
||||
#include "win32event.h"
|
||||
#include "connectionconfig.h"
|
||||
#include <QElapsedTimer>
|
||||
|
|
@ -48,6 +49,7 @@ public:
|
|||
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();
|
||||
|
||||
|
|
@ -56,12 +58,16 @@ private:
|
|||
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
|
||||
|
|
|
|||
|
|
@ -11,12 +11,13 @@ QVariant ParamListModel::headerData(int section, Qt::Orientation orientation, in
|
|||
QVariant result;
|
||||
if (orientation == Qt::Horizontal) {
|
||||
if (role == Qt::DisplayRole) {
|
||||
if (section == 0) {
|
||||
// result = tr("$n");
|
||||
switch (section) {
|
||||
case ColValue:
|
||||
result = tr("Value");
|
||||
}
|
||||
else if (section == 1) {
|
||||
break;
|
||||
case ColType:
|
||||
result = tr("Type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -39,20 +40,14 @@ QVariant ParamListModel::headerData(int section, Qt::Orientation orientation, in
|
|||
//}
|
||||
|
||||
|
||||
int ParamListModel::rowCount(const QModelIndex &parent) const
|
||||
int ParamListModel::rowCount(const QModelIndex &) const
|
||||
{
|
||||
//if (parent.isValid())
|
||||
return 2;
|
||||
|
||||
// FIXME: Implement me!
|
||||
return m_paramList.size();
|
||||
}
|
||||
|
||||
int ParamListModel::columnCount(const QModelIndex &parent) const
|
||||
int ParamListModel::columnCount(const QModelIndex &) const
|
||||
{
|
||||
//if (parent.isValid())
|
||||
return 2;
|
||||
|
||||
// FIXME: Implement me!
|
||||
return ColumnCount;
|
||||
}
|
||||
|
||||
QVariant ParamListModel::data(const QModelIndex &index, int role) const
|
||||
|
|
@ -62,28 +57,40 @@ QVariant ParamListModel::data(const QModelIndex &index, int role) const
|
|||
int row = index.row();
|
||||
int col = index.column();
|
||||
if (role == Qt::DisplayRole) {
|
||||
const auto& record = m_paramList[row];
|
||||
switch (col) {
|
||||
case 0: // value column
|
||||
result = tr("val, %1").arg(row);
|
||||
case ColValue: // value column
|
||||
result = record.value; // tr("val, %1").arg(row);
|
||||
break;
|
||||
case 1: // type column
|
||||
result = tr("type, %1").arg(row);
|
||||
case ColType: // type column
|
||||
result = record.type; // tr("type, %1").arg(row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Implement me!
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ParamListModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (data(index, role) != value) {
|
||||
// // FIXME: Implement me!
|
||||
if (role == Qt::EditRole) {
|
||||
int row = index.row();
|
||||
int col = index.column();
|
||||
auto& record = m_paramList[row];
|
||||
switch (col) {
|
||||
case ColValue:
|
||||
record.value = value.toString();
|
||||
break;
|
||||
case ColType:
|
||||
record.type = value.toString();
|
||||
break;
|
||||
}
|
||||
|
||||
emit dataChanged(index, index, QVector<int>() << role);
|
||||
return true;
|
||||
emit dataChanged(index, index, QVector<int>() << role);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -93,16 +100,18 @@ Qt::ItemFlags ParamListModel::flags(const QModelIndex &index) const
|
|||
if (!index.isValid())
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsEditable; // FIXME: Implement me!
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsEditable;
|
||||
}
|
||||
|
||||
//bool ParamListModel::insertRows(int row, int count, const QModelIndex &parent)
|
||||
//{
|
||||
// beginInsertRows(parent, row, row + count - 1);
|
||||
// // FIXME: Implement me!
|
||||
// endInsertRows();
|
||||
// return false;
|
||||
//}
|
||||
bool ParamListModel::insertRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
beginInsertRows(parent, row, row + count - 1);
|
||||
// FIXME: Implement me!
|
||||
auto iter = m_paramList.begin() + row;
|
||||
m_paramList.insert(iter, count, Param());
|
||||
endInsertRows();
|
||||
return true;
|
||||
}
|
||||
|
||||
//bool ParamListModel::insertColumns(int column, int count, const QModelIndex &parent)
|
||||
//{
|
||||
|
|
@ -111,13 +120,14 @@ Qt::ItemFlags ParamListModel::flags(const QModelIndex &index) const
|
|||
// endInsertColumns();
|
||||
//}
|
||||
|
||||
//bool ParamListModel::removeRows(int row, int count, const QModelIndex &parent)
|
||||
//{
|
||||
// beginRemoveRows(parent, row, row + count - 1);
|
||||
// // FIXME: Implement me!
|
||||
// endRemoveRows();
|
||||
// return false;
|
||||
//}
|
||||
bool ParamListModel::removeRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
beginRemoveRows(parent, row, row + count - 1);
|
||||
auto iter = m_paramList.begin() + row;
|
||||
m_paramList.erase(iter, iter + count);
|
||||
endRemoveRows();
|
||||
return true;
|
||||
}
|
||||
|
||||
//bool ParamListModel::removeColumns(int column, int count, const QModelIndex &parent)
|
||||
//{
|
||||
|
|
|
|||
|
|
@ -2,12 +2,29 @@
|
|||
#define PARAMLISTMODEL_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <vector>
|
||||
#include "Pgsql_declare.h"
|
||||
|
||||
class ParamListModel : public QAbstractTableModel
|
||||
{
|
||||
class ParamListModel : public QAbstractTableModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
class Param {
|
||||
public:
|
||||
QString value; ///< the value of the parameter (currently this is passed directly)
|
||||
QString type = InvalidOid; ///< the type of the parameter
|
||||
|
||||
Param() = default;
|
||||
Param(const QString &v, const QString t)
|
||||
: value(v), type(t)
|
||||
{}
|
||||
};
|
||||
|
||||
enum e_Column {
|
||||
ColValue = 0,
|
||||
ColType,
|
||||
ColumnCount // Keep last not a column just the count
|
||||
};
|
||||
|
||||
explicit ParamListModel(QObject *parent = 0);
|
||||
|
||||
// Header:
|
||||
|
|
@ -26,16 +43,15 @@ public:
|
|||
int role = Qt::EditRole) override;
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
|
||||
// Add data:
|
||||
// bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
//bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
|
||||
// Remove data:
|
||||
// bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
//bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
|
||||
auto begin() const { return m_paramList.begin(); }
|
||||
auto end() const { return m_paramList.end(); }
|
||||
private:
|
||||
|
||||
using t_ParamList = std::vector<Param>;
|
||||
t_ParamList m_paramList;
|
||||
};
|
||||
|
||||
#endif // PARAMLISTMODEL_H
|
||||
|
|
|
|||
|
|
@ -33,3 +33,67 @@ QWidget *ParamTypeDelegate::createEditor(QWidget *parent,
|
|||
|
||||
return w;
|
||||
}
|
||||
|
||||
void ParamTypeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
|
||||
{
|
||||
// if (index.data().canConvert<StarRating>()) {
|
||||
// StarRating starRating = qvariant_cast<StarRating>(index.data());
|
||||
// StarEditor *starEditor = qobject_cast<StarEditor *>(editor);
|
||||
// starEditor->setStarRating(starRating);
|
||||
// } else {
|
||||
// QStyledItemDelegate::setEditorData(editor, index);
|
||||
// }
|
||||
if (index.column() == 1) {
|
||||
QComboBox *cmbbx = dynamic_cast<QComboBox*>(editor);
|
||||
if (cmbbx) {
|
||||
auto data = index.data();
|
||||
if (data.canConvert<QString>()) {
|
||||
QModelIndexList indexes = m_typeSelectionModel->match(
|
||||
m_typeSelectionModel->index(0, 1), Qt::DisplayRole, data, 1, Qt::MatchFlags( Qt::MatchExactly ));
|
||||
if (!indexes.empty()) {
|
||||
cmbbx->setCurrentIndex(indexes.at(0).row());
|
||||
}
|
||||
else {
|
||||
cmbbx->setCurrentIndex(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
QStyledItemDelegate::setEditorData(editor, index);
|
||||
}
|
||||
}
|
||||
|
||||
void ParamTypeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
// if (index.data().canConvert<StarRating>()) {
|
||||
// StarEditor *starEditor = qobject_cast<StarEditor *>(editor);
|
||||
// model->setData(index, QVariant::fromValue(starEditor->starRating()));
|
||||
// } else {
|
||||
// QStyledItemDelegate::setModelData(editor, model, index);
|
||||
// }
|
||||
if (index.column() == 1) {
|
||||
QComboBox *cmbbx = dynamic_cast<QComboBox*>(editor);
|
||||
if (cmbbx) {
|
||||
auto data = index.data();
|
||||
if (data.canConvert<QString>()) {
|
||||
QVariant d = m_typeSelectionModel->data(
|
||||
m_typeSelectionModel->index(cmbbx->currentIndex(), 0));
|
||||
model->setData(index, d);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
QStyledItemDelegate::setModelData(editor, model, index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// triggered by editing finished from editor
|
||||
void ParamTypeDelegate::commitAndCloseEditor()
|
||||
{
|
||||
// StarEditor *editor = qobject_cast<StarEditor *>(sender());
|
||||
// emit commitData(editor);
|
||||
// emit closeEditor(editor);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,7 @@ class TypeSelectionItemModel;
|
|||
/** Item delegate for supplying a combobox for selected the parameter type in
|
||||
* the parameter list.
|
||||
*/
|
||||
class ParamTypeDelegate : public QStyledItemDelegate
|
||||
{
|
||||
class ParamTypeDelegate : public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ParamTypeDelegate();
|
||||
|
|
@ -18,8 +17,14 @@ public:
|
|||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
void setTypeSelectionModel(TypeSelectionItemModel* model);
|
||||
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
|
||||
void setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||
const QModelIndex &index) const override;
|
||||
private:
|
||||
TypeSelectionItemModel* m_typeSelectionModel = nullptr;
|
||||
|
||||
private slots:
|
||||
void commitAndCloseEditor();
|
||||
};
|
||||
|
||||
#endif // PARAMTYPEDELEGATE_H
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "PgsqlConn.h"
|
||||
#include "Pgsql_declare.h"
|
||||
#include "Pgsql_Params.h"
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
|
|
@ -158,6 +159,15 @@ bool Connection::sendQuery(const char *query)
|
|||
return res == 1;
|
||||
}
|
||||
|
||||
bool Connection::sendQueryParams(const char * command, const Params ¶ms)
|
||||
{
|
||||
int res = PQsendQueryParams(conn, command, params.size(), params.types(),
|
||||
params.values(), params.lengths(), params.formats(),
|
||||
0); // text format
|
||||
|
||||
return res == 1;
|
||||
}
|
||||
|
||||
std::shared_ptr<Result> Connection::getResult()
|
||||
{
|
||||
PGresult *r = PQgetResult(conn);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ namespace Pgsql {
|
|||
|
||||
|
||||
class Result;
|
||||
class Params;
|
||||
|
||||
|
||||
|
||||
|
|
@ -126,6 +127,8 @@ namespace Pgsql {
|
|||
return sendQuery(command.toUtf8().data());
|
||||
}
|
||||
|
||||
bool sendQueryParams(const char * command, const Params ¶ms);
|
||||
|
||||
std::shared_ptr<Result> getResult();
|
||||
|
||||
bool consumeInput();
|
||||
|
|
|
|||
|
|
@ -25,12 +25,26 @@ Params& Params::operator=(const Params& rhs)
|
|||
return *this;
|
||||
}
|
||||
|
||||
Params::Params(const Params&& rhs)
|
||||
Params::Params(Params&& rhs)
|
||||
: m_paramTypes(std::move(rhs.m_paramTypes))
|
||||
, m_paramValues(std::move(rhs.m_paramValues))
|
||||
, m_paramLengths(std::move(rhs.m_paramLengths))
|
||||
, m_paramFormats(std::move(rhs.m_paramFormats))
|
||||
{}
|
||||
{
|
||||
//rhs.m_paramValues.clear(); // make sure origin is empty, to prevent double deletion
|
||||
}
|
||||
|
||||
Params& Params::operator=(Params&& rhs)
|
||||
{
|
||||
if (&rhs != this) {
|
||||
m_paramTypes = std::move(rhs.m_paramTypes);
|
||||
m_paramValues = std::move(rhs.m_paramValues);
|
||||
//rhs.m_paramValues.clear(); // make sure origin is empty, to prevent double deletion
|
||||
m_paramLengths = std::move(rhs.m_paramLengths);
|
||||
m_paramFormats = std::move(rhs.m_paramFormats);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Params::~Params()
|
||||
{
|
||||
|
|
@ -49,8 +63,9 @@ void Params::add(const QString &s, Oid oid)
|
|||
{
|
||||
auto ba = s.toUtf8();
|
||||
const int len = ba.size();
|
||||
char * p = new char[len];
|
||||
char * p = new char[len+1];
|
||||
std::memcpy(p, ba.data(), len);
|
||||
p[len] = 0;
|
||||
addText(p, oid);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ namespace Pgsql {
|
|||
Params();
|
||||
Params(const Params& rhs);
|
||||
Params& operator=(const Params& rhs);
|
||||
Params(const Params&& rhs);
|
||||
Params(Params&& rhs);
|
||||
Params& operator=(Params&& rhs);
|
||||
~Params();
|
||||
|
||||
|
||||
|
|
@ -26,6 +27,14 @@ namespace Pgsql {
|
|||
void addBinary(const char *data, int length, Oid oid);
|
||||
void clear();
|
||||
|
||||
bool empty() const { return m_paramTypes.empty(); }
|
||||
int size() const { return m_paramTypes.size(); }
|
||||
|
||||
const Oid* types() const { return m_paramTypes.data(); }
|
||||
const char* const* values() const { return m_paramValues.data(); }
|
||||
const int* lengths() const { return m_paramLengths.data(); }
|
||||
const int* formats() const { return m_paramFormats.data(); }
|
||||
|
||||
private:
|
||||
using t_paramValues = std::vector<const char *>;
|
||||
|
||||
|
|
|
|||
118
src/QueryTab.cpp
118
src/QueryTab.cpp
|
|
@ -4,6 +4,7 @@
|
|||
#include "SqlSyntaxHighlighter.h"
|
||||
|
||||
#include <QStandardPaths>
|
||||
#include <QPushButton>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QTabWidget>
|
||||
|
|
@ -19,6 +20,44 @@
|
|||
#include "pgsqldatabasecatalogue.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
QueryParamListController::QueryParamListController(QTableView *tv,
|
||||
OpenDatabase *opendb, QWidget *parent)
|
||||
: QObject(parent)
|
||||
, paramTableView(tv)
|
||||
, m_openDatabase(opendb)
|
||||
{
|
||||
m_typeDelegate.setTypeSelectionModel(opendb->typeSelectionModel());
|
||||
|
||||
paramTableView->setModel(&m_paramList);
|
||||
paramTableView->setItemDelegateForColumn(1, &m_typeDelegate);
|
||||
}
|
||||
|
||||
Pgsql::Params QueryParamListController::params() const
|
||||
{
|
||||
Pgsql::Params params;
|
||||
auto types = m_openDatabase->catalogue()->types();
|
||||
for (auto e : m_paramList) {
|
||||
Oid oid = types->getByName(e.type).oid;
|
||||
params.add(e.value, oid);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
void QueryParamListController::on_addParam()
|
||||
{
|
||||
m_paramList.insertRows(m_paramList.rowCount(), 1);
|
||||
}
|
||||
|
||||
void QueryParamListController::on_removeParam()
|
||||
{
|
||||
auto rc = m_paramList.rowCount();
|
||||
if (rc > 0)
|
||||
m_paramList.removeRows(rc-1, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
QueryTab::QueryTab(MainWindow *win, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::QueryTab),
|
||||
|
|
@ -43,20 +82,16 @@ QueryTab::QueryTab(MainWindow *win, QWidget *parent) :
|
|||
ui->queryEdit->setFont(font);
|
||||
|
||||
OpenDatabase* open_database = m_win->getDatabase();
|
||||
m_typeDelegate.setTypeSelectionModel(open_database->typeSelectionModel());
|
||||
|
||||
auto cat = open_database->catalogue();
|
||||
|
||||
highlighter = new SqlSyntaxHighlighter(ui->queryEdit->document());
|
||||
highlighter->setTypes(cat->types());
|
||||
|
||||
ui->paramTableView->setModel(&m_paramList);
|
||||
ui->paramTableView->setItemDelegateForColumn(1, &m_typeDelegate);
|
||||
|
||||
connect(ui->queryEdit, &QPlainTextEdit::textChanged, this, &QueryTab::queryTextChanged);
|
||||
// m_stopwatch.setOutputLabel(ui->lblElapsedTime);
|
||||
// ui->lblElapsedTime->clear();
|
||||
// ui->lblRowCount->clear();
|
||||
|
||||
m_queryParamListController = new QueryParamListController(ui->paramTableView, open_database, this);
|
||||
connect(ui->addButton, &QPushButton::clicked, m_queryParamListController, &QueryParamListController::on_addParam);
|
||||
connect(ui->removeButton, &QPushButton::clicked, m_queryParamListController, &QueryParamListController::on_removeParam);
|
||||
}
|
||||
|
||||
QueryTab::~QueryTab()
|
||||
|
|
@ -64,16 +99,12 @@ QueryTab::~QueryTab()
|
|||
m_dbConnection.closeConnection();
|
||||
m_dbConnection.setStateCallback(nullptr);
|
||||
|
||||
// delete m_pgTypes;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void QueryTab::setConfig(const ConnectionConfig &config)
|
||||
{
|
||||
m_config = config;
|
||||
// QString title = "pglab - ";
|
||||
// title += m_config.name().c_str();
|
||||
// setWindowTitle(title);
|
||||
m_win->QueueTask([this]() { startConnect(); });
|
||||
}
|
||||
|
||||
|
|
@ -89,30 +120,6 @@ bool QueryTab::canClose()
|
|||
return can_close;
|
||||
}
|
||||
|
||||
//void QueryTab::open()
|
||||
//{
|
||||
// if (m_queryTextChanged && !continueWithoutSavingWarning()) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// QString home_dir = QStandardPaths::locate(QStandardPaths::HomeLocation, "", QStandardPaths::LocateDirectory);
|
||||
// QString file_name = QFileDialog::getOpenFileName(this,
|
||||
// tr("Open sql query"), home_dir, tr("SQL files (*.sql *.txt)"));
|
||||
// if ( ! file_name.isEmpty()) {
|
||||
// QFile file(file_name);
|
||||
// if (file.open(QIODevice::ReadWrite)) {
|
||||
// QTextStream stream(&file);
|
||||
// ui->queryEdit->clear();
|
||||
// while (!stream.atEnd()){
|
||||
// QString line = stream.readLine();
|
||||
// ui->queryEdit->appendPlainText(line);
|
||||
// }
|
||||
// m_queryTextChanged = false;
|
||||
// setFileName(file_name);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
void QueryTab::newdoc()
|
||||
{
|
||||
ui->queryEdit->clear();
|
||||
|
|
@ -183,6 +190,7 @@ void QueryTab::execute()
|
|||
std::string cmd = getCommand();
|
||||
m_stopwatch.start();
|
||||
m_dbConnection.send(cmd,
|
||||
m_queryParamListController->params(),
|
||||
[this](std::shared_ptr<Pgsql::Result> res, qint64 elapsedms)
|
||||
{
|
||||
m_win->QueueTask([this, res, elapsedms]() { query_ready(res, elapsedms); });
|
||||
|
|
@ -295,26 +303,6 @@ void QueryTab::queryTextChanged()
|
|||
|
||||
void QueryTab::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;
|
||||
// }
|
||||
// addLog(status_str);
|
||||
|
||||
QTabWidget *tabwidget = getTabWidget();
|
||||
if (tabwidget) {
|
||||
int i = tabwidget->indexOf(this);
|
||||
|
|
@ -334,13 +322,6 @@ void QueryTab::connectionStateChanged(ASyncDBConnection::State state)
|
|||
}
|
||||
tabwidget->setTabIcon(i, QIcon(iconname));
|
||||
}
|
||||
|
||||
// statusBar()->showMessage(status_str);
|
||||
|
||||
// bool connected = ASyncDBConnection::State::Connected == state;
|
||||
// ui->actionExecute_SQL->setEnabled(connected);
|
||||
// ui->actionExplain_Analyze->setEnabled(connected);
|
||||
// ui->actionCancel->setEnabled(ASyncDBConnection::State::QuerySend == state);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -488,16 +469,9 @@ void QueryTab::query_ready(std::shared_ptr<Pgsql::Result> dbres, qint64 elapsedm
|
|||
if (resultList.size() == 1)
|
||||
ui->tabWidget->setCurrentWidget(trw);
|
||||
|
||||
|
||||
// ui->lblRowCount->setText(rowcount_str);
|
||||
// resultModel.reset(new QueryResultModel(nullptr , dbres));
|
||||
// ui->ResultView->setModel(resultModel.get());
|
||||
// ui->tabWidget->setCurrentWidget(ui->dataTab);
|
||||
//statusBar()->showMessage(tr("Query ready."));
|
||||
}
|
||||
else {
|
||||
if (st == PGRES_COMMAND_OK) {
|
||||
// statusBar()->showMessage(tr("Command OK."));
|
||||
int tuples_affected = dbres->tuplesAffected();
|
||||
QString msg;
|
||||
if (tuples_affected >= 0)
|
||||
|
|
@ -548,18 +522,14 @@ void QueryTab::query_ready(std::shared_ptr<Pgsql::Result> dbres, qint64 elapsedm
|
|||
else {
|
||||
m_stopwatch.stop();
|
||||
addLog("query_ready with NO result");
|
||||
// statusBar()->showMessage(tr("Query cancelled."));
|
||||
}
|
||||
}
|
||||
|
||||
void QueryTab::clearResult()
|
||||
{
|
||||
// ui->ResultView->setModel(nullptr);
|
||||
// resultModel.reset();
|
||||
for (auto e : resultList)
|
||||
delete e;
|
||||
resultList.clear();
|
||||
// ui->lblRowCount->clear();
|
||||
}
|
||||
|
||||
void QueryTab::copyQueryAsCString()
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ namespace Ui {
|
|||
class QueryTab;
|
||||
}
|
||||
|
||||
class QTableView;
|
||||
|
||||
class QTabWidget;
|
||||
class MainWindow;
|
||||
class SqlSyntaxHighlighter;
|
||||
|
|
@ -23,14 +25,29 @@ class ExplainRoot;
|
|||
class QueryResultModel;
|
||||
class QueryExplainModel;
|
||||
class PgTypeContainer;
|
||||
class OpenDatabase;
|
||||
|
||||
|
||||
class QueryTab : public QWidget
|
||||
{
|
||||
class QueryParamListController : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QueryTab(MainWindow *win, QWidget *parent = 0);
|
||||
QueryParamListController(QTableView *tv, OpenDatabase *opendb, QWidget *parent);
|
||||
|
||||
Pgsql::Params params() const;
|
||||
public slots:
|
||||
void on_addParam();
|
||||
void on_removeParam();
|
||||
private:
|
||||
QTableView *paramTableView;
|
||||
OpenDatabase *m_openDatabase;
|
||||
ParamListModel m_paramList;
|
||||
ParamTypeDelegate m_typeDelegate;
|
||||
};
|
||||
|
||||
|
||||
class QueryTab : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
QueryTab(MainWindow *win, QWidget *parent = nullptr);
|
||||
~QueryTab();
|
||||
|
||||
void setConfig(const ConnectionConfig &config);
|
||||
|
|
@ -70,8 +87,8 @@ private:
|
|||
SqlSyntaxHighlighter* highlighter;
|
||||
ConnectionConfig m_config;
|
||||
StopWatch m_stopwatch;
|
||||
ParamListModel m_paramList;
|
||||
ParamTypeDelegate m_typeDelegate;
|
||||
|
||||
QueryParamListController *m_queryParamListController = nullptr;
|
||||
|
||||
QString m_fileName; ///< use setFileName function to set
|
||||
bool m_queryTextChanged = false;
|
||||
|
|
|
|||
268
src/QueryTab.ui
268
src/QueryTab.ui
|
|
@ -13,123 +13,199 @@
|
|||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="queryEdit"/>
|
||||
<widget class="QTableView" name="paramTableView">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="messageTab">
|
||||
<attribute name="title">
|
||||
<string>Messages</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextEdit" name="messagesEdit">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addButton">
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="removeButton">
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="explainTab">
|
||||
<attribute name="title">
|
||||
<string>Explain</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<widget class="QTreeView" name="explainTreeView">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTableView" name="paramTableView">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="uniformRowHeights">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="headerStretchLastSection">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblTimes">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="logTab">
|
||||
<attribute name="title">
|
||||
<string>Log</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="edtLog"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="messageTab">
|
||||
<attribute name="title">
|
||||
<string>Messages</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextEdit" name="messagesEdit">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="explainTab">
|
||||
<attribute name="title">
|
||||
<string>Explain</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<widget class="QTreeView" name="explainTreeView">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="uniformRowHeights">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="headerStretchLastSection">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblTimes">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="logTab">
|
||||
<attribute name="title">
|
||||
<string>Log</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="edtLog"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ QVariant TypeSelectionItemModel::data(const QModelIndex &index, int role) const
|
|||
int row = index.row();
|
||||
int column = index.column();
|
||||
if (role == Qt::DisplayRole) {
|
||||
const PgType &tp = m_types->getByIdx(row);
|
||||
if (column == 0) {
|
||||
const PgType &tp = m_types->getByIdx(row);
|
||||
result = tp.typname;
|
||||
|
||||
// switch (row) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue