The catalogue now loads the list of databases en there is a table model that can show this data.
This commit is contained in:
parent
a9430bca1a
commit
20af12535e
22 changed files with 504 additions and 118 deletions
25
src/ASyncWindow.cpp
Normal file
25
src/ASyncWindow.cpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#include "ASyncWindow.h"
|
||||
#include <QTimer>
|
||||
|
||||
ASyncWindow::ASyncWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
{}
|
||||
|
||||
void ASyncWindow::QueueTask(TSQueue::t_Callable c)
|
||||
{
|
||||
m_taskQueue.add(c);
|
||||
// Theoretically this needs to be only called if the queue was empty because otherwise it already would
|
||||
// be busy emptying the queue. For now however I think it is safer to call it just to make sure.
|
||||
QMetaObject::invokeMethod(this, "processCallableQueue", Qt::QueuedConnection); // queues on main thread
|
||||
}
|
||||
|
||||
void ASyncWindow::processCallableQueue()
|
||||
{
|
||||
if (!m_taskQueue.empty()) {
|
||||
auto c = m_taskQueue.pop();
|
||||
c();
|
||||
if (!m_taskQueue.empty()) {
|
||||
QTimer::singleShot(0, this, SLOT(processCallableQueue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
24
src/ASyncWindow.h
Normal file
24
src/ASyncWindow.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef ASYNCWINDOW_H
|
||||
#define ASYNCWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include "tsqueue.h"
|
||||
|
||||
class ASyncWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ASyncWindow(QWidget *parent);
|
||||
/* Meant to be called from other threads to pass a code block
|
||||
* that has to be executed in the context of the thread of the window.
|
||||
*/
|
||||
void QueueTask(TSQueue::t_Callable c);
|
||||
private:
|
||||
TSQueue m_taskQueue;
|
||||
private slots:
|
||||
|
||||
void processCallableQueue();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // ASYNCWINDOW_H
|
||||
117
src/DatabasesTableModel.cpp
Normal file
117
src/DatabasesTableModel.cpp
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
#include "DatabasesTableModel.h"
|
||||
#include "PgDatabaseContainer.h"
|
||||
|
||||
DatabasesTableModel::DatabasesTableModel(QObject *parent)
|
||||
: QAbstractTableModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QVariant DatabasesTableModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
QVariant v;
|
||||
if (orientation == Qt::Horizontal) {
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch (section) {
|
||||
case NameCol:
|
||||
v = tr("Name");
|
||||
break;
|
||||
case DbaCol:
|
||||
v = tr("Owner");
|
||||
break;
|
||||
case EncodingCol:
|
||||
v = tr("Encoding");
|
||||
break;
|
||||
case CollateCol:
|
||||
v = tr("Collation");
|
||||
break;
|
||||
case CTypeCol:
|
||||
v = tr("CType");
|
||||
break;
|
||||
case IsTemplateCol:
|
||||
v = tr("Is template");
|
||||
break;
|
||||
case AllowConnCol:
|
||||
v = tr("Can connect");
|
||||
break;
|
||||
case ConnLimitCol:
|
||||
v = tr("Conn. limit");
|
||||
break;
|
||||
case TablespaceCol:
|
||||
v = tr("Tablespace");
|
||||
break;
|
||||
case AclCol:
|
||||
v = tr("ACL");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
int DatabasesTableModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
int result = 0;
|
||||
if (m_databases) {
|
||||
if (parent.isValid())
|
||||
return m_databases->count();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int DatabasesTableModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
int result = 10;
|
||||
// if (parent.isValid())
|
||||
// return 10;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QVariant DatabasesTableModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
QVariant v;
|
||||
//if (!index.isValid())
|
||||
if (m_databases) {
|
||||
const PgDatabase &db = m_databases->getByIdx(index.row());
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch (index.column()) {
|
||||
case NameCol:
|
||||
v = db.name;
|
||||
break;
|
||||
case DbaCol:
|
||||
// todo lookup role name
|
||||
v = db.dba;
|
||||
break;
|
||||
case EncodingCol:
|
||||
// todo lookup encoding name
|
||||
v = db.encoding;
|
||||
break;
|
||||
case CollateCol:
|
||||
v = db.collate;
|
||||
break;
|
||||
case CTypeCol:
|
||||
v = db.ctype;
|
||||
break;
|
||||
case IsTemplateCol:
|
||||
v = db.isTemplate;
|
||||
break;
|
||||
case AllowConnCol:
|
||||
v = db.allowConn;
|
||||
break;
|
||||
case ConnLimitCol:
|
||||
v = db.connLimit;
|
||||
break;
|
||||
case TablespaceCol:
|
||||
// todo lookup tablespace name
|
||||
v = db.tablespace;
|
||||
break;
|
||||
case AclCol:
|
||||
v = db.acl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
39
src/DatabasesTableModel.h
Normal file
39
src/DatabasesTableModel.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef DATABASESTABLEMODEL_H
|
||||
#define DATABASESTABLEMODEL_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
class PgDatabaseContainer;
|
||||
|
||||
/** Class for displaying the list of databases of a server in a QTableView
|
||||
*
|
||||
*/
|
||||
class DatabasesTableModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum e_Columns : int { NameCol, DbaCol, EncodingCol, CollateCol,
|
||||
CTypeCol, IsTemplateCol, AllowConnCol, ConnLimitCol,
|
||||
TablespaceCol, AclCol };
|
||||
|
||||
|
||||
|
||||
explicit DatabasesTableModel(QObject *parent = 0);
|
||||
|
||||
// Header:
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
|
||||
// Basic functionality:
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
PgDatabaseContainer *m_databases;
|
||||
};
|
||||
|
||||
#endif // DATABASESTABLEMODEL_H
|
||||
63
src/PgContainer.h
Normal file
63
src/PgContainer.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#ifndef PGCONTAINER_H
|
||||
#define PGCONTAINER_H
|
||||
|
||||
#include <QString>
|
||||
#include <vector>
|
||||
#include <pgsql/libpq-fe.h>
|
||||
|
||||
template<typename T>
|
||||
class PgContainer {
|
||||
public:
|
||||
using t_Container = std::vector<T>; ///< Do not assume it will stay a vector only expect bidirectional access
|
||||
|
||||
typename t_Container::const_iterator begin() const
|
||||
{
|
||||
return m_container.begin();
|
||||
}
|
||||
|
||||
typename t_Container::const_iterator end() const
|
||||
{
|
||||
return m_container.end();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_container.clear();
|
||||
}
|
||||
|
||||
int count() const
|
||||
{
|
||||
return (int)m_container.size();
|
||||
}
|
||||
|
||||
const T& getByOid(Oid oid) const
|
||||
{
|
||||
auto lb_result = std::lower_bound(m_container.begin(), m_container.end(), oid);
|
||||
if (lb_result != m_container.end() && lb_result->oid == oid)
|
||||
return *lb_result;
|
||||
|
||||
return m_invalidInstance;
|
||||
}
|
||||
|
||||
const T& getByName(const QString &name) const
|
||||
{
|
||||
auto find_res = std::find(m_container.begin(), m_container.end(), name);
|
||||
|
||||
if (find_res != m_container.end())
|
||||
return *find_res;
|
||||
|
||||
return m_invalidInstance;
|
||||
}
|
||||
|
||||
const T& getByIdx(int idx) const
|
||||
{
|
||||
return m_container.at(idx);
|
||||
}
|
||||
protected:
|
||||
t_Container m_container;
|
||||
private:
|
||||
T m_invalidInstance;
|
||||
|
||||
};
|
||||
|
||||
#endif // PGCONTAINER_H
|
||||
6
src/PgDatabase.cpp
Normal file
6
src/PgDatabase.cpp
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#include "PgDatabase.h"
|
||||
|
||||
PgDatabase::PgDatabase()
|
||||
{
|
||||
|
||||
}
|
||||
31
src/PgDatabase.h
Normal file
31
src/PgDatabase.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef PGDATABASE_H
|
||||
#define PGDATABASE_H
|
||||
|
||||
#include <QString>
|
||||
#include <pgsql/libpq-fe.h>
|
||||
|
||||
class PgDatabase {
|
||||
public:
|
||||
PgDatabase();
|
||||
|
||||
Oid oid = InvalidOid;
|
||||
QString name;
|
||||
Oid dba; // owner?
|
||||
int encoding;
|
||||
QString collate;
|
||||
QString ctype;
|
||||
bool isTemplate;
|
||||
bool allowConn;
|
||||
int connLimit;
|
||||
Oid tablespace;
|
||||
QString acl;//"ARRAY";"YES"
|
||||
|
||||
bool isValid() const { return oid != InvalidOid; }
|
||||
|
||||
bool operator==(Oid _oid) const { return oid == _oid; }
|
||||
bool operator==(const QString &n) const { return name == n; }
|
||||
bool operator<(Oid _oid) const { return oid < _oid; }
|
||||
bool operator<(const PgDatabase &rhs) const { return oid < rhs.oid; }
|
||||
};
|
||||
|
||||
#endif // PGDATABASE_H
|
||||
35
src/PgDatabaseContainer.cpp
Normal file
35
src/PgDatabaseContainer.cpp
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#include "PgDatabaseContainer.h"
|
||||
#include "PgsqlConn.h"
|
||||
|
||||
PgDatabaseContainer::PgDatabaseContainer()
|
||||
{}
|
||||
|
||||
std::string PgDatabaseContainer::getLoadQuery() const
|
||||
{
|
||||
return "SELECT oid,datname,datdba,encoding,datcollate,datctype,datistemplate,datallowcon,"
|
||||
"datconnlimit,dattablespace,datacl FROM pg_database";
|
||||
}
|
||||
|
||||
void PgDatabaseContainer::load(const Pgsql::Result &res)
|
||||
{
|
||||
const int n_rows = res.getRows();
|
||||
m_container.clear();
|
||||
m_container.reserve(n_rows);
|
||||
for (auto row : res) {
|
||||
PgDatabase v;
|
||||
v.oid = row.get(0); // InvalidOid;
|
||||
v.name = row.get(1);
|
||||
v.dba = row.get(2); // owner?
|
||||
v.encoding = row.get(3);
|
||||
v.collate = row.get(4);
|
||||
v.ctype = row.get(5);
|
||||
v.isTemplate = row.get(6);
|
||||
v.allowConn = row.get(7);
|
||||
v.connLimit = row.get(8);
|
||||
v.tablespace = row.get(9);
|
||||
v.acl = row.get(10);
|
||||
m_container.push_back(v);
|
||||
}
|
||||
std::sort(m_container.begin(), m_container.end());
|
||||
}
|
||||
|
||||
26
src/PgDatabaseContainer.h
Normal file
26
src/PgDatabaseContainer.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef PGDATABASECONTAINER_H
|
||||
#define PGDATABASECONTAINER_H
|
||||
|
||||
#include <vector>
|
||||
#include "PgContainer.h"
|
||||
#include "PgDatabase.h"
|
||||
|
||||
namespace Pgsql {
|
||||
|
||||
class Result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
class PgDatabaseContainer: public PgContainer<PgDatabase> {
|
||||
public:
|
||||
PgDatabaseContainer();
|
||||
|
||||
std::string getLoadQuery() const;
|
||||
void load(const Pgsql::Result &res);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
#endif // PGDATABASECONTAINER_H
|
||||
|
|
@ -5,29 +5,29 @@
|
|||
PgTypeContainer::PgTypeContainer() = default;
|
||||
|
||||
|
||||
const PgType& PgTypeContainer::getTypeByOid(Oid oid) const
|
||||
{
|
||||
auto lb_result = std::lower_bound(m_types.begin(), m_types.end(), oid);
|
||||
if (lb_result != m_types.end() && lb_result->oid == oid)
|
||||
return *lb_result;
|
||||
//const PgType& PgTypeContainer::getTypeByOid(Oid oid) const
|
||||
//{
|
||||
// auto lb_result = std::lower_bound(m_types.begin(), m_types.end(), oid);
|
||||
// if (lb_result != m_types.end() && lb_result->oid == oid)
|
||||
// return *lb_result;
|
||||
|
||||
return m_invalidType;
|
||||
}
|
||||
// return m_invalidType;
|
||||
//}
|
||||
|
||||
const PgType& PgTypeContainer::getTypeByName(const QString &name) const
|
||||
{
|
||||
auto find_res = std::find(m_types.begin(), m_types.end(), name);
|
||||
//const PgType& PgTypeContainer::getTypeByName(const QString &name) const
|
||||
//{
|
||||
// auto find_res = std::find(m_types.begin(), m_types.end(), name);
|
||||
|
||||
if (find_res != m_types.end())
|
||||
return *find_res;
|
||||
// if (find_res != m_types.end())
|
||||
// return *find_res;
|
||||
|
||||
return m_invalidType;
|
||||
}
|
||||
// return m_invalidType;
|
||||
//}
|
||||
|
||||
const PgType& PgTypeContainer::getTypeByIdx(int idx) const
|
||||
{
|
||||
return m_types.at(idx);
|
||||
}
|
||||
//const PgType& PgTypeContainer::getTypeByIdx(int idx) const
|
||||
//{
|
||||
// return m_types.at(idx);
|
||||
//}
|
||||
|
||||
std::string PgTypeContainer::getLoadQuery()
|
||||
{
|
||||
|
|
@ -42,8 +42,8 @@ std::string PgTypeContainer::getLoadQuery()
|
|||
void PgTypeContainer::load(const Pgsql::Result &res)
|
||||
{
|
||||
const int n_rows = res.getRows();
|
||||
m_types.clear();
|
||||
m_types.reserve(n_rows);
|
||||
m_container.clear();
|
||||
m_container.reserve(n_rows);
|
||||
for (auto row : res) {
|
||||
PgType v;
|
||||
v.oid = row.get(0); // InvalidOid;
|
||||
|
|
@ -77,7 +77,7 @@ void PgTypeContainer::load(const Pgsql::Result &res)
|
|||
v.typdefaultbin = row.get(28).asQString();//"pg_node_tree";"YES"
|
||||
v.typdefault = row.get(29).asQString();//"text";"YES"
|
||||
v.typacl = row.get(30).asQString();//"ARRAY";"YES"
|
||||
m_types.push_back(v);
|
||||
m_container.push_back(v);
|
||||
}
|
||||
std::sort(m_types.begin(), m_types.end());
|
||||
std::sort(m_container.begin(), m_container.end());
|
||||
}
|
||||
40
src/PgTypeContainer.h
Normal file
40
src/PgTypeContainer.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef PGTYPECONTAINER_H
|
||||
#define PGTYPECONTAINER_H
|
||||
|
||||
#include <vector>
|
||||
#include "pgtype.h"
|
||||
#include "PgContainer.h"
|
||||
|
||||
namespace Pgsql {
|
||||
|
||||
class Result;
|
||||
|
||||
}
|
||||
|
||||
class PgTypeContainer: public PgContainer<PgType> {
|
||||
public:
|
||||
// using t_Types = std::vector<PgType>; ///< Do not assume it will stay a vector only expect bidirectional access
|
||||
|
||||
PgTypeContainer();
|
||||
|
||||
// t_Types::const_iterator begin() const { return m_types.begin(); }
|
||||
// t_Types::const_iterator end() const { return m_types.end(); }
|
||||
|
||||
// void clear();
|
||||
// int count() const { return (int)m_types.size(); }
|
||||
std::string getLoadQuery();
|
||||
void load(const Pgsql::Result &res);
|
||||
|
||||
/** Searches for the type matching the specified oid.
|
||||
*
|
||||
* \return Returns the matching type or if it is not found a default constructed PgType (oid == InvalidOid).
|
||||
*/
|
||||
// const PgType& getTypeByOid(Oid oid) const;
|
||||
// const PgType& getTypeByName(const QString &name) const;
|
||||
// const PgType& getTypeByIdx(int idx) const;
|
||||
private:
|
||||
// PgType m_invalidType; ///< default constructed object for when a non existent type is being retrieved.
|
||||
// t_Types m_types; // Keep sorted by Oid
|
||||
};
|
||||
|
||||
#endif // PGTYPECONTAINER_H
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
#include "ServerWindow.h"
|
||||
#include "ui_ServerWindow.h"
|
||||
#include "OpenDatabase.h"
|
||||
|
||||
ServerWindow::ServerWindow(MasterController *master, QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::ServerWindow)
|
||||
ServerWindow::ServerWindow(MasterController *master, QWidget *parent)
|
||||
: ASyncWindow(parent)
|
||||
, m_masterController(master)
|
||||
, ui(new Ui::ServerWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
|
@ -12,3 +14,16 @@ ServerWindow::~ServerWindow()
|
|||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ServerWindow::setConfig(const ConnectionConfig &config)
|
||||
{
|
||||
m_config = config;
|
||||
auto res = OpenDatabase::createOpenDatabase(config);
|
||||
if (res.valid()) {
|
||||
m_database = res.get();
|
||||
}
|
||||
QString title = "pglab - ";
|
||||
title += m_config.name().c_str();
|
||||
setWindowTitle(title);
|
||||
// newSqlPage();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,29 @@
|
|||
#ifndef SERVERWINDOW_H
|
||||
#define SERVERWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include "ASyncWindow.h"
|
||||
#include "ConnectionConfig.h"
|
||||
|
||||
namespace Ui {
|
||||
class ServerWindow;
|
||||
}
|
||||
|
||||
class MasterController;
|
||||
class OpenDatabase;
|
||||
|
||||
class ServerWindow : public QMainWindow
|
||||
{
|
||||
class ServerWindow : public ASyncWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ServerWindow(MasterController *master, QWidget *parent = 0);
|
||||
explicit ServerWindow(MasterController *master, QWidget *parent );
|
||||
~ServerWindow();
|
||||
|
||||
void setConfig(const ConnectionConfig &config);
|
||||
private:
|
||||
Ui::ServerWindow *ui;
|
||||
|
||||
MasterController *m_masterController;
|
||||
ConnectionConfig m_config;
|
||||
OpenDatabase *m_database;
|
||||
};
|
||||
|
||||
#endif // SERVERWINDOW_H
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
#include "MainWindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
//#include "QueryResultModel.h"
|
||||
//#include "QueryExplainModel.h"
|
||||
#include <QStandardPaths>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QTextTable>
|
||||
#include <QTimer>
|
||||
#include <QElapsedTimer>
|
||||
#include <windows.h>
|
||||
#include <algorithm>
|
||||
|
|
@ -23,15 +20,12 @@ namespace pg = Pgsql;
|
|||
|
||||
|
||||
MainWindow::MainWindow(MasterController *master, QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
: ASyncWindow(parent)
|
||||
, ui(new Ui::MainWindow)
|
||||
, m_masterController(master)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->setDocumentMode(true);
|
||||
|
||||
|
||||
//ui->tabWidget->setTabsClosable(true);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
|
|
@ -69,25 +63,6 @@ void MainWindow::setConfig(const ConnectionConfig &config)
|
|||
newSqlPage();
|
||||
}
|
||||
|
||||
void MainWindow::QueueTask(TSQueue::t_Callable c)
|
||||
{
|
||||
m_taskQueue.add(c);
|
||||
// Theoretically this needs to be only called if the queue was empty because otherwise it already would
|
||||
// be busy emptying the queue. For now however I think it is safer to call it just to make sure.
|
||||
QMetaObject::invokeMethod(this, "processCallableQueue", Qt::QueuedConnection); // queues on main thread
|
||||
}
|
||||
|
||||
void MainWindow::processCallableQueue()
|
||||
{
|
||||
if (!m_taskQueue.empty()) {
|
||||
auto c = m_taskQueue.pop();
|
||||
c();
|
||||
if (!m_taskQueue.empty()) {
|
||||
QTimer::singleShot(0, this, SLOT(processCallableQueue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionLoad_SQL_triggered()
|
||||
{
|
||||
QString home_dir = QStandardPaths::locate(QStandardPaths::HomeLocation, "", QStandardPaths::LocateDirectory);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include "connectionconfig.h"
|
||||
#include "tsqueue.h"
|
||||
#include <QLabel>
|
||||
#include <QMainWindow>
|
||||
#include "ASyncWindow.h"
|
||||
#include <QSocketNotifier>
|
||||
#include <memory>
|
||||
#include <future>
|
||||
|
|
@ -14,10 +14,6 @@
|
|||
#include <deque>
|
||||
#include <mutex>
|
||||
|
||||
//class ExplainRoot;
|
||||
//class QueryResultModel;
|
||||
//class QueryExplainModel;
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
|
@ -31,25 +27,19 @@ class MasterController;
|
|||
class QCloseEvent;
|
||||
class OpenDatabase;
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
class MainWindow : public ASyncWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MainWindow(MasterController *master, QWidget *parent);
|
||||
~MainWindow();
|
||||
|
||||
void setConfig(const ConnectionConfig &config);
|
||||
/* Meant to be called from other threads to pass a code block
|
||||
* that has to be executed in the context of the thread of the window.
|
||||
*/
|
||||
void QueueTask(TSQueue::t_Callable c);
|
||||
|
||||
OpenDatabase* getDatabase() { return m_database; }
|
||||
private:
|
||||
|
||||
Ui::MainWindow *ui;
|
||||
|
||||
TSQueue m_taskQueue;
|
||||
ConnectionConfig m_config;
|
||||
OpenDatabase *m_database;
|
||||
|
||||
|
|
@ -76,8 +66,6 @@ private:
|
|||
|
||||
private slots:
|
||||
|
||||
void processCallableQueue();
|
||||
|
||||
void on_actionLoad_SQL_triggered();
|
||||
void on_actionSave_SQL_triggered();
|
||||
void on_actionExport_data_triggered();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "pgsqldatabasecatalogue.h"
|
||||
#include "pgtypecontainer.h"
|
||||
#include "PgsqlDatabaseCatalogue.h"
|
||||
#include "PgTypeContainer.h"
|
||||
#include "PgDatabaseContainer.h"
|
||||
#include "PgsqlConn.h"
|
||||
|
||||
PgsqlDatabaseCatalogue::PgsqlDatabaseCatalogue()
|
||||
|
|
@ -14,6 +15,7 @@ PgsqlDatabaseCatalogue::~PgsqlDatabaseCatalogue()
|
|||
void PgsqlDatabaseCatalogue::loadAll(Pgsql::Connection &conn)
|
||||
{
|
||||
loadTypes(conn);
|
||||
loadDatabases(conn);
|
||||
}
|
||||
|
||||
void PgsqlDatabaseCatalogue::loadTypes(Pgsql::Connection &conn)
|
||||
|
|
@ -26,3 +28,24 @@ void PgsqlDatabaseCatalogue::loadTypes(Pgsql::Connection &conn)
|
|||
Pgsql::Result result = conn.query(q.c_str());
|
||||
m_types->load(result);
|
||||
}
|
||||
|
||||
void PgsqlDatabaseCatalogue::loadDatabases(Pgsql::Connection &conn)
|
||||
{
|
||||
if (m_databases == nullptr) {
|
||||
m_databases = new PgDatabaseContainer;
|
||||
}
|
||||
|
||||
std::string q = m_databases->getLoadQuery();
|
||||
Pgsql::Result result = conn.query(q.c_str());
|
||||
m_databases->load(result);
|
||||
}
|
||||
|
||||
const PgTypeContainer* PgsqlDatabaseCatalogue::types() const
|
||||
{
|
||||
return m_types;
|
||||
}
|
||||
|
||||
const PgDatabaseContainer *PgsqlDatabaseCatalogue::databases() const
|
||||
{
|
||||
return m_databases;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ namespace Pgsql {
|
|||
}
|
||||
|
||||
class PgTypeContainer;
|
||||
class PgDatabaseContainer;
|
||||
|
||||
class PgsqlDatabaseCatalogue {
|
||||
public:
|
||||
|
|
@ -22,10 +23,13 @@ public:
|
|||
|
||||
void loadAll(Pgsql::Connection &conn);
|
||||
void loadTypes(Pgsql::Connection &conn);
|
||||
void loadDatabases(Pgsql::Connection &conn);
|
||||
|
||||
const PgTypeContainer* types() const { return m_types; }
|
||||
const PgDatabaseContainer *databases() const { return m_databases; }
|
||||
private:
|
||||
PgTypeContainer *m_types = nullptr;
|
||||
PgDatabaseContainer *m_databases = nullptr;
|
||||
};
|
||||
|
||||
#endif // PGSQLDATABASECATALOGUE_H
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
#ifndef PGTYPECONTAINER_H
|
||||
#define PGTYPECONTAINER_H
|
||||
|
||||
#include <vector>
|
||||
#include "pgtype.h"
|
||||
|
||||
namespace Pgsql {
|
||||
|
||||
class Result;
|
||||
|
||||
}
|
||||
|
||||
class PgTypeContainer {
|
||||
public:
|
||||
using t_Types = std::vector<PgType>; ///< Do not assume it will stay a vector only expect bidirectional access
|
||||
|
||||
PgTypeContainer();
|
||||
|
||||
t_Types::const_iterator begin() const { return m_types.begin(); }
|
||||
t_Types::const_iterator end() const { return m_types.end(); }
|
||||
|
||||
void clear();
|
||||
int count() const { return (int)m_types.size(); }
|
||||
std::string getLoadQuery();
|
||||
void load(const Pgsql::Result &res);
|
||||
|
||||
/** Searches for the type matching the specified oid.
|
||||
*
|
||||
* \return Returns the matching type or if it is not found a default constructed PgType (oid == InvalidOid).
|
||||
*/
|
||||
const PgType& getTypeByOid(Oid oid) const;
|
||||
const PgType& getTypeByName(const QString &name) const;
|
||||
const PgType& getTypeByIdx(int idx) const;
|
||||
private:
|
||||
PgType m_invalidType; ///< default constructed object for when a non existent type is being retrieved.
|
||||
t_Types m_types; // Keep sorted by Oid
|
||||
};
|
||||
|
||||
#endif // PGTYPECONTAINER_H
|
||||
21
src/src.pro
21
src/src.pro
|
|
@ -37,9 +37,9 @@ ConnectionConfig.cpp \
|
|||
stopwatch.cpp \
|
||||
util.cpp \
|
||||
databaseinspectorwidget.cpp \
|
||||
pgtype.cpp \
|
||||
PgType.cpp \
|
||||
pgsqldatabasecatalogue.cpp \
|
||||
pgtypecontainer.cpp \
|
||||
PgTypeContainer.cpp \
|
||||
tuplesresultwidget.cpp \
|
||||
pgnamespace.cpp \
|
||||
pgclass.cpp \
|
||||
|
|
@ -52,7 +52,11 @@ ConnectionConfig.cpp \
|
|||
MainWindow.cpp \
|
||||
SqlSyntaxHighlighter.cpp \
|
||||
SqlLexer.cpp \
|
||||
ServerWindow.cpp
|
||||
ServerWindow.cpp \
|
||||
ASyncWindow.cpp \
|
||||
DatabasesTableModel.cpp \
|
||||
PgDatabase.cpp \
|
||||
PgDatabaseContainer.cpp
|
||||
|
||||
HEADERS += \
|
||||
sqlparser.h \
|
||||
|
|
@ -76,9 +80,9 @@ ConnectionConfig.h \
|
|||
stopwatch.h \
|
||||
util.h \
|
||||
databaseinspectorwidget.h \
|
||||
pgtype.h \
|
||||
PgType.h \
|
||||
pgsqldatabasecatalogue.h \
|
||||
pgtypecontainer.h \
|
||||
PgTypeContainer.h \
|
||||
tuplesresultwidget.h \
|
||||
pgnamespace.h \
|
||||
pgclass.h \
|
||||
|
|
@ -91,7 +95,12 @@ ConnectionConfig.h \
|
|||
MainWindow.h \
|
||||
SqlSyntaxHighlighter.h \
|
||||
SqlLexer.h \
|
||||
ServerWindow.h
|
||||
ServerWindow.h \
|
||||
ASyncWindow.h \
|
||||
DatabasesTableModel.h \
|
||||
PgDatabase.h \
|
||||
PgDatabaseContainer.h \
|
||||
PgContainer.h
|
||||
|
||||
FORMS += mainwindow.ui \
|
||||
databasewindow.ui \
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ QVariant TypeSelectionItemModel::data(const QModelIndex &index, int role) const
|
|||
int column = index.column();
|
||||
if (role == Qt::DisplayRole) {
|
||||
if (column == 0) {
|
||||
const PgType &tp = m_types->getTypeByIdx(row);
|
||||
const PgType &tp = m_types->getByIdx(row);
|
||||
result = tp.typname;
|
||||
|
||||
// switch (row) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue