The catalogue now loads the list of databases en there is a table model that can show this data.

This commit is contained in:
eelke 2017-02-12 14:03:42 +01:00
parent a9430bca1a
commit 20af12535e
22 changed files with 504 additions and 118 deletions

25
src/ASyncWindow.cpp Normal file
View 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
View 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
View 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
View 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
View 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
View file

@ -0,0 +1,6 @@
#include "PgDatabase.h"
PgDatabase::PgDatabase()
{
}

31
src/PgDatabase.h Normal file
View 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

View 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
View 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

View file

@ -5,29 +5,29 @@
PgTypeContainer::PgTypeContainer() = default; PgTypeContainer::PgTypeContainer() = default;
const PgType& PgTypeContainer::getTypeByOid(Oid oid) const //const PgType& PgTypeContainer::getTypeByOid(Oid oid) const
{ //{
auto lb_result = std::lower_bound(m_types.begin(), m_types.end(), oid); // auto lb_result = std::lower_bound(m_types.begin(), m_types.end(), oid);
if (lb_result != m_types.end() && lb_result->oid == oid) // if (lb_result != m_types.end() && lb_result->oid == oid)
return *lb_result; // return *lb_result;
return m_invalidType; // return m_invalidType;
} //}
const PgType& PgTypeContainer::getTypeByName(const QString &name) const //const PgType& PgTypeContainer::getTypeByName(const QString &name) const
{ //{
auto find_res = std::find(m_types.begin(), m_types.end(), name); // auto find_res = std::find(m_types.begin(), m_types.end(), name);
if (find_res != m_types.end()) // if (find_res != m_types.end())
return *find_res; // return *find_res;
return m_invalidType; // return m_invalidType;
} //}
const PgType& PgTypeContainer::getTypeByIdx(int idx) const //const PgType& PgTypeContainer::getTypeByIdx(int idx) const
{ //{
return m_types.at(idx); // return m_types.at(idx);
} //}
std::string PgTypeContainer::getLoadQuery() std::string PgTypeContainer::getLoadQuery()
{ {
@ -42,8 +42,8 @@ std::string PgTypeContainer::getLoadQuery()
void PgTypeContainer::load(const Pgsql::Result &res) void PgTypeContainer::load(const Pgsql::Result &res)
{ {
const int n_rows = res.getRows(); const int n_rows = res.getRows();
m_types.clear(); m_container.clear();
m_types.reserve(n_rows); m_container.reserve(n_rows);
for (auto row : res) { for (auto row : res) {
PgType v; PgType v;
v.oid = row.get(0); // InvalidOid; 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.typdefaultbin = row.get(28).asQString();//"pg_node_tree";"YES"
v.typdefault = row.get(29).asQString();//"text";"YES" v.typdefault = row.get(29).asQString();//"text";"YES"
v.typacl = row.get(30).asQString();//"ARRAY";"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
View 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

View file

@ -1,9 +1,11 @@
#include "ServerWindow.h" #include "ServerWindow.h"
#include "ui_ServerWindow.h" #include "ui_ServerWindow.h"
#include "OpenDatabase.h"
ServerWindow::ServerWindow(MasterController *master, QWidget *parent) : ServerWindow::ServerWindow(MasterController *master, QWidget *parent)
QMainWindow(parent), : ASyncWindow(parent)
ui(new Ui::ServerWindow) , m_masterController(master)
, ui(new Ui::ServerWindow)
{ {
ui->setupUi(this); ui->setupUi(this);
} }
@ -12,3 +14,16 @@ ServerWindow::~ServerWindow()
{ {
delete ui; 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();
}

View file

@ -1,24 +1,29 @@
#ifndef SERVERWINDOW_H #ifndef SERVERWINDOW_H
#define SERVERWINDOW_H #define SERVERWINDOW_H
#include <QMainWindow> #include "ASyncWindow.h"
#include "ConnectionConfig.h"
namespace Ui { namespace Ui {
class ServerWindow; class ServerWindow;
} }
class MasterController; class MasterController;
class OpenDatabase;
class ServerWindow : public QMainWindow class ServerWindow : public ASyncWindow {
{
Q_OBJECT Q_OBJECT
public: public:
explicit ServerWindow(MasterController *master, QWidget *parent = 0); explicit ServerWindow(MasterController *master, QWidget *parent );
~ServerWindow(); ~ServerWindow();
void setConfig(const ConnectionConfig &config);
private: private:
Ui::ServerWindow *ui; Ui::ServerWindow *ui;
MasterController *m_masterController;
ConnectionConfig m_config;
OpenDatabase *m_database;
}; };
#endif // SERVERWINDOW_H #endif // SERVERWINDOW_H

View file

@ -1,13 +1,10 @@
#include "MainWindow.h" #include "MainWindow.h"
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
//#include "QueryResultModel.h"
//#include "QueryExplainModel.h"
#include <QStandardPaths> #include <QStandardPaths>
#include <QFileDialog> #include <QFileDialog>
#include <QMessageBox> #include <QMessageBox>
#include <QTextTable> #include <QTextTable>
#include <QTimer>
#include <QElapsedTimer> #include <QElapsedTimer>
#include <windows.h> #include <windows.h>
#include <algorithm> #include <algorithm>
@ -23,15 +20,12 @@ namespace pg = Pgsql;
MainWindow::MainWindow(MasterController *master, QWidget *parent) MainWindow::MainWindow(MasterController *master, QWidget *parent)
: QMainWindow(parent) : ASyncWindow(parent)
, ui(new Ui::MainWindow) , ui(new Ui::MainWindow)
, m_masterController(master) , m_masterController(master)
{ {
ui->setupUi(this); ui->setupUi(this);
ui->tabWidget->setDocumentMode(true); ui->tabWidget->setDocumentMode(true);
//ui->tabWidget->setTabsClosable(true);
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
@ -69,25 +63,6 @@ void MainWindow::setConfig(const ConnectionConfig &config)
newSqlPage(); 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() void MainWindow::on_actionLoad_SQL_triggered()
{ {
QString home_dir = QStandardPaths::locate(QStandardPaths::HomeLocation, "", QStandardPaths::LocateDirectory); QString home_dir = QStandardPaths::locate(QStandardPaths::HomeLocation, "", QStandardPaths::LocateDirectory);

View file

@ -5,7 +5,7 @@
#include "connectionconfig.h" #include "connectionconfig.h"
#include "tsqueue.h" #include "tsqueue.h"
#include <QLabel> #include <QLabel>
#include <QMainWindow> #include "ASyncWindow.h"
#include <QSocketNotifier> #include <QSocketNotifier>
#include <memory> #include <memory>
#include <future> #include <future>
@ -14,10 +14,6 @@
#include <deque> #include <deque>
#include <mutex> #include <mutex>
//class ExplainRoot;
//class QueryResultModel;
//class QueryExplainModel;
namespace Ui { namespace Ui {
class MainWindow; class MainWindow;
} }
@ -31,25 +27,19 @@ class MasterController;
class QCloseEvent; class QCloseEvent;
class OpenDatabase; class OpenDatabase;
class MainWindow : public QMainWindow class MainWindow : public ASyncWindow {
{
Q_OBJECT Q_OBJECT
public: public:
explicit MainWindow(MasterController *master, QWidget *parent); explicit MainWindow(MasterController *master, QWidget *parent);
~MainWindow(); ~MainWindow();
void setConfig(const ConnectionConfig &config); 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; } OpenDatabase* getDatabase() { return m_database; }
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
TSQueue m_taskQueue;
ConnectionConfig m_config; ConnectionConfig m_config;
OpenDatabase *m_database; OpenDatabase *m_database;
@ -76,8 +66,6 @@ private:
private slots: private slots:
void processCallableQueue();
void on_actionLoad_SQL_triggered(); void on_actionLoad_SQL_triggered();
void on_actionSave_SQL_triggered(); void on_actionSave_SQL_triggered();
void on_actionExport_data_triggered(); void on_actionExport_data_triggered();

View file

@ -1,5 +1,6 @@
#include "pgsqldatabasecatalogue.h" #include "PgsqlDatabaseCatalogue.h"
#include "pgtypecontainer.h" #include "PgTypeContainer.h"
#include "PgDatabaseContainer.h"
#include "PgsqlConn.h" #include "PgsqlConn.h"
PgsqlDatabaseCatalogue::PgsqlDatabaseCatalogue() PgsqlDatabaseCatalogue::PgsqlDatabaseCatalogue()
@ -14,6 +15,7 @@ PgsqlDatabaseCatalogue::~PgsqlDatabaseCatalogue()
void PgsqlDatabaseCatalogue::loadAll(Pgsql::Connection &conn) void PgsqlDatabaseCatalogue::loadAll(Pgsql::Connection &conn)
{ {
loadTypes(conn); loadTypes(conn);
loadDatabases(conn);
} }
void PgsqlDatabaseCatalogue::loadTypes(Pgsql::Connection &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()); Pgsql::Result result = conn.query(q.c_str());
m_types->load(result); 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;
}

View file

@ -10,6 +10,7 @@ namespace Pgsql {
} }
class PgTypeContainer; class PgTypeContainer;
class PgDatabaseContainer;
class PgsqlDatabaseCatalogue { class PgsqlDatabaseCatalogue {
public: public:
@ -22,10 +23,13 @@ public:
void loadAll(Pgsql::Connection &conn); void loadAll(Pgsql::Connection &conn);
void loadTypes(Pgsql::Connection &conn); void loadTypes(Pgsql::Connection &conn);
void loadDatabases(Pgsql::Connection &conn);
const PgTypeContainer* types() const { return m_types; } const PgTypeContainer* types() const { return m_types; }
const PgDatabaseContainer *databases() const { return m_databases; }
private: private:
PgTypeContainer *m_types = nullptr; PgTypeContainer *m_types = nullptr;
PgDatabaseContainer *m_databases = nullptr;
}; };
#endif // PGSQLDATABASECATALOGUE_H #endif // PGSQLDATABASECATALOGUE_H

View file

@ -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

View file

@ -37,9 +37,9 @@ ConnectionConfig.cpp \
stopwatch.cpp \ stopwatch.cpp \
util.cpp \ util.cpp \
databaseinspectorwidget.cpp \ databaseinspectorwidget.cpp \
pgtype.cpp \ PgType.cpp \
pgsqldatabasecatalogue.cpp \ pgsqldatabasecatalogue.cpp \
pgtypecontainer.cpp \ PgTypeContainer.cpp \
tuplesresultwidget.cpp \ tuplesresultwidget.cpp \
pgnamespace.cpp \ pgnamespace.cpp \
pgclass.cpp \ pgclass.cpp \
@ -52,7 +52,11 @@ ConnectionConfig.cpp \
MainWindow.cpp \ MainWindow.cpp \
SqlSyntaxHighlighter.cpp \ SqlSyntaxHighlighter.cpp \
SqlLexer.cpp \ SqlLexer.cpp \
ServerWindow.cpp ServerWindow.cpp \
ASyncWindow.cpp \
DatabasesTableModel.cpp \
PgDatabase.cpp \
PgDatabaseContainer.cpp
HEADERS += \ HEADERS += \
sqlparser.h \ sqlparser.h \
@ -76,9 +80,9 @@ ConnectionConfig.h \
stopwatch.h \ stopwatch.h \
util.h \ util.h \
databaseinspectorwidget.h \ databaseinspectorwidget.h \
pgtype.h \ PgType.h \
pgsqldatabasecatalogue.h \ pgsqldatabasecatalogue.h \
pgtypecontainer.h \ PgTypeContainer.h \
tuplesresultwidget.h \ tuplesresultwidget.h \
pgnamespace.h \ pgnamespace.h \
pgclass.h \ pgclass.h \
@ -91,7 +95,12 @@ ConnectionConfig.h \
MainWindow.h \ MainWindow.h \
SqlSyntaxHighlighter.h \ SqlSyntaxHighlighter.h \
SqlLexer.h \ SqlLexer.h \
ServerWindow.h ServerWindow.h \
ASyncWindow.h \
DatabasesTableModel.h \
PgDatabase.h \
PgDatabaseContainer.h \
PgContainer.h
FORMS += mainwindow.ui \ FORMS += mainwindow.ui \
databasewindow.ui \ databasewindow.ui \

View file

@ -33,7 +33,7 @@ QVariant TypeSelectionItemModel::data(const QModelIndex &index, int role) const
int column = index.column(); int column = index.column();
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
if (column == 0) { if (column == 0) {
const PgType &tp = m_types->getTypeByIdx(row); const PgType &tp = m_types->getByIdx(row);
result = tp.typname; result = tp.typname;
// switch (row) { // switch (row) {