PgAttribute loading + ColummnTableModel
Required enchancement to PgContainer to make multifield key work.
This commit is contained in:
parent
f9caadb59e
commit
e9d72d391d
32 changed files with 698 additions and 99 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -3,3 +3,4 @@ build/*
|
||||||
*.kdev4
|
*.kdev4
|
||||||
.kdev4/*
|
.kdev4/*
|
||||||
|
|
||||||
|
DIST/
|
||||||
|
|
|
||||||
149
pglab/ColumnTableModel.cpp
Normal file
149
pglab/ColumnTableModel.cpp
Normal file
|
|
@ -0,0 +1,149 @@
|
||||||
|
#include "ColumnTableModel.h"
|
||||||
|
#include "PgDatabaseCatalog.h"
|
||||||
|
#include "PgAttribute.h"
|
||||||
|
#include "PgAttributeContainer.h"
|
||||||
|
#include "PgType.h"
|
||||||
|
#include "PgTypeContainer.h"
|
||||||
|
#include "ScopeGuard.h"
|
||||||
|
#include <QBrush>
|
||||||
|
|
||||||
|
void ColumnTableModel::setData(std::shared_ptr<const PgDatabaseCatalog> cat, Oid table_oid)
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
SCOPE_EXIT { endResetModel(); };
|
||||||
|
|
||||||
|
m_catalog = cat;
|
||||||
|
m_columns = cat->attributes()->getColumnsForRelation(table_oid);
|
||||||
|
|
||||||
|
// hide system columns
|
||||||
|
m_columns.erase(std::remove_if(m_columns.begin(), m_columns.end(),
|
||||||
|
[](auto &e) { return e.num <= 0; } ),
|
||||||
|
m_columns.end());
|
||||||
|
|
||||||
|
// sort remaining columns by order in table
|
||||||
|
std::sort(m_columns.begin(), m_columns.end(),
|
||||||
|
[] (auto &l, auto &r) -> bool { return l.num < r.num; });
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ColumnTableModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
QVariant v;
|
||||||
|
if (orientation == Qt::Horizontal) {
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
QString c;
|
||||||
|
switch (section) {
|
||||||
|
case NameCol:
|
||||||
|
c = tr("Name");
|
||||||
|
break;
|
||||||
|
case TypeCol:
|
||||||
|
c = tr("Type");
|
||||||
|
break;
|
||||||
|
case NullCol:
|
||||||
|
c = tr("Nullable");
|
||||||
|
break;
|
||||||
|
case DefaultCol:
|
||||||
|
c = tr("Default");
|
||||||
|
break;
|
||||||
|
case CollationCol:
|
||||||
|
c = tr("Collation");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
v = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ColumnTableModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return m_columns.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ColumnTableModel::columnCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return colCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
Oid ColumnTableModel::getType(int column) const
|
||||||
|
{
|
||||||
|
Oid oid = Pgsql::VARCHAROID;
|
||||||
|
// switch (column) {
|
||||||
|
// case TypeCol:
|
||||||
|
// case NameCol:
|
||||||
|
// case NullCol:
|
||||||
|
// case DefaultCol:
|
||||||
|
// case CollationCol:
|
||||||
|
// oid = VARCHAROID;
|
||||||
|
// break;
|
||||||
|
|
||||||
|
// c = tr("Collation");
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
return oid;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ColumnTableModel::getData(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
QVariant v;
|
||||||
|
const auto &t = m_columns[index.row()];
|
||||||
|
QString s;
|
||||||
|
switch (index.column()) {
|
||||||
|
case NameCol:
|
||||||
|
s = t.name;
|
||||||
|
break;
|
||||||
|
case TypeCol:
|
||||||
|
s = getTypeDisplayString(*m_catalog, t.typid);
|
||||||
|
break;
|
||||||
|
case NullCol:
|
||||||
|
s = t.notnull ? "NOT NULL" : "";
|
||||||
|
break;
|
||||||
|
case DefaultCol:
|
||||||
|
s = "";
|
||||||
|
break;
|
||||||
|
case CollationCol:
|
||||||
|
s = ""; //t.collation;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
v = s;
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ColumnTableModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (role == Qt::ForegroundRole && index.column() == TypeCol) {
|
||||||
|
QVariant v;
|
||||||
|
const auto &t = m_columns[index.row()];
|
||||||
|
auto c = m_catalog->types()->getByKey(t.typid);
|
||||||
|
switch (c.category) {
|
||||||
|
case TypCategory::Boolean:
|
||||||
|
v = QBrush(Qt::darkGreen);
|
||||||
|
break;
|
||||||
|
case TypCategory::Numeric:
|
||||||
|
v = QBrush(Qt::darkBlue);
|
||||||
|
break;
|
||||||
|
case TypCategory::DateTime:
|
||||||
|
case TypCategory::Timespan:
|
||||||
|
v = QBrush(Qt::darkMagenta);
|
||||||
|
break;
|
||||||
|
case TypCategory::String:
|
||||||
|
v = QBrush(Qt::darkYellow);
|
||||||
|
break;
|
||||||
|
case TypCategory::Array:
|
||||||
|
case TypCategory::Composite:
|
||||||
|
case TypCategory::Enum:
|
||||||
|
case TypCategory::Geometric:
|
||||||
|
case TypCategory::NetworkAddress:
|
||||||
|
case TypCategory::Pseudo:
|
||||||
|
case TypCategory::Range:
|
||||||
|
case TypCategory::UserDefined:
|
||||||
|
case TypCategory::BitString:
|
||||||
|
case TypCategory::Unknown:
|
||||||
|
default:
|
||||||
|
v = QBrush(Qt::black);
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
return BaseTableModel::data(index, role);
|
||||||
|
}
|
||||||
44
pglab/ColumnTableModel.h
Normal file
44
pglab/ColumnTableModel.h
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
#ifndef COLUMNTABLEMODEL_H
|
||||||
|
#define COLUMNTABLEMODEL_H
|
||||||
|
|
||||||
|
#include "BaseTableModel.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class PgDatabaseCatalog;
|
||||||
|
class PgAttribute;
|
||||||
|
|
||||||
|
class ColumnTableModel: public BaseTableModel {
|
||||||
|
public:
|
||||||
|
enum e_Columns : int {
|
||||||
|
NameCol, ///
|
||||||
|
TypeCol,
|
||||||
|
NullCol,
|
||||||
|
DefaultCol,
|
||||||
|
CollationCol,
|
||||||
|
|
||||||
|
colCount };
|
||||||
|
|
||||||
|
|
||||||
|
using BaseTableModel::BaseTableModel;
|
||||||
|
void setData(std::shared_ptr<const PgDatabaseCatalog> cat, Oid table_oid);
|
||||||
|
|
||||||
|
// Header:
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||||
|
|
||||||
|
// Basic functionality:
|
||||||
|
int rowCount(const QModelIndex &parent) const override;
|
||||||
|
int columnCount(const QModelIndex &parent) const override;
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role) const override;
|
||||||
|
protected:
|
||||||
|
virtual Oid getType(int column) const override;
|
||||||
|
virtual QVariant getData(const QModelIndex &index) const override;
|
||||||
|
|
||||||
|
using t_Columns = std::vector<PgAttribute>;
|
||||||
|
|
||||||
|
std::shared_ptr<const PgDatabaseCatalog> m_catalog;
|
||||||
|
t_Columns m_columns;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // COLUMNTABLEMODEL_H
|
||||||
|
|
@ -40,12 +40,6 @@ QueryTab* MainWindow::newSqlPage()
|
||||||
ui->tabWidget->addTab(qt, "Tab");
|
ui->tabWidget->addTab(qt, "Tab");
|
||||||
ui->tabWidget->setCurrentWidget(qt);
|
ui->tabWidget->setCurrentWidget(qt);
|
||||||
qt->newdoc();
|
qt->newdoc();
|
||||||
|
|
||||||
auto tt = new TablesPage(this);
|
|
||||||
tt->setCatalog(m_database->catalogue());
|
|
||||||
ui->tabWidget->addTab(tt, "Tables");
|
|
||||||
ui->tabWidget->setCurrentWidget(tt);
|
|
||||||
|
|
||||||
return qt;
|
return qt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,6 +62,12 @@ void MainWindow::setConfig(const ConnectionConfig &config)
|
||||||
QString title = "pglab - ";
|
QString title = "pglab - ";
|
||||||
title += m_config.name().c_str();
|
title += m_config.name().c_str();
|
||||||
setWindowTitle(title);
|
setWindowTitle(title);
|
||||||
|
|
||||||
|
auto tt = new TablesPage(this);
|
||||||
|
tt->setCatalog(m_database->catalogue());
|
||||||
|
ui->tabWidget->addTab(tt, "Tables");
|
||||||
|
ui->tabWidget->setCurrentWidget(tt);
|
||||||
|
|
||||||
newSqlPage();
|
newSqlPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
2
pglab/PgAttribute.cpp
Normal file
2
pglab/PgAttribute.cpp
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
#include "PgAttribute.h"
|
||||||
|
|
||||||
35
pglab/PgAttribute.h
Normal file
35
pglab/PgAttribute.h
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef PGATTRIBUTE_H
|
||||||
|
#define PGATTRIBUTE_H
|
||||||
|
|
||||||
|
#include "Pgsql_declare.h"
|
||||||
|
#include <QString>
|
||||||
|
#include <libpq-fe.h>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
class PgAttribute {
|
||||||
|
public:
|
||||||
|
using Key = std::tuple<Oid, int16_t>;
|
||||||
|
|
||||||
|
// Oid oid = InvalidOid;
|
||||||
|
Oid relid = InvalidOid;
|
||||||
|
QString name;
|
||||||
|
Oid typid = InvalidOid;
|
||||||
|
int32_t stattarget = 0;
|
||||||
|
int16_t num = 0;
|
||||||
|
int32_t ndims = 0; // array dimensions
|
||||||
|
int32_t typmod = -1;
|
||||||
|
bool notnull = false;
|
||||||
|
bool hasdef = false;
|
||||||
|
Oid collation = InvalidOid;
|
||||||
|
QString acl;
|
||||||
|
QString options;
|
||||||
|
|
||||||
|
|
||||||
|
bool operator==(Key _k) const { return relid == std::get<0>(_k) && num == std::get<1>(_k); }
|
||||||
|
bool operator==(const QString &n) const { return name == n; }
|
||||||
|
bool operator<(Key _k) const { return relid < std::get<0>(_k) || (relid == std::get<0>(_k) && num < std::get<1>(_k)); }
|
||||||
|
bool operator<(const PgAttribute &rhs) const { return relid < rhs.relid || (relid == rhs.relid && num < rhs.num); }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PGATTRIBUTE_H
|
||||||
30
pglab/PgAttributeContainer.cpp
Normal file
30
pglab/PgAttributeContainer.cpp
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
#include "PgAttributeContainer.h"
|
||||||
|
#include "Pgsql_Col.h"
|
||||||
|
|
||||||
|
std::string PgAttributeContainer::getLoadQuery() const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
"SELECT attrelid, attname, atttypid, attstattarget, \n"
|
||||||
|
" attnum, attndims, atttypmod, attnotnull, atthasdef, \n"
|
||||||
|
" attcollation, attacl, attoptions \n"
|
||||||
|
" FROM pg_catalog.pg_attribute";
|
||||||
|
}
|
||||||
|
|
||||||
|
PgAttribute PgAttributeContainer::loadElem(const Pgsql::Row &row)
|
||||||
|
{
|
||||||
|
Pgsql::Col col(row);
|
||||||
|
PgAttribute v;
|
||||||
|
col >> v.relid >> v.name >> v.typid >> v.stattarget
|
||||||
|
>> v.num >> v.ndims >> v.typmod >> v.notnull >> v.hasdef
|
||||||
|
>> v.collation >> v.acl >> v.options;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<PgAttribute> PgAttributeContainer::getColumnsForRelation(Oid oid) const
|
||||||
|
{
|
||||||
|
std::vector<PgAttribute> result;
|
||||||
|
for (const auto &e : m_container)
|
||||||
|
if (e.relid == oid)
|
||||||
|
result.push_back(e);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
20
pglab/PgAttributeContainer.h
Normal file
20
pglab/PgAttributeContainer.h
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef PGATTRIBUTECONTAINER_H
|
||||||
|
#define PGATTRIBUTECONTAINER_H
|
||||||
|
|
||||||
|
#include "PgContainer.h"
|
||||||
|
#include "PgAttribute.h"
|
||||||
|
#include "Pgsql_declare.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class PgAttributeContainer : public PgContainer<PgAttribute, PgAttribute::Key> {
|
||||||
|
public:
|
||||||
|
using PgContainer<PgAttribute, PgAttribute::Key>::PgContainer;
|
||||||
|
|
||||||
|
virtual std::string getLoadQuery() const override;
|
||||||
|
|
||||||
|
std::vector<PgAttribute> getColumnsForRelation(Oid oid) const;
|
||||||
|
protected:
|
||||||
|
PgAttribute loadElem(const Pgsql::Row &row) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PGATTRIBUTECONTAINER_H
|
||||||
|
|
@ -12,12 +12,8 @@ std::string PgClassContainer::getLoadQuery() const
|
||||||
"FROM pg_catalog.pg_class";
|
"FROM pg_catalog.pg_class";
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgClassContainer::load(const Pgsql::Result &res)
|
PgClass PgClassContainer::loadElem(const Pgsql::Row &row)
|
||||||
{
|
{
|
||||||
const int n_rows = res.rows();
|
|
||||||
m_container.clear();
|
|
||||||
m_container.reserve(n_rows);
|
|
||||||
for (auto row : res) {
|
|
||||||
Pgsql::Col col(row);
|
Pgsql::Col col(row);
|
||||||
PgClass v;
|
PgClass v;
|
||||||
col >> v.oid >> v.name >> v.relnamespace >> v.type >> v.oftype
|
col >> v.oid >> v.name >> v.relnamespace >> v.type >> v.oftype
|
||||||
|
|
@ -25,9 +21,5 @@ void PgClassContainer::load(const Pgsql::Result &res)
|
||||||
>> v.tuples_est >> v.toastrelid >> v.isshared >> v.persistence
|
>> v.tuples_est >> v.toastrelid >> v.isshared >> v.persistence
|
||||||
>> v.kind >> v.hasoids >> v.ispopulated >> v.frozenxid >> v.minmxid
|
>> v.kind >> v.hasoids >> v.ispopulated >> v.frozenxid >> v.minmxid
|
||||||
>> v.acl >> v.options;
|
>> v.acl >> v.options;
|
||||||
|
return v;
|
||||||
m_container.push_back(v);
|
|
||||||
}
|
|
||||||
std::sort(m_container.begin(), m_container.end());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ public:
|
||||||
using PgContainer<PgClass>::PgContainer;
|
using PgContainer<PgClass>::PgContainer;
|
||||||
|
|
||||||
virtual std::string getLoadQuery() const override;
|
virtual std::string getLoadQuery() const override;
|
||||||
virtual void load(const Pgsql::Result &res) override;
|
protected:
|
||||||
|
PgClass loadElem(const Pgsql::Row &row) override;
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
2
pglab/PgContainer.cpp
Normal file
2
pglab/PgContainer.cpp
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
#include "PgContainer.h"
|
||||||
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#define PGCONTAINER_H
|
#define PGCONTAINER_H
|
||||||
|
|
||||||
#include "Pgsql_declare.h"
|
#include "Pgsql_declare.h"
|
||||||
|
#include "Pgsql_Result.h"
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
@ -18,7 +19,7 @@ public:
|
||||||
virtual void load(const Pgsql::Result &res) = 0;
|
virtual void load(const Pgsql::Result &res) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename K=Oid>
|
||||||
class PgContainer: public IPgContainter {
|
class PgContainer: public IPgContainter {
|
||||||
public:
|
public:
|
||||||
using t_Container = std::vector<T>; ///< Do not assume it will stay a vector only expect bidirectional access
|
using t_Container = std::vector<T>; ///< Do not assume it will stay a vector only expect bidirectional access
|
||||||
|
|
@ -48,10 +49,10 @@ public:
|
||||||
return (int)m_container.size();
|
return (int)m_container.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
const T& getByOid(Oid oid) const
|
const T& getByKey(const K &key) const
|
||||||
{
|
{
|
||||||
auto lb_result = std::lower_bound(m_container.begin(), m_container.end(), oid);
|
auto lb_result = std::lower_bound(m_container.begin(), m_container.end(), key);
|
||||||
if (lb_result != m_container.end() && lb_result->oid == oid)
|
if (lb_result != m_container.end() && *lb_result == key)
|
||||||
return *lb_result;
|
return *lb_result;
|
||||||
|
|
||||||
return m_invalidInstance;
|
return m_invalidInstance;
|
||||||
|
|
@ -71,9 +72,30 @@ public:
|
||||||
{
|
{
|
||||||
return m_container.at(idx);
|
return m_container.at(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Override to implement complete loading logic.
|
||||||
|
*
|
||||||
|
* Do not override this function if you only want to implement
|
||||||
|
* the loading of a single element. Override loadElem instead.
|
||||||
|
*/
|
||||||
|
virtual void load(const Pgsql::Result &res) override
|
||||||
|
{
|
||||||
|
m_container.clear();
|
||||||
|
m_container.reserve(res.rows());
|
||||||
|
for (auto row : res)
|
||||||
|
m_container.push_back(loadElem(row));
|
||||||
|
|
||||||
|
std::sort(m_container.begin(), m_container.end());
|
||||||
|
}
|
||||||
protected:
|
protected:
|
||||||
std::weak_ptr<PgDatabaseCatalog> m_catalogue;
|
std::weak_ptr<PgDatabaseCatalog> m_catalogue;
|
||||||
t_Container m_container;
|
t_Container m_container;
|
||||||
|
|
||||||
|
/** Override the implementation for this function to implement loading of single row.
|
||||||
|
*
|
||||||
|
* When overriding this function there is no need to override load.
|
||||||
|
*/
|
||||||
|
virtual T loadElem(const Pgsql::Row &) { return T(); }
|
||||||
private:
|
private:
|
||||||
T m_invalidInstance;
|
T m_invalidInstance;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
#include "PgDatabaseCatalog.h"
|
#include "PgDatabaseCatalog.h"
|
||||||
#include "PgTypeContainer.h"
|
|
||||||
#include "PgDatabaseContainer.h"
|
#include "PgAttributeContainer.h"
|
||||||
#include "PgAuthIdContainer.h"
|
#include "PgAuthIdContainer.h"
|
||||||
#include "PgClassContainer.h"
|
#include "PgClassContainer.h"
|
||||||
|
#include "PgDatabaseContainer.h"
|
||||||
|
#include "PgNamespaceContainer.h"
|
||||||
|
#include "PgTypeContainer.h"
|
||||||
#include "Pgsql_Connection.h"
|
#include "Pgsql_Connection.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -11,7 +14,7 @@ QString getRoleNameFromOid(const PgDatabaseCatalog &cat, Oid oid)
|
||||||
QString name;
|
QString name;
|
||||||
auto auth_ids = cat.authIds();
|
auto auth_ids = cat.authIds();
|
||||||
if (auth_ids) {
|
if (auth_ids) {
|
||||||
const PgAuthId& auth_id = auth_ids->getByOid(oid);
|
const PgAuthId& auth_id = auth_ids->getByKey(oid);
|
||||||
if (auth_id.valid()) {
|
if (auth_id.valid()) {
|
||||||
name = auth_id.name;
|
name = auth_id.name;
|
||||||
}
|
}
|
||||||
|
|
@ -22,13 +25,15 @@ QString getRoleNameFromOid(const PgDatabaseCatalog &cat, Oid oid)
|
||||||
QString getRoleDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
QString getRoleDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
||||||
{
|
{
|
||||||
QString name = getRoleNameFromOid(cat, oid);
|
QString name = getRoleNameFromOid(cat, oid);
|
||||||
return QString("%1 (%2)").arg(name).arg(oid);
|
return name;
|
||||||
|
// return QString("%1 (%2)").arg(name).arg(oid);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString getNamespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
QString getNamespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
||||||
{
|
{
|
||||||
//QString name;
|
//QString name;
|
||||||
// auto c = cat.();
|
auto nss = cat.namespaces();
|
||||||
|
auto ns = nss->getByKey(oid);
|
||||||
// if (auth_ids) {
|
// if (auth_ids) {
|
||||||
// const PgAuthId& auth_id = auth_ids->getByOid(oid);
|
// const PgAuthId& auth_id = auth_ids->getByOid(oid);
|
||||||
// if (auth_id.valid()) {
|
// if (auth_id.valid()) {
|
||||||
|
|
@ -37,7 +42,7 @@ QString getNamespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
||||||
// }
|
// }
|
||||||
//return name;
|
//return name;
|
||||||
// TODO load list and lookup name
|
// TODO load list and lookup name
|
||||||
return QString("ns %1").arg(oid);
|
return ns.name; //QString("ns %1").arg(oid);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,6 +52,13 @@ QString getTablespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
||||||
return QString("ts %1").arg(oid);
|
return QString("ts %1").arg(oid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString getTypeDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
||||||
|
{
|
||||||
|
auto tc = cat.types();
|
||||||
|
auto t = tc->getByKey(oid);
|
||||||
|
return t.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PgDatabaseCatalog::PgDatabaseCatalog()
|
PgDatabaseCatalog::PgDatabaseCatalog()
|
||||||
{
|
{
|
||||||
|
|
@ -59,10 +71,13 @@ PgDatabaseCatalog::~PgDatabaseCatalog()
|
||||||
void PgDatabaseCatalog::loadAll(Pgsql::Connection &conn)
|
void PgDatabaseCatalog::loadAll(Pgsql::Connection &conn)
|
||||||
{
|
{
|
||||||
loadInfo(conn);
|
loadInfo(conn);
|
||||||
loadTypes(conn);
|
|
||||||
loadDatabases(conn);
|
loadAttributes(conn);
|
||||||
loadAuthIds(conn);
|
loadAuthIds(conn);
|
||||||
loadClasses(conn);
|
loadClasses(conn);
|
||||||
|
loadDatabases(conn);
|
||||||
|
loadNamespaces(conn);
|
||||||
|
loadTypes(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgDatabaseCatalog::loadInfo(Pgsql::Connection &conn)
|
void PgDatabaseCatalog::loadInfo(Pgsql::Connection &conn)
|
||||||
|
|
@ -89,20 +104,12 @@ void load(Pgsql::Connection &conn, IPgContainter &pg_cont)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgDatabaseCatalog::loadTypes(Pgsql::Connection &conn)
|
void PgDatabaseCatalog::loadAttributes(Pgsql::Connection &conn)
|
||||||
{
|
{
|
||||||
if (!m_types)
|
if (!m_attributes)
|
||||||
m_types = std::make_shared<PgTypeContainer>(shared_from_this());
|
m_attributes = std::make_shared<PgAttributeContainer>(shared_from_this());
|
||||||
|
|
||||||
load(conn, *m_types);
|
load(conn, *m_attributes);
|
||||||
}
|
|
||||||
|
|
||||||
void PgDatabaseCatalog::loadDatabases(Pgsql::Connection &conn)
|
|
||||||
{
|
|
||||||
if (!m_databases)
|
|
||||||
m_databases = std::make_shared<PgDatabaseContainer>(shared_from_this());
|
|
||||||
|
|
||||||
load(conn, *m_databases);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgDatabaseCatalog::loadAuthIds(Pgsql::Connection &conn)
|
void PgDatabaseCatalog::loadAuthIds(Pgsql::Connection &conn)
|
||||||
|
|
@ -121,6 +128,31 @@ void PgDatabaseCatalog::loadClasses(Pgsql::Connection &conn)
|
||||||
load(conn, *m_classes);
|
load(conn, *m_classes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PgDatabaseCatalog::loadDatabases(Pgsql::Connection &conn)
|
||||||
|
{
|
||||||
|
if (!m_databases)
|
||||||
|
m_databases = std::make_shared<PgDatabaseContainer>(shared_from_this());
|
||||||
|
|
||||||
|
load(conn, *m_databases);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PgDatabaseCatalog::loadNamespaces(Pgsql::Connection &conn)
|
||||||
|
{
|
||||||
|
if (!m_namespaces)
|
||||||
|
m_namespaces = std::make_shared<PgNamespaceContainer>(shared_from_this());
|
||||||
|
|
||||||
|
load(conn, *m_namespaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PgDatabaseCatalog::loadTypes(Pgsql::Connection &conn)
|
||||||
|
{
|
||||||
|
if (!m_types)
|
||||||
|
m_types = std::make_shared<PgTypeContainer>(shared_from_this());
|
||||||
|
|
||||||
|
load(conn, *m_types);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const QString& PgDatabaseCatalog::serverVersionString() const
|
const QString& PgDatabaseCatalog::serverVersionString() const
|
||||||
{
|
{
|
||||||
return m_serverVersionString;
|
return m_serverVersionString;
|
||||||
|
|
@ -131,14 +163,9 @@ int PgDatabaseCatalog::serverVersion() const
|
||||||
return m_serverVersion;
|
return m_serverVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const PgTypeContainer> PgDatabaseCatalog::types() const
|
std::shared_ptr<const PgAttributeContainer> PgDatabaseCatalog::attributes() const
|
||||||
{
|
{
|
||||||
return m_types;
|
return m_attributes;
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<const PgDatabaseContainer> PgDatabaseCatalog::databases() const
|
|
||||||
{
|
|
||||||
return m_databases;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const PgAuthIdContainer> PgDatabaseCatalog::authIds() const
|
std::shared_ptr<const PgAuthIdContainer> PgDatabaseCatalog::authIds() const
|
||||||
|
|
@ -150,3 +177,19 @@ std::shared_ptr<const PgClassContainer> PgDatabaseCatalog::classes() const
|
||||||
{
|
{
|
||||||
return m_classes;
|
return m_classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<const PgDatabaseContainer> PgDatabaseCatalog::databases() const
|
||||||
|
{
|
||||||
|
return m_databases;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<const PgNamespaceContainer> PgDatabaseCatalog::namespaces() const
|
||||||
|
{
|
||||||
|
return m_namespaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<const PgTypeContainer> PgDatabaseCatalog::types() const
|
||||||
|
{
|
||||||
|
return m_types;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,11 @@ namespace Pgsql {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PgAttributeContainer;
|
||||||
class PgAuthIdContainer;
|
class PgAuthIdContainer;
|
||||||
class PgClassContainer;
|
class PgClassContainer;
|
||||||
class PgDatabaseContainer;
|
class PgDatabaseContainer;
|
||||||
|
class PgNamespaceContainer;
|
||||||
class PgTypeContainer;
|
class PgTypeContainer;
|
||||||
|
|
||||||
class PgDatabaseCatalog: public std::enable_shared_from_this<PgDatabaseCatalog> {
|
class PgDatabaseCatalog: public std::enable_shared_from_this<PgDatabaseCatalog> {
|
||||||
|
|
@ -27,32 +29,41 @@ public:
|
||||||
|
|
||||||
|
|
||||||
void loadAll(Pgsql::Connection &conn);
|
void loadAll(Pgsql::Connection &conn);
|
||||||
void loadInfo(Pgsql::Connection &conn);
|
|
||||||
void loadTypes(Pgsql::Connection &conn);
|
void loadAttributes(Pgsql::Connection &conn);
|
||||||
void loadDatabases(Pgsql::Connection &conn);
|
|
||||||
void loadAuthIds(Pgsql::Connection &conn);
|
void loadAuthIds(Pgsql::Connection &conn);
|
||||||
void loadClasses(Pgsql::Connection &conn);
|
void loadClasses(Pgsql::Connection &conn);
|
||||||
|
void loadDatabases(Pgsql::Connection &conn);
|
||||||
|
void loadInfo(Pgsql::Connection &conn);
|
||||||
|
void loadNamespaces(Pgsql::Connection &conn);
|
||||||
|
void loadTypes(Pgsql::Connection &conn);
|
||||||
|
|
||||||
const QString& serverVersionString() const;
|
const QString& serverVersionString() const;
|
||||||
int serverVersion() const;
|
int serverVersion() const;
|
||||||
|
|
||||||
std::shared_ptr<const PgTypeContainer> types() const;
|
std::shared_ptr<const PgAttributeContainer> attributes() const;
|
||||||
std::shared_ptr<const PgDatabaseContainer> databases() const;
|
|
||||||
std::shared_ptr<const PgAuthIdContainer> authIds() const;
|
std::shared_ptr<const PgAuthIdContainer> authIds() const;
|
||||||
std::shared_ptr<const PgClassContainer> classes() const;
|
std::shared_ptr<const PgClassContainer> classes() const;
|
||||||
|
std::shared_ptr<const PgDatabaseContainer> databases() const;
|
||||||
|
std::shared_ptr<const PgNamespaceContainer> namespaces() const;
|
||||||
|
std::shared_ptr<const PgTypeContainer> types() const;
|
||||||
private:
|
private:
|
||||||
QString m_serverVersionString;
|
QString m_serverVersionString;
|
||||||
int m_serverVersion;
|
int m_serverVersion;
|
||||||
std::shared_ptr<PgTypeContainer> m_types;
|
|
||||||
std::shared_ptr<PgDatabaseContainer> m_databases;
|
std::shared_ptr<PgAttributeContainer> m_attributes;
|
||||||
std::shared_ptr<PgAuthIdContainer> m_authIds;
|
std::shared_ptr<PgAuthIdContainer> m_authIds;
|
||||||
std::shared_ptr<PgClassContainer> m_classes;
|
std::shared_ptr<PgClassContainer> m_classes;
|
||||||
|
std::shared_ptr<PgDatabaseContainer> m_databases;
|
||||||
|
std::shared_ptr<PgNamespaceContainer> m_namespaces;
|
||||||
|
std::shared_ptr<PgTypeContainer> m_types;
|
||||||
};
|
};
|
||||||
|
|
||||||
QString getRoleNameFromOid(const PgDatabaseCatalog &cat, Oid oid);
|
QString getRoleNameFromOid(const PgDatabaseCatalog &cat, Oid oid);
|
||||||
QString getRoleDisplayString(const PgDatabaseCatalog &cat, Oid oid);
|
QString getRoleDisplayString(const PgDatabaseCatalog &cat, Oid oid);
|
||||||
QString getNamespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid);
|
QString getNamespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid);
|
||||||
QString getTablespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid);
|
QString getTablespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid);
|
||||||
|
QString getTypeDisplayString(const PgDatabaseCatalog &cat, Oid oid);
|
||||||
|
|
||||||
|
|
||||||
#endif // PGSQLDATABASECATALOGUE_H
|
#endif // PGSQLDATABASECATALOGUE_H
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,8 @@
|
||||||
|
|
||||||
PgNamespace::PgNamespace() = default;
|
PgNamespace::PgNamespace() = default;
|
||||||
|
|
||||||
|
bool PgNamespace::isSystemCatalog() const
|
||||||
|
{
|
||||||
|
return name == "pg_catalog"
|
||||||
|
|| name == "information_schema";
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,21 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <libpq-fe.h>
|
#include <libpq-fe.h>
|
||||||
|
|
||||||
class PgNamespace
|
class PgNamespace {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
PgNamespace();
|
PgNamespace();
|
||||||
|
|
||||||
|
Oid oid = InvalidOid;
|
||||||
QString name;
|
QString name;
|
||||||
Oid owner = InvalidOid;
|
Oid owner = InvalidOid;
|
||||||
QString acl;
|
QString acl;
|
||||||
|
|
||||||
|
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 PgNamespace &rhs) const { return oid < rhs.oid; }
|
||||||
|
|
||||||
|
bool isSystemCatalog() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PGNAMESPACE_H
|
#endif // PGNAMESPACE_H
|
||||||
|
|
|
||||||
23
pglab/PgNamespaceContainer.cpp
Normal file
23
pglab/PgNamespaceContainer.cpp
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include "PgNamespaceContainer.h"
|
||||||
|
#include "Pgsql_Col.h"
|
||||||
|
#include "Pgsql_Result.h"
|
||||||
|
#include "Pgsql_Value.h"
|
||||||
|
|
||||||
|
std::string PgNamespaceContainer::getLoadQuery() const
|
||||||
|
{
|
||||||
|
return "SELECT oid, nspname, nspowner, nspacl FROM pg_catalog.pg_namespace";
|
||||||
|
}
|
||||||
|
|
||||||
|
void PgNamespaceContainer::load(const Pgsql::Result &res)
|
||||||
|
{
|
||||||
|
const int n_rows = res.rows();
|
||||||
|
m_container.clear();
|
||||||
|
m_container.reserve(n_rows);
|
||||||
|
for (auto row : res) {
|
||||||
|
Pgsql::Col col(row);
|
||||||
|
PgNamespace v;
|
||||||
|
col >> v.oid >> v.name >> v.owner >> v.acl;
|
||||||
|
m_container.push_back(v);
|
||||||
|
}
|
||||||
|
std::sort(m_container.begin(), m_container.end());
|
||||||
|
}
|
||||||
24
pglab/PgNamespaceContainer.h
Normal file
24
pglab/PgNamespaceContainer.h
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef PGNAMESPACECONTAINER_H
|
||||||
|
#define PGNAMESPACECONTAINER_H
|
||||||
|
|
||||||
|
#include "PgNamespace.h"
|
||||||
|
#include "PgContainer.h"
|
||||||
|
|
||||||
|
namespace Pgsql {
|
||||||
|
|
||||||
|
class Result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class PgNamespaceContainer: public PgContainer<PgNamespace> {
|
||||||
|
public:
|
||||||
|
using PgContainer<PgNamespace>::PgContainer;
|
||||||
|
|
||||||
|
virtual std::string getLoadQuery() const override;
|
||||||
|
virtual void load(const Pgsql::Result &res) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // PGNAMESPACECONTAINER_H
|
||||||
|
|
@ -1,5 +1,56 @@
|
||||||
#include "PgType.h"
|
#include "PgType.h"
|
||||||
#include "Pgsql_Connection.h"
|
#include "Pgsql_Connection.h"
|
||||||
|
|
||||||
|
void operator<<(TypCategory &s, const Pgsql::Value &v)
|
||||||
|
{
|
||||||
|
//s = static_cast<T>(v);
|
||||||
|
const char *c = v.c_str();
|
||||||
|
switch (*c) {
|
||||||
|
case 'A':
|
||||||
|
s = TypCategory::Array;
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
s = TypCategory::Boolean;
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
s = TypCategory::DateTime;
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
s = TypCategory::Enum;
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
s = TypCategory::Geometric;
|
||||||
|
break;
|
||||||
|
case 'I':
|
||||||
|
s = TypCategory::NetworkAddress;
|
||||||
|
break;
|
||||||
|
case 'N':
|
||||||
|
s = TypCategory::Numeric;
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
s = TypCategory::Pseudo;
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
s = TypCategory::Range;
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
s = TypCategory::String;
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
s = TypCategory::Timespan;
|
||||||
|
break;
|
||||||
|
case 'U':
|
||||||
|
s = TypCategory::UserDefined;
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
s = TypCategory::BitString;
|
||||||
|
break;
|
||||||
|
case 'X':
|
||||||
|
s = TypCategory::Unknown;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PgType::PgType() = default;
|
PgType::PgType() = default;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,41 @@
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <libpq-fe.h>
|
#include <libpq-fe.h>
|
||||||
|
#include "Pgsql_Value.h"
|
||||||
|
|
||||||
|
enum class TypCategory {
|
||||||
|
Array,
|
||||||
|
Boolean,
|
||||||
|
Composite,
|
||||||
|
DateTime,
|
||||||
|
Enum,
|
||||||
|
Geometric,
|
||||||
|
NetworkAddress,
|
||||||
|
Numeric,
|
||||||
|
Pseudo,
|
||||||
|
Range,
|
||||||
|
String,
|
||||||
|
Timespan,
|
||||||
|
UserDefined,
|
||||||
|
BitString,
|
||||||
|
Unknown
|
||||||
|
};
|
||||||
|
|
||||||
|
void operator<<(TypCategory &s, const Pgsql::Value &v);
|
||||||
|
|
||||||
|
|
||||||
class PgType {
|
class PgType {
|
||||||
public:
|
public:
|
||||||
PgType();
|
PgType();
|
||||||
|
|
||||||
Oid oid = InvalidOid;
|
Oid oid = InvalidOid;
|
||||||
QString typname;//"name";"NO"
|
QString name;//"name";"NO"
|
||||||
Oid typnamespace = InvalidOid;//"oid";"NO"
|
Oid typnamespace = InvalidOid;//"oid";"NO"
|
||||||
Oid typowner = InvalidOid;//"oid";"NO"
|
Oid owner = InvalidOid;//"oid";"NO"
|
||||||
short typlen = -1;//"smallint";"NO"
|
short len = -1;//"smallint";"NO"
|
||||||
bool typbyval = false;//"boolean";"NO"
|
bool byval = false;//"boolean";"NO"
|
||||||
QString typtype;//""char"";"NO"
|
QString type;//""char"";"NO"
|
||||||
QString typcategory;//""char"";"NO"
|
TypCategory category;//""char"";"NO"
|
||||||
bool typispreferred = false;//"boolean";"NO"
|
bool typispreferred = false;//"boolean";"NO"
|
||||||
bool typisdefined = false;//"boolean";"NO"
|
bool typisdefined = false;//"boolean";"NO"
|
||||||
QString typdelim;//""char"";"NO"
|
QString typdelim;//""char"";"NO"
|
||||||
|
|
@ -41,7 +63,7 @@ public:
|
||||||
QString typacl;//"ARRAY";"YES"
|
QString typacl;//"ARRAY";"YES"
|
||||||
|
|
||||||
bool operator==(Oid _oid) const { return oid == _oid; }
|
bool operator==(Oid _oid) const { return oid == _oid; }
|
||||||
bool operator==(const QString &n) const { return typname == n; }
|
bool operator==(const QString &n) const { return name == n; }
|
||||||
bool operator<(Oid _oid) const { return oid < _oid; }
|
bool operator<(Oid _oid) const { return oid < _oid; }
|
||||||
bool operator<(const PgType &rhs) const { return oid < rhs.oid; }
|
bool operator<(const PgType &rhs) const { return oid < rhs.oid; }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -44,13 +44,13 @@ void PgTypeContainer::load(const Pgsql::Result &res)
|
||||||
for (auto row : res) {
|
for (auto row : res) {
|
||||||
PgType v;
|
PgType v;
|
||||||
v.oid << row.get(0); // InvalidOid;
|
v.oid << row.get(0); // InvalidOid;
|
||||||
v.typname << row.get(1); //. operator QString(); // "name";"NO"
|
v.name << row.get(1); //. operator QString(); // "name";"NO"
|
||||||
v.typnamespace << row.get(2); // InvalidOid;//"oid";"NO"
|
v.typnamespace << row.get(2); // InvalidOid;//"oid";"NO"
|
||||||
v.typowner << row.get(3); // InvalidOid;//"oid";"NO"
|
v.owner << row.get(3); // InvalidOid;//"oid";"NO"
|
||||||
v.typlen << row.get(4); // -1;//"smallint";"NO"
|
v.len << row.get(4); // -1;//"smallint";"NO"
|
||||||
v.typbyval << row.get(5); // false;//"boolean";"NO"
|
v.byval << row.get(5); // false;//"boolean";"NO"
|
||||||
v.typtype << row.get(6);//""char"";"NO"
|
v.type << row.get(6);//""char"";"NO"
|
||||||
v.typcategory << row.get(7);//""char"";"NO"
|
v.category << row.get(7);//""char"";"NO"
|
||||||
v.typispreferred << row.get(8); //false;//"boolean";"NO"
|
v.typispreferred << row.get(8); //false;//"boolean";"NO"
|
||||||
v.typisdefined << row.get(9); //false;//"boolean";"NO"
|
v.typisdefined << row.get(9); //false;//"boolean";"NO"
|
||||||
v.typdelim << row.get(10); //""char"";"NO"
|
v.typdelim << row.get(10); //""char"";"NO"
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include "PgType.h"
|
#include "PgType.h"
|
||||||
#include "PgContainer.h"
|
#include "PgContainer.h"
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace Pgsql {
|
namespace Pgsql {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
#include "ResultTableModelUtil.h"
|
#include "ResultTableModelUtil.h"
|
||||||
|
#include <QTableView>
|
||||||
|
#include <QHeaderView>
|
||||||
|
|
||||||
using namespace Pgsql;
|
using namespace Pgsql;
|
||||||
|
|
||||||
|
|
@ -55,3 +57,36 @@ QString FormatBoolForDisplay(bool v)
|
||||||
return v ? "TRUE" : "FALSE";
|
return v ? "TRUE" : "FALSE";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//<widget class="QTableView" name="ResultView">
|
||||||
|
// <property name="font">
|
||||||
|
// <font>
|
||||||
|
// <family>Source Sans Pro</family>
|
||||||
|
// <pointsize>10</pointsize>
|
||||||
|
// </font>
|
||||||
|
// </property>
|
||||||
|
// <property name="editTriggers">
|
||||||
|
// <set>QAbstractItemView::NoEditTriggers</set>
|
||||||
|
// </property>
|
||||||
|
// <property name="verticalScrollMode">
|
||||||
|
// <enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||||
|
// </property>
|
||||||
|
// <property name="horizontalScrollMode">
|
||||||
|
// <enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||||
|
// </property>
|
||||||
|
// <property name="wordWrap">
|
||||||
|
// <bool>false</bool>
|
||||||
|
// </property>
|
||||||
|
// <attribute name="verticalHeaderDefaultSectionSize">
|
||||||
|
// <number>20</number>
|
||||||
|
// </attribute>
|
||||||
|
// <attribute name="verticalHeaderMinimumSectionSize">
|
||||||
|
// <number>16</number>
|
||||||
|
// </attribute>
|
||||||
|
//</widget>
|
||||||
|
void SetTableViewDefault(QTableView *tv)
|
||||||
|
{
|
||||||
|
tv->setAlternatingRowColors(true);
|
||||||
|
tv->verticalHeader()->setMinimumSectionSize(16);
|
||||||
|
tv->verticalHeader()->setDefaultSectionSize(20);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,3 +21,5 @@ inline QColor GetDefaultNumericColor() { return Qt::darkGreen; }
|
||||||
|
|
||||||
QString FormatBoolForDisplay(bool v);
|
QString FormatBoolForDisplay(bool v);
|
||||||
|
|
||||||
|
class QTableView;
|
||||||
|
void SetTableViewDefault(QTableView *tv);
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ void SqlSyntaxHighlighter::setTypes(const PgTypeContainer& types)
|
||||||
{
|
{
|
||||||
m_typeNames.clear();
|
m_typeNames.clear();
|
||||||
for (auto &e : types) {
|
for (auto &e : types) {
|
||||||
m_typeNames.insert(e.typname);
|
m_typeNames.insert(e.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
#include "TablesPage.h"
|
#include "TablesPage.h"
|
||||||
#include "ui_TablesPage.h"
|
#include "ui_TablesPage.h"
|
||||||
|
|
||||||
|
#include "PgAttribute.h"
|
||||||
#include "TablesTableModel.h"
|
#include "TablesTableModel.h"
|
||||||
|
#include "ResultTableModelUtil.h"
|
||||||
|
#include "ColumnTableModel.h"
|
||||||
|
|
||||||
TablesPage::TablesPage(QWidget *parent) :
|
TablesPage::TablesPage(QWidget *parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
|
|
@ -9,9 +12,22 @@ TablesPage::TablesPage(QWidget *parent) :
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
SetTableViewDefault(ui->tableListTable);
|
||||||
m_tablesModel = new TablesTableModel(this);
|
m_tablesModel = new TablesTableModel(this);
|
||||||
ui->tableListTable->setModel(m_tablesModel);
|
ui->tableListTable->setModel(m_tablesModel);
|
||||||
|
|
||||||
|
SetTableViewDefault(ui->columnsTable);
|
||||||
|
m_columnsModel = new ColumnTableModel(this);
|
||||||
|
ui->columnsTable->setModel(m_columnsModel);
|
||||||
|
|
||||||
|
connect(ui->tableListTable->selectionModel(), &QItemSelectionModel::currentRowChanged, this,
|
||||||
|
&TablesPage::on_tableListTable_currentRowChanged);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TablesPage::~TablesPage()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TablesPage::setCatalog(std::shared_ptr<PgDatabaseCatalog> cat)
|
void TablesPage::setCatalog(std::shared_ptr<PgDatabaseCatalog> cat)
|
||||||
|
|
@ -20,7 +36,10 @@ void TablesPage::setCatalog(std::shared_ptr<PgDatabaseCatalog> cat)
|
||||||
m_tablesModel->setCatalog(cat);
|
m_tablesModel->setCatalog(cat);
|
||||||
}
|
}
|
||||||
|
|
||||||
TablesPage::~TablesPage()
|
void TablesPage::on_tableListTable_currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous)
|
||||||
{
|
{
|
||||||
delete ui;
|
if (current.row() != previous.row()) {
|
||||||
|
Oid table_oid = m_tablesModel->getTableOid(current.row());
|
||||||
|
m_columnsModel->setData(m_catalog, table_oid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ class TablesPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
class TablesTableModel;
|
class TablesTableModel;
|
||||||
|
class ColumnTableModel;
|
||||||
class PgDatabaseCatalog;
|
class PgDatabaseCatalog;
|
||||||
|
|
||||||
class TablesPage : public QWidget
|
class TablesPage : public QWidget
|
||||||
|
|
@ -24,6 +25,11 @@ private:
|
||||||
Ui::TablesPage *ui;
|
Ui::TablesPage *ui;
|
||||||
std::shared_ptr<PgDatabaseCatalog> m_catalog;
|
std::shared_ptr<PgDatabaseCatalog> m_catalog;
|
||||||
TablesTableModel* m_tablesModel = nullptr;
|
TablesTableModel* m_tablesModel = nullptr;
|
||||||
|
ColumnTableModel* m_columnsModel = nullptr;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void on_tableListTable_currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TABLESPAGE_H
|
#endif // TABLESPAGE_H
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,10 @@
|
||||||
#include "PgDatabaseCatalog.h"
|
#include "PgDatabaseCatalog.h"
|
||||||
#include "PgClass.h"
|
#include "PgClass.h"
|
||||||
#include "PgClassContainer.h"
|
#include "PgClassContainer.h"
|
||||||
|
#include "PgNamespace.h"
|
||||||
|
#include "PgNamespaceContainer.h"
|
||||||
#include "Pgsql_declare.h"
|
#include "Pgsql_declare.h"
|
||||||
|
#include <QBrush>
|
||||||
|
|
||||||
TablesTableModel::TablesTableModel(QObject *parent)
|
TablesTableModel::TablesTableModel(QObject *parent)
|
||||||
: BaseTableModel(parent)
|
: BaseTableModel(parent)
|
||||||
|
|
@ -44,6 +47,9 @@ QVariant TablesTableModel::headerData(int section, Qt::Orientation orientation,
|
||||||
case NameCol:
|
case NameCol:
|
||||||
v = tr("Name");
|
v = tr("Name");
|
||||||
break;
|
break;
|
||||||
|
case NamespaceCol:
|
||||||
|
v = tr("Schema");
|
||||||
|
break;
|
||||||
case OwnerCol:
|
case OwnerCol:
|
||||||
v = tr("Owner");
|
v = tr("Owner");
|
||||||
break;
|
break;
|
||||||
|
|
@ -80,6 +86,7 @@ Oid TablesTableModel::getType(int column) const
|
||||||
case TablespaceCol:
|
case TablespaceCol:
|
||||||
case OwnerCol:
|
case OwnerCol:
|
||||||
case NameCol:
|
case NameCol:
|
||||||
|
case NamespaceCol:
|
||||||
case OptionsCol:
|
case OptionsCol:
|
||||||
case AclCol:
|
case AclCol:
|
||||||
default:
|
default:
|
||||||
|
|
@ -94,7 +101,10 @@ QVariant TablesTableModel::getData(const QModelIndex &index) const
|
||||||
const auto &t = m_tables[index.row()];
|
const auto &t = m_tables[index.row()];
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case NameCol:
|
case NameCol:
|
||||||
v = formatTableName(t);
|
v = t.name; //formatTableName(t);
|
||||||
|
break;
|
||||||
|
case NamespaceCol:
|
||||||
|
v = getNamespaceDisplayString(*m_catalog, t.relnamespace);
|
||||||
break;
|
break;
|
||||||
case OwnerCol:
|
case OwnerCol:
|
||||||
v = getRoleDisplayString(*m_catalog, t.owner);
|
v = getRoleDisplayString(*m_catalog, t.owner);
|
||||||
|
|
@ -113,9 +123,33 @@ QVariant TablesTableModel::getData(const QModelIndex &index) const
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Oid TablesTableModel::getTableOid(int row) const
|
||||||
|
{
|
||||||
|
return m_tables[row].oid;
|
||||||
|
}
|
||||||
|
|
||||||
QString TablesTableModel::formatTableName(const PgClass &cls) const
|
QString TablesTableModel::formatTableName(const PgClass &cls) const
|
||||||
{
|
{
|
||||||
const char * format = "%2 (%1)";
|
const char * format = "%2 (%1)";
|
||||||
QString ns_name = getNamespaceDisplayString(*m_catalog, cls.relnamespace);
|
QString ns_name = getNamespaceDisplayString(*m_catalog, cls.relnamespace);
|
||||||
return QString(format).arg(ns_name).arg(cls.name);
|
return QString(format).arg(ns_name).arg(cls.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariant TablesTableModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
|
||||||
|
if (role == Qt::ForegroundRole) {
|
||||||
|
|
||||||
|
const auto &t = m_tables[index.row()];
|
||||||
|
auto ns = m_catalog->namespaces()->getByKey(t.relnamespace);
|
||||||
|
if (ns.isSystemCatalog()) {
|
||||||
|
switch (index.column()) {
|
||||||
|
case NameCol:
|
||||||
|
case NamespaceCol:
|
||||||
|
return QBrush(Qt::blue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return BaseTableModel::data(index, role);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ class TablesTableModel: public BaseTableModel
|
||||||
public:
|
public:
|
||||||
enum e_Columns : int {
|
enum e_Columns : int {
|
||||||
NameCol, ///< either table, ns.table or table (ns) depending on settings/filters
|
NameCol, ///< either table, ns.table or table (ns) depending on settings/filters
|
||||||
|
NamespaceCol,
|
||||||
OwnerCol,
|
OwnerCol,
|
||||||
TablespaceCol,
|
TablespaceCol,
|
||||||
OptionsCol,
|
OptionsCol,
|
||||||
|
|
@ -30,6 +31,8 @@ public:
|
||||||
int rowCount(const QModelIndex &parent) const override;
|
int rowCount(const QModelIndex &parent) const override;
|
||||||
int columnCount(const QModelIndex &parent) const override;
|
int columnCount(const QModelIndex &parent) const override;
|
||||||
|
|
||||||
|
virtual QVariant data(const QModelIndex &index, int role) const override;
|
||||||
|
Oid getTableOid(int row) const;
|
||||||
protected:
|
protected:
|
||||||
virtual Oid getType(int column) const override;
|
virtual Oid getType(int column) const override;
|
||||||
virtual QVariant getData(const QModelIndex &index) const override;
|
virtual QVariant getData(const QModelIndex &index) const override;
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,8 @@ void TypeSelectionItemModel::setTypeList(std::shared_ptr<const PgTypeContainer>
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
m_types.clear();
|
m_types.clear();
|
||||||
for (const auto &e : *types) {
|
for (const auto &e : *types) {
|
||||||
if (e.typcategory != "A" && e.typtype != "c") {
|
if (e.category != TypCategory::Array && e.type != "c") {
|
||||||
m_types.push_back(e.typname);
|
m_types.push_back(e.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::sort(m_types.begin(), m_types.end());
|
std::sort(m_types.begin(), m_types.end());
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,12 @@ SOURCES += main.cpp\
|
||||||
TablesPage.cpp \
|
TablesPage.cpp \
|
||||||
PgClassContainer.cpp \
|
PgClassContainer.cpp \
|
||||||
TablesTableModel.cpp \
|
TablesTableModel.cpp \
|
||||||
PgDatabaseCatalog.cpp
|
PgDatabaseCatalog.cpp \
|
||||||
|
PgNamespaceContainer.cpp \
|
||||||
|
ColumnTableModel.cpp \
|
||||||
|
PgAttribute.cpp \
|
||||||
|
PgContainer.cpp \
|
||||||
|
PgAttributeContainer.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
QueryResultModel.h \
|
QueryResultModel.h \
|
||||||
|
|
@ -117,7 +122,11 @@ HEADERS += \
|
||||||
TablesPage.h \
|
TablesPage.h \
|
||||||
PgClassContainer.h \
|
PgClassContainer.h \
|
||||||
TablesTableModel.h \
|
TablesTableModel.h \
|
||||||
PgDatabaseCatalog.h
|
PgDatabaseCatalog.h \
|
||||||
|
PgNamespaceContainer.h \
|
||||||
|
ColumnTableModel.h \
|
||||||
|
PgAttribute.h \
|
||||||
|
PgAttributeContainer.h
|
||||||
|
|
||||||
FORMS += mainwindow.ui \
|
FORMS += mainwindow.ui \
|
||||||
DatabaseWindow.ui \
|
DatabaseWindow.ui \
|
||||||
|
|
@ -136,12 +145,27 @@ RESOURCES += \
|
||||||
QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS,5.01
|
QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS,5.01
|
||||||
|
|
||||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../core/release/ -lcore
|
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../core/release/ -lcore
|
||||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../core/debug/ -L$$OUT_PWD/../pgsql/debug/ -lcore -lpgsql
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../core/debug/ -lcore
|
||||||
|
|
||||||
INCLUDEPATH += $$PWD/../core $$PWD/../pgsql
|
INCLUDEPATH += $$PWD/../core
|
||||||
DEPENDPATH += $$PWD/../core $$PWD/../pgsql
|
DEPENDPATH += $$PWD/../core
|
||||||
|
|
||||||
win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/release/libcore.a
|
win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/release/libcore.a
|
||||||
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/debug/libcore.a
|
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/debug/libcore.a
|
||||||
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/release/core.lib
|
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/release/core.lib
|
||||||
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/debug/core.lib $$OUT_PWD/../pgsql/debug/pgsql.lib
|
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/debug/core.lib
|
||||||
|
|
||||||
|
|
||||||
|
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../pgsql/release/ -lpgsql
|
||||||
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../pgsql/debug/ -lpgsql
|
||||||
|
else:unix:!macx: LIBS += -L$$OUT_PWD/../pgsql/ -lpgsql
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/../pgsql
|
||||||
|
DEPENDPATH += $$PWD/../pgsql
|
||||||
|
|
||||||
|
win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pgsql/release/libpgsql.a
|
||||||
|
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pgsql/debug/libpgsql.a
|
||||||
|
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pgsql/release/pgsql.lib
|
||||||
|
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pgsql/debug/pgsql.lib
|
||||||
|
else:unix:!macx: PRE_TARGETDEPS += $$OUT_PWD/../pgsql/libpgsql.a
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ namespace Pgsql {
|
||||||
|
|
||||||
class Col {
|
class Col {
|
||||||
public:
|
public:
|
||||||
explicit Col(Pgsql::Row &r)
|
explicit Col(const Pgsql::Row &r)
|
||||||
: row(r)
|
: row(r)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
@ -17,16 +17,10 @@ namespace Pgsql {
|
||||||
return row.get(++col);
|
return row.get(++col);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Pgsql::Row &row;
|
const Pgsql::Row &row;
|
||||||
int col = -1;
|
int col = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
// template <typename T>
|
|
||||||
// void operator<<(T &s, Col &c)
|
|
||||||
// {
|
|
||||||
// s << c.nextValue();
|
|
||||||
// }
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Col& operator>>(Col &c, T &s)
|
Col& operator>>(Col &c, T &s)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue