Added list of constraints to the tables page.
Last column shows the full textual definition until I have decided on a better way to visualize the details.
This commit is contained in:
parent
22db22c6b1
commit
a99f059b70
27 changed files with 663 additions and 22 deletions
14
pglab/ApplicationWindow.cpp
Normal file
14
pglab/ApplicationWindow.cpp
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#include "ApplicationWindow.h"
|
||||
#include "ui_ApplicationWindow.h"
|
||||
|
||||
ApplicationWindow::ApplicationWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::ApplicationWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
ApplicationWindow::~ApplicationWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
22
pglab/ApplicationWindow.h
Normal file
22
pglab/ApplicationWindow.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef APPLICATIONWINDOW_H
|
||||
#define APPLICATIONWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
namespace Ui {
|
||||
class ApplicationWindow;
|
||||
}
|
||||
|
||||
class ApplicationWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ApplicationWindow(QWidget *parent = 0);
|
||||
~ApplicationWindow();
|
||||
|
||||
private:
|
||||
Ui::ApplicationWindow *ui;
|
||||
};
|
||||
|
||||
#endif // APPLICATIONWINDOW_H
|
||||
145
pglab/ApplicationWindow.ui
Normal file
145
pglab/ApplicationWindow.ui
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ApplicationWindow</class>
|
||||
<widget class="QMainWindow" name="ApplicationWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>314</width>
|
||||
<height>672</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButton">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>314</width>
|
||||
<height>25</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
@ -83,7 +83,8 @@ QVariant ColumnTableModel::headerData(int section, Qt::Orientation orientation,
|
|||
else if (role == Qt::ToolTipRole) {
|
||||
if (section >= colCount) {
|
||||
const auto &tbl_idx = m_indexes[section - colCount];
|
||||
auto idx_cls = m_catalog->classes()->getByKey(tbl_idx.indexrelid);
|
||||
//auto idx_cls = m_catalog->classes()->getByKey(tbl_idx.indexrelid);
|
||||
auto idx_class_name = getClassDisplayString(*m_catalog, tbl_idx.indexrelid);
|
||||
QString s;
|
||||
if (tbl_idx.isprimary)
|
||||
s = tr("Primary key");
|
||||
|
|
@ -91,7 +92,7 @@ QVariant ColumnTableModel::headerData(int section, Qt::Orientation orientation,
|
|||
s = tr("Unique index");
|
||||
else
|
||||
s = tr("Index");
|
||||
s += "\n" + idx_cls.name;
|
||||
s += "\n" + idx_class_name;
|
||||
v = s;
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>24</height>
|
||||
<height>25</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
|
|
@ -217,6 +217,18 @@
|
|||
<property name="windowTitle">
|
||||
<string>toolBar</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QToolBar {
|
||||
border-top: 1px solid rgb(192, 192, 192);
|
||||
border-bottom: 1px solid rgb(192, 192, 192);
|
||||
padding: 4px;
|
||||
|
||||
}
|
||||
|
||||
QToolButton {
|
||||
border: none;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="movable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
|
|
|
|||
168
pglab/ConstraintModel.cpp
Normal file
168
pglab/ConstraintModel.cpp
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
#include "ConstraintModel.h"
|
||||
#include "ScopeGuard.h"
|
||||
#include "PgDatabaseCatalog.h"
|
||||
#include "PgConstraintContainer.h"
|
||||
#include "Pgsql_oids.h"
|
||||
|
||||
ConstraintModel::ConstraintModel(QObject *parent)
|
||||
: BaseTableModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ConstraintModel::setData(std::shared_ptr<const PgDatabaseCatalog> cat, const PgClass &table)
|
||||
{
|
||||
beginResetModel();
|
||||
SCOPE_EXIT { endResetModel(); };
|
||||
|
||||
m_table = table;
|
||||
m_catalog = cat;
|
||||
m_constraints = cat->constraints()->getConstraintsForRelation(table.oid);
|
||||
|
||||
std::sort(m_constraints.begin(), m_constraints.end(),
|
||||
[] (auto &l, auto &r) {
|
||||
return l.type < r.type ||
|
||||
(l.type == r.type && l.name < r.name);
|
||||
});
|
||||
|
||||
// // hide system columns
|
||||
// auto si = table.hasoids
|
||||
// ? std::remove_if(m_columns.begin(), m_columns.end(),
|
||||
// [](PgAttribute &e) { return e.num <= 0 && e.name != "oid"; })
|
||||
// : std::remove_if(m_columns.begin(), m_columns.end(),
|
||||
// [](PgAttribute &e) { return e.num <= 0; });
|
||||
// // move columns to end and remove them
|
||||
// m_columns.erase(si, 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; });
|
||||
|
||||
// m_indexes = m_catalog->indexes()->getIndexesForTable(table.oid);
|
||||
// std::sort(m_indexes.begin(), m_indexes.end(),
|
||||
// [] (const auto &l, const auto &r) -> bool
|
||||
// {
|
||||
// return l.isprimary > r.isprimary
|
||||
// || (l.isprimary == r.isprimary && l.indexrelid < r.indexrelid);
|
||||
// });
|
||||
|
||||
}
|
||||
|
||||
QVariant ConstraintModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
QVariant v;
|
||||
if (orientation == Qt::Horizontal) {
|
||||
if (role == Qt::DisplayRole) {
|
||||
QString c;
|
||||
switch (section) {
|
||||
case TypeCol:
|
||||
c = tr("Type");
|
||||
break;
|
||||
case NameCol:
|
||||
c = tr("Name");
|
||||
break;
|
||||
case NsCol:
|
||||
c = tr("Schema");
|
||||
break;
|
||||
case SupportingIndexCol:
|
||||
c = tr("Supporting index");
|
||||
break;
|
||||
case DefinitionCol:
|
||||
c = tr("Definition");
|
||||
break;
|
||||
}
|
||||
v = c;
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
int ConstraintModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return m_constraints.size();
|
||||
}
|
||||
|
||||
int ConstraintModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return colCount;
|
||||
}
|
||||
|
||||
//QVariant ConstraintModel::data(const QModelIndex &index, int role) const
|
||||
//{
|
||||
// QVariant v;
|
||||
// if (!index.isValid())
|
||||
// return QVariant();
|
||||
|
||||
// // FIXME: Implement me!
|
||||
// return v;
|
||||
//}
|
||||
|
||||
Oid ConstraintModel::getType(int column) const
|
||||
{
|
||||
Oid oid = Pgsql::varchar_oid;
|
||||
|
||||
return oid;
|
||||
}
|
||||
|
||||
QString IconForConstraintType(ConstraintType ct)
|
||||
{
|
||||
QString s = ":/icons/constraints/";
|
||||
switch (ct) {
|
||||
case ConstraintType::Check:
|
||||
s += "check.png";
|
||||
break;
|
||||
case ConstraintType::ForeignKey:
|
||||
s += "foreignkey.png";
|
||||
break;
|
||||
case ConstraintType::PrimaryKey:
|
||||
s += "primarykey.png";
|
||||
break;
|
||||
case ConstraintType::Unique:
|
||||
s += "unique.png";
|
||||
break;
|
||||
case ConstraintType::ConstraintTrigger:
|
||||
s = "CT";
|
||||
break;
|
||||
case ConstraintType::ExclusionConstraint:
|
||||
s = "XC";
|
||||
break;
|
||||
default:
|
||||
s = "?";
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QVariant ConstraintModel::getData(const QModelIndex &index) const
|
||||
{
|
||||
QVariant v;
|
||||
const int row = index.row();
|
||||
const auto &t = m_constraints[row];
|
||||
|
||||
const int col = index.column();
|
||||
QString s;
|
||||
switch (col) {
|
||||
case TypeCol:
|
||||
s = IconForConstraintType(t.type);
|
||||
break;
|
||||
case NameCol:
|
||||
s = t.name;
|
||||
break;
|
||||
case NsCol:
|
||||
s = getNamespaceDisplayString(*m_catalog, t.connamespace);
|
||||
break;
|
||||
case SupportingIndexCol:
|
||||
s = getIndexDisplayString(*m_catalog, t.indid);
|
||||
break;
|
||||
case DefinitionCol:
|
||||
s = t.definition;
|
||||
break;
|
||||
}
|
||||
v = s;
|
||||
|
||||
return v;
|
||||
}
|
||||
51
pglab/ConstraintModel.h
Normal file
51
pglab/ConstraintModel.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef CONSTRAINTMODEL_H
|
||||
#define CONSTRAINTMODEL_H
|
||||
|
||||
#include "BaseTableModel.h"
|
||||
#include "PgClass.h"
|
||||
#include "PgConstraint.h"
|
||||
#include <QAbstractTableModel>
|
||||
#include <vector>
|
||||
|
||||
class PgDatabaseCatalog;
|
||||
|
||||
class ConstraintModel : public BaseTableModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
enum e_Columns : int {
|
||||
TypeCol,
|
||||
NameCol, ///
|
||||
NsCol, ///
|
||||
SupportingIndexCol,
|
||||
DefinitionCol,
|
||||
colCount };
|
||||
|
||||
explicit ConstraintModel(QObject *parent = nullptr);
|
||||
|
||||
void setData(std::shared_ptr<const PgDatabaseCatalog> cat, const PgClass &table);
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
protected:
|
||||
|
||||
virtual Oid getType(int column) const override;
|
||||
virtual QVariant getData(const QModelIndex &index) const override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<const PgDatabaseCatalog> m_catalog;
|
||||
PgClass m_table;
|
||||
|
||||
using t_Constraints = std::vector<PgConstraint>;
|
||||
t_Constraints m_constraints;
|
||||
};
|
||||
|
||||
#endif // CONSTRAINTMODEL_H
|
||||
59
pglab/IconColumnDelegate.cpp
Normal file
59
pglab/IconColumnDelegate.cpp
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
#include "IconColumnDelegate.h"
|
||||
#include <QPainter>
|
||||
|
||||
IconColumnDelegate::IconColumnDelegate(QWidget *parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
|
||||
IconColumnDelegate::~IconColumnDelegate()
|
||||
{
|
||||
clearCache();
|
||||
}
|
||||
|
||||
void IconColumnDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
if (index.data().canConvert<QString>()) {
|
||||
QString icon_name = qvariant_cast<QString>(index.data());
|
||||
|
||||
|
||||
QIcon* icon = IconColumnDelegate::getIcon(icon_name);
|
||||
if (icon) {
|
||||
if (option.state & QStyle::State_Selected)
|
||||
painter->fillRect(option.rect, option.palette.highlight());
|
||||
icon->paint(painter, option.rect);
|
||||
}
|
||||
else
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
|
||||
} else {
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
}
|
||||
}
|
||||
|
||||
QSize IconColumnDelegate::sizeHint(const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
return QSize(16, 16);
|
||||
}
|
||||
|
||||
|
||||
void IconColumnDelegate::clearCache()
|
||||
{
|
||||
for (auto &e : m_Icons)
|
||||
delete e.
|
||||
second;
|
||||
m_Icons.clear();
|
||||
}
|
||||
|
||||
QIcon* IconColumnDelegate::getIcon(const QString &name) const
|
||||
{
|
||||
auto fr = m_Icons.find(name);
|
||||
if (fr == m_Icons.end()) {
|
||||
// load and insert icon
|
||||
QIcon *icon = new QIcon(name);
|
||||
fr = m_Icons.emplace(name, icon).first;
|
||||
}
|
||||
return fr->second;
|
||||
}
|
||||
29
pglab/IconColumnDelegate.h
Normal file
29
pglab/IconColumnDelegate.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef ICONCOLUMNDELEGATE_H
|
||||
#define ICONCOLUMNDELEGATE_H
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
#include <map>
|
||||
|
||||
/** This class asumes that the string values supplies for the column data
|
||||
* can be Resolved by QIcon to an actual icon. Icons are cached and reused.
|
||||
*
|
||||
*/
|
||||
class IconColumnDelegate: public QStyledItemDelegate {
|
||||
public:
|
||||
IconColumnDelegate(QWidget *parent = nullptr);
|
||||
~IconColumnDelegate();
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
QSize sizeHint(const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
|
||||
void clearCache();
|
||||
private:
|
||||
using t_IconCache = std::map<QString, QIcon*>;
|
||||
|
||||
mutable t_IconCache m_Icons;
|
||||
|
||||
QIcon* getIcon(const QString &name) const;
|
||||
};
|
||||
|
||||
#endif // ICONCOLUMNDELEGATE_H
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
#include <QPushButton>
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QStatusBar>
|
||||
#include <QMessageBox>
|
||||
#include <QTabWidget>
|
||||
#include <QTextCodec>
|
||||
|
|
@ -399,7 +400,10 @@ void QueryTab::explain_ready(ExplainRoot::SPtr explain)
|
|||
ui->explainTreeView->setColumnWidth(5, 80);
|
||||
ui->explainTreeView->setColumnWidth(6, 600);
|
||||
ui->tabWidget->setCurrentWidget(ui->explainTab);
|
||||
// statusBar()->showMessage(tr("Explain ready."));
|
||||
|
||||
auto w = dynamic_cast<QMainWindow*>(this->window());
|
||||
if (w)
|
||||
w->statusBar()->showMessage(tr("Explain ready."));
|
||||
}
|
||||
else {
|
||||
addLog("Explain no result");
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@
|
|||
#include "TablesTableModel.h"
|
||||
#include "ResultTableModelUtil.h"
|
||||
#include "ColumnTableModel.h"
|
||||
#include "ConstraintModel.h"
|
||||
#include "NamespaceFilterWidget.h"
|
||||
#include "IconColumnDelegate.h"
|
||||
|
||||
TablesPage::TablesPage(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
|
|
@ -22,6 +24,13 @@ TablesPage::TablesPage(QWidget *parent) :
|
|||
m_columnsModel = new ColumnTableModel(this);
|
||||
ui->columnsTable->setModel(m_columnsModel);
|
||||
|
||||
SetTableViewDefault(ui->constraintsTable);
|
||||
m_constraintModel = new ConstraintModel(this);
|
||||
auto delegate = new IconColumnDelegate(this);
|
||||
|
||||
ui->constraintsTable->setModel(m_constraintModel);
|
||||
ui->constraintsTable->setItemDelegateForColumn(0, delegate);
|
||||
|
||||
m_namespaceFilterWidget = new NamespaceFilterWidget(this);
|
||||
ui->verticalLayoutTableView->addWidget(m_namespaceFilterWidget);
|
||||
|
||||
|
|
@ -50,5 +59,8 @@ void TablesPage::on_tableListTable_currentRowChanged(const QModelIndex ¤t,
|
|||
PgClass table = m_tablesModel->getTable(current.row());
|
||||
m_columnsModel->setData(m_catalog, table);
|
||||
ui->columnsTable->resizeColumnsToContents();
|
||||
|
||||
m_constraintModel->setData(m_catalog, table);
|
||||
ui->constraintsTable->resizeColumnsToContents();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ class TablesPage;
|
|||
|
||||
class TablesTableModel;
|
||||
class ColumnTableModel;
|
||||
class ConstraintModel;
|
||||
class PgDatabaseCatalog;
|
||||
class NamespaceFilterWidget;
|
||||
|
||||
|
|
@ -27,6 +28,7 @@ private:
|
|||
std::shared_ptr<PgDatabaseCatalog> m_catalog;
|
||||
TablesTableModel* m_tablesModel = nullptr;
|
||||
ColumnTableModel* m_columnsModel = nullptr;
|
||||
ConstraintModel* m_constraintModel = nullptr;
|
||||
NamespaceFilterWidget* m_namespaceFilterWidget;
|
||||
|
||||
private slots:
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
</widget>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="columnsTab">
|
||||
<attribute name="title">
|
||||
|
|
@ -50,6 +50,26 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabConstraints">
|
||||
<attribute name="title">
|
||||
<string>Constraints</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QTableView" name="constraintsTable"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabIndexes">
|
||||
<attribute name="title">
|
||||
<string>Indexes</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QTableView" name="indexesTable"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="propertiesTab">
|
||||
<attribute name="title">
|
||||
<string>Properties</string>
|
||||
|
|
|
|||
BIN
pglab/icons/constraints/check.png
Normal file
BIN
pglab/icons/constraints/check.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 406 B |
BIN
pglab/icons/constraints/foreignkey.png
Normal file
BIN
pglab/icons/constraints/foreignkey.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 299 B |
BIN
pglab/icons/constraints/primarykey.png
Normal file
BIN
pglab/icons/constraints/primarykey.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 443 B |
BIN
pglab/icons/constraints/unique.png
Normal file
BIN
pglab/icons/constraints/unique.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 422 B |
|
|
@ -62,7 +62,10 @@ SOURCES += main.cpp\
|
|||
TablesTableModel.cpp \
|
||||
ColumnTableModel.cpp \
|
||||
NamespaceFilterWidget.cpp \
|
||||
NamespaceItemModel.cpp
|
||||
NamespaceItemModel.cpp \
|
||||
ApplicationWindow.cpp \
|
||||
ConstraintModel.cpp \
|
||||
IconColumnDelegate.cpp
|
||||
|
||||
HEADERS += \
|
||||
QueryResultModel.h \
|
||||
|
|
@ -96,7 +99,10 @@ HEADERS += \
|
|||
TablesTableModel.h \
|
||||
ColumnTableModel.h \
|
||||
NamespaceFilterWidget.h \
|
||||
NamespaceItemModel.h
|
||||
NamespaceItemModel.h \
|
||||
ApplicationWindow.h \
|
||||
ConstraintModel.h \
|
||||
IconColumnDelegate.h
|
||||
|
||||
FORMS += mainwindow.ui \
|
||||
ConnectionManagerWindow.ui \
|
||||
|
|
@ -107,7 +113,8 @@ FORMS += mainwindow.ui \
|
|||
ServerWindow.ui \
|
||||
ProcessStdioWidget.ui \
|
||||
TablesPage.ui \
|
||||
NamespaceFilterWidget.ui
|
||||
NamespaceFilterWidget.ui \
|
||||
ApplicationWindow.ui
|
||||
|
||||
RESOURCES += \
|
||||
resources.qrc
|
||||
|
|
|
|||
|
|
@ -23,5 +23,9 @@
|
|||
<file>icons/delete_connection.png</file>
|
||||
<file>icons/open_query_window.png</file>
|
||||
<file>icons/manage_server.png</file>
|
||||
<file>icons/constraints/check.png</file>
|
||||
<file>icons/constraints/foreignkey.png</file>
|
||||
<file>icons/constraints/primarykey.png</file>
|
||||
<file>icons/constraints/unique.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ SUBDIRS += core \
|
|||
pglablib \
|
||||
pglab
|
||||
|
||||
pglab.depends = core ctk pgsql pglablib
|
||||
pgsql.depends = core
|
||||
pglablib.depends = core pgsql
|
||||
|
||||
|
||||
CONFIG(debug, debug|release) {
|
||||
SUBDIRS += tests
|
||||
|
|
|
|||
|
|
@ -25,6 +25,64 @@ void operator<<(ConstraintType &s, const Pgsql::Value &v)
|
|||
}
|
||||
}
|
||||
|
||||
QString ShortNameForConstraintType(ConstraintType ct)
|
||||
{
|
||||
QString s;
|
||||
switch (ct) {
|
||||
case ConstraintType::Check:
|
||||
s = "C";
|
||||
break;
|
||||
case ConstraintType::ForeignKey:
|
||||
s = "FK";
|
||||
break;
|
||||
case ConstraintType::PrimaryKey:
|
||||
s = "PK";
|
||||
break;
|
||||
case ConstraintType::Unique:
|
||||
s = "U";
|
||||
break;
|
||||
case ConstraintType::ConstraintTrigger:
|
||||
s = "CT";
|
||||
break;
|
||||
case ConstraintType::ExclusionConstraint:
|
||||
s = "XC";
|
||||
break;
|
||||
default:
|
||||
s = "?";
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
QString LongNameForConstraintType(ConstraintType ct)
|
||||
{
|
||||
QString s;
|
||||
switch (ct) {
|
||||
case ConstraintType::Check:
|
||||
s = "check";
|
||||
break;
|
||||
case ConstraintType::ForeignKey:
|
||||
s = "foreign key";
|
||||
break;
|
||||
case ConstraintType::PrimaryKey:
|
||||
s = "primary key";
|
||||
break;
|
||||
case ConstraintType::Unique:
|
||||
s = "unique";
|
||||
break;
|
||||
case ConstraintType::ConstraintTrigger:
|
||||
s = "constraint trigger";
|
||||
break;
|
||||
case ConstraintType::ExclusionConstraint:
|
||||
s = "exclusion constraint";
|
||||
break;
|
||||
default:
|
||||
s = "?";
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void operator<<(ForeignKeyAction &s, const Pgsql::Value &v)
|
||||
{
|
||||
const char *c = v.c_str();
|
||||
|
|
@ -64,6 +122,7 @@ void operator<<(ForeignKeyMatch &s, const Pgsql::Value &v)
|
|||
}
|
||||
|
||||
|
||||
|
||||
PgConstraint::PgConstraint()
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -9,16 +9,19 @@
|
|||
#include <vector>
|
||||
|
||||
enum class ConstraintType {
|
||||
Check, // c
|
||||
ForeignKey, // f
|
||||
PrimaryKey, // p
|
||||
ForeignKey, // f
|
||||
Unique, // u
|
||||
Check, // c
|
||||
ConstraintTrigger, // t
|
||||
ExclusionConstraint, // x
|
||||
};
|
||||
|
||||
void operator<<(ConstraintType &s, const Pgsql::Value &v);
|
||||
|
||||
QString ShortNameForConstraintType(ConstraintType ct);
|
||||
QString LongNameForConstraintType(ConstraintType ct);
|
||||
|
||||
|
||||
enum class ForeignKeyAction {
|
||||
NoAction, // a
|
||||
|
|
|
|||
|
|
@ -63,3 +63,12 @@ const PgConstraint* PgConstraintContainer::getFKeyForTableColumn(Oid relid, int1
|
|||
// });
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<PgConstraint> PgConstraintContainer::getConstraintsForRelation(Oid relid) const
|
||||
{
|
||||
std::vector<PgConstraint> result;
|
||||
for (const auto &e : m_container)
|
||||
if (e.relid == relid)
|
||||
result.push_back(e);
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ public:
|
|||
virtual std::string getLoadQuery() const override;
|
||||
//std::vector<PgConstraint> getIndexesForTable(Oid table_oid) const;
|
||||
const PgConstraint* getFKeyForTableColumn(Oid relid, int16_t attnum) const;
|
||||
|
||||
std::vector<PgConstraint> getConstraintsForRelation(Oid relid) const;
|
||||
protected:
|
||||
virtual PgConstraint loadElem(const Pgsql::Row &row) override;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -38,19 +38,31 @@ QString getRoleDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
|||
|
||||
QString getNamespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
||||
{
|
||||
//QString name;
|
||||
QString result;
|
||||
auto nss = cat.namespaces();
|
||||
auto ns = nss->getByKey(oid);
|
||||
// if (auth_ids) {
|
||||
// const PgAuthId& auth_id = auth_ids->getByOid(oid);
|
||||
// if (auth_id.valid()) {
|
||||
// name = auth_id.name;
|
||||
// }
|
||||
// }
|
||||
//return name;
|
||||
// TODO load list and lookup name
|
||||
return ns.name; //QString("ns %1").arg(oid);
|
||||
result = ns.name; //QString("ns %1").arg(oid);
|
||||
return result;
|
||||
}
|
||||
|
||||
QString getClassDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
||||
{
|
||||
QString result;
|
||||
auto l = cat.classes();
|
||||
auto e = l->getByKey(oid);
|
||||
result = e.name;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
QString getIndexDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
||||
{
|
||||
QString result;
|
||||
// auto l = cat.indexes();
|
||||
// auto e = l->getByKey(oid);
|
||||
// if (e)
|
||||
result = getClassDisplayString(cat, oid);
|
||||
return result;
|
||||
}
|
||||
|
||||
QString getTablespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ QString getRoleDisplayString(const PgDatabaseCatalog &cat, Oid oid);
|
|||
QString getNamespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid);
|
||||
QString getTablespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid);
|
||||
QString getTypeDisplayString(const PgDatabaseCatalog &cat, Oid oid, int32_t typmod = -1);
|
||||
QString getIndexDisplayString(const PgDatabaseCatalog &cat, Oid oid);
|
||||
QString getClassDisplayString(const PgDatabaseCatalog &cat, Oid oid);
|
||||
|
||||
|
||||
#endif // PGSQLDATABASECATALOGUE_H
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue