Added dependants tab to table page
Retrieves all foreignkeys pointing to the current table and shows the tables they are foreignkeys of.
This commit is contained in:
parent
b90df1cd77
commit
8dd13d103e
10 changed files with 268 additions and 4 deletions
57
pglab/DependantsPage.cpp
Normal file
57
pglab/DependantsPage.cpp
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
#include "DependantsPage.h"
|
||||||
|
|
||||||
|
#include "ResultTableModelUtil.h"
|
||||||
|
#include "UserConfiguration.h"
|
||||||
|
#include "catalog/PgClass.h"
|
||||||
|
//#include "SqlCodePreview.h"
|
||||||
|
#include "DependantsTableModel.h"
|
||||||
|
#include "CustomFilterSortModel.h"
|
||||||
|
#include "CustomDataRole.h"
|
||||||
|
#include "PgLabTableView.h"
|
||||||
|
//#include "catalog/PgProcContainer.h"
|
||||||
|
#include <QStringBuilder>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
DependantsPage::DependantsPage(QWidget *parent)
|
||||||
|
: CatalogPageBase(parent)
|
||||||
|
{
|
||||||
|
m_model = new DependantsTableModel(this);
|
||||||
|
m_sortFilterProxy->setSourceModel(m_model);
|
||||||
|
|
||||||
|
// connect(m_tableView->selectionModel(), &QItemSelectionModel::selectionChanged,
|
||||||
|
// this, &DependentsPage::tableView_selectionChanged);
|
||||||
|
// connect(m_model, &DependentsTableModel::modelReset, m_definitionView, &SqlCodePreview::clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DependantsPage::catalogSet()
|
||||||
|
{
|
||||||
|
m_model->setCatalog(m_catalog);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DependantsPage::setFilter(const std::optional<PgClass> &cls)
|
||||||
|
{
|
||||||
|
m_model->loadForTable(cls ? cls->oid() : InvalidOid);
|
||||||
|
m_tableView->resizeColumnsToContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//void DependentsPage::tableView_selectionChanged(const QItemSelection &/*selected*/, const QItemSelection &/*deselected*/)
|
||||||
|
//{
|
||||||
|
// auto rijen = selectedRows();
|
||||||
|
|
||||||
|
// QString drops;
|
||||||
|
// QString creates;
|
||||||
|
// for (auto rij : rijen) {
|
||||||
|
// auto&& t = m_model->trigger(rij);
|
||||||
|
// drops += t.dropSql() % "\n";
|
||||||
|
// creates += t.createSql() % "\n";
|
||||||
|
|
||||||
|
// const PgProc *proc = m_catalog->procs()->getByKey(t.foid);
|
||||||
|
// if (proc) {
|
||||||
|
// creates += "\n" % proc->createSql() % "\n";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// m_definitionView->setPlainText(drops % "\n" % creates);
|
||||||
|
//}
|
||||||
30
pglab/DependantsPage.h
Normal file
30
pglab/DependantsPage.h
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef DEPENDENTSPAGE_H
|
||||||
|
#define DEPENDENTSPAGE_H
|
||||||
|
|
||||||
|
#include "widgets/CatalogPageBase.h"
|
||||||
|
|
||||||
|
class PgClass;
|
||||||
|
class DependantsTableModel;
|
||||||
|
class QItemSelection;
|
||||||
|
|
||||||
|
class DependantsPage : public CatalogPageBase {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DependantsPage(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
void setFilter(const std::optional<PgClass> &cls);
|
||||||
|
signals:
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void catalogSet() override;
|
||||||
|
private:
|
||||||
|
DependantsTableModel *m_model = nullptr;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
// void tableView_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // DEPENDENTSPAGE_H
|
||||||
94
pglab/DependantsTableModel.cpp
Normal file
94
pglab/DependantsTableModel.cpp
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
#include "DependantsTableModel.h"
|
||||||
|
#include "catalog/PgDatabaseCatalog.h"
|
||||||
|
#include "catalog/PgConstraintContainer.h"
|
||||||
|
#include "catalog/PgClassContainer.h"
|
||||||
|
|
||||||
|
|
||||||
|
DependantsTableModel::DependantsTableModel(QObject *parent)
|
||||||
|
: QAbstractTableModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void DependantsTableModel::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat)
|
||||||
|
{
|
||||||
|
if (cat != m_catalog) {
|
||||||
|
m_catalog = cat;
|
||||||
|
refreshConnection = connect(m_catalog.get(), &PgDatabaseCatalog::refreshed,
|
||||||
|
this, &DependantsTableModel::refresh);
|
||||||
|
}
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DependantsTableModel::loadForTable(Oid table_id)
|
||||||
|
{
|
||||||
|
if (table_id != tableId) {
|
||||||
|
tableId = table_id;
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant DependantsTableModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
if (orientation == Qt::Horizontal) {
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
switch (section) {
|
||||||
|
case NameCol: return tr("Table");
|
||||||
|
case NamespaceCol: return tr("Namespace");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
int DependantsTableModel::rowCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return dependants.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int DependantsTableModel::columnCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return colCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant DependantsTableModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
auto&& data = dependants[index.row()];
|
||||||
|
switch (index.column()) {
|
||||||
|
case NameCol: return data.tableName;
|
||||||
|
case NamespaceCol: return data.namespaceName;
|
||||||
|
case ConstraintCol: return data.constraintName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void DependantsTableModel::refresh()
|
||||||
|
{
|
||||||
|
if (!m_catalog)
|
||||||
|
return;
|
||||||
|
|
||||||
|
beginResetModel();
|
||||||
|
dependants.clear();
|
||||||
|
|
||||||
|
if (tableId != InvalidOid) {
|
||||||
|
auto&& constraints = m_catalog->constraints();
|
||||||
|
auto fkeys = constraints->getReferencedForRelation(tableId);
|
||||||
|
|
||||||
|
dependants.reserve(static_cast<int>(fkeys.size()));
|
||||||
|
auto&& tables = m_catalog->classes();
|
||||||
|
for (auto&& fk : fkeys) {
|
||||||
|
//dependants.append(
|
||||||
|
auto t = tables->getByKey(fk.relid);
|
||||||
|
if (t) {
|
||||||
|
Item i;
|
||||||
|
i.tableOid = t->oid();
|
||||||
|
i.tableName = t->objectName();
|
||||||
|
i.namespaceName = t->nsName();
|
||||||
|
i.constraintName = fk.objectName();
|
||||||
|
dependants.push_back(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
55
pglab/DependantsTableModel.h
Normal file
55
pglab/DependantsTableModel.h
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
#ifndef DEPENDENTSTABLEMODEL_H
|
||||||
|
#define DEPENDENTSTABLEMODEL_H
|
||||||
|
|
||||||
|
#include <QAbstractTableModel>
|
||||||
|
#include <memory>
|
||||||
|
#include "catalog/PgClass.h"
|
||||||
|
#include "Pgsql_oids.h"
|
||||||
|
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
class PgDatabaseCatalog;
|
||||||
|
|
||||||
|
class DependantsTableModel: public QAbstractTableModel {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum e_Columns : int {
|
||||||
|
NameCol, //
|
||||||
|
NamespaceCol, // Schema
|
||||||
|
ConstraintCol,
|
||||||
|
|
||||||
|
colCount
|
||||||
|
};
|
||||||
|
|
||||||
|
DependantsTableModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
void setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat);
|
||||||
|
void loadForTable(Oid table_id);
|
||||||
|
|
||||||
|
// Basic functionality:
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
QVariant data(const QModelIndex &index, int role) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<const PgDatabaseCatalog> m_catalog;
|
||||||
|
QMetaObject::Connection refreshConnection;
|
||||||
|
Oid tableId;
|
||||||
|
|
||||||
|
class Item {
|
||||||
|
public:
|
||||||
|
Oid tableOid;
|
||||||
|
QString tableName;
|
||||||
|
QString namespaceName;
|
||||||
|
QString constraintName;
|
||||||
|
};
|
||||||
|
|
||||||
|
QVector<Item> dependants;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void refresh();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DEPENDENTSTABLEMODEL_H
|
||||||
|
|
@ -33,11 +33,11 @@ public:
|
||||||
|
|
||||||
ProcTableModel(QObject *parent = nullptr);
|
ProcTableModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
|
||||||
void setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat);
|
void setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat);
|
||||||
void setNamespaceFilter(NamespaceFilter filter);
|
void setNamespaceFilter(NamespaceFilter filter);
|
||||||
|
|
||||||
// Basic functionality:
|
// Basic functionality:
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
QVariant data(const QModelIndex &index, int role) const override;
|
QVariant data(const QModelIndex &index, int role) const override;
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ win32:RC_ICONS += pglab.ico
|
||||||
SOURCES += main.cpp\
|
SOURCES += main.cpp\
|
||||||
ConnectionConfigurationWidget.cpp \
|
ConnectionConfigurationWidget.cpp \
|
||||||
ConnectionController.cpp \
|
ConnectionController.cpp \
|
||||||
|
DependantsPage.cpp \
|
||||||
|
DependantsTableModel.cpp \
|
||||||
NotificationListWidget.cpp \
|
NotificationListWidget.cpp \
|
||||||
NotificationModel.cpp \
|
NotificationModel.cpp \
|
||||||
NotificationService.cpp \
|
NotificationService.cpp \
|
||||||
|
|
@ -88,6 +90,8 @@ PropertyProxyModel.cpp \
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
ConnectionConfigurationWidget.h \
|
ConnectionConfigurationWidget.h \
|
||||||
ConnectionController.h \
|
ConnectionController.h \
|
||||||
|
DependantsPage.h \
|
||||||
|
DependantsTableModel.h \
|
||||||
IDatabaseWindow.h \
|
IDatabaseWindow.h \
|
||||||
NotificationListWidget.h \
|
NotificationListWidget.h \
|
||||||
NotificationModel.h \
|
NotificationModel.h \
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include "ColumnPage.h"
|
#include "ColumnPage.h"
|
||||||
#include "ColumnTableModel.h"
|
#include "ColumnTableModel.h"
|
||||||
#include "ConstraintModel.h"
|
#include "ConstraintModel.h"
|
||||||
|
#include "DependantsPage.h"
|
||||||
#include "PgLabTableView.h"
|
#include "PgLabTableView.h"
|
||||||
#include "PropertiesPage.h"
|
#include "PropertiesPage.h"
|
||||||
#include "ResultTableModelUtil.h"
|
#include "ResultTableModelUtil.h"
|
||||||
|
|
@ -62,6 +63,9 @@ CatalogTablesPage::CatalogTablesPage(QWidget *parent)
|
||||||
m_triggerPage = new TriggerPage(this);
|
m_triggerPage = new TriggerPage(this);
|
||||||
m_detailsTabs->addTab(m_triggerPage, "");
|
m_detailsTabs->addTab(m_triggerPage, "");
|
||||||
|
|
||||||
|
m_dependentsPage = new DependantsPage(this);
|
||||||
|
m_detailsTabs->addTab(m_dependentsPage, "");
|
||||||
|
|
||||||
// SQL tab
|
// SQL tab
|
||||||
m_tableSql = new SqlCodePreview(this);
|
m_tableSql = new SqlCodePreview(this);
|
||||||
m_detailsTabs->addTab(m_tableSql, "");
|
m_detailsTabs->addTab(m_tableSql, "");
|
||||||
|
|
@ -97,6 +101,7 @@ void CatalogTablesPage::retranslateUi(bool /*all*/)
|
||||||
set_tabtext(m_indexPage, QApplication::translate("TablesPage", "Indexes", nullptr));
|
set_tabtext(m_indexPage, QApplication::translate("TablesPage", "Indexes", nullptr));
|
||||||
set_tabtext(m_propertiesPage, QApplication::translate("TablesPage", "Properties", nullptr));
|
set_tabtext(m_propertiesPage, QApplication::translate("TablesPage", "Properties", nullptr));
|
||||||
set_tabtext(m_triggerPage, QApplication::translate("TablesPage", "Triggers", nullptr));
|
set_tabtext(m_triggerPage, QApplication::translate("TablesPage", "Triggers", nullptr));
|
||||||
|
set_tabtext(m_dependentsPage, QApplication::translate("TablesPage", "Dependants", nullptr));
|
||||||
set_tabtext(m_tableSql, QApplication::translate("TablesPage", "SQL", nullptr));
|
set_tabtext(m_tableSql, QApplication::translate("TablesPage", "SQL", nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,6 +114,7 @@ void CatalogTablesPage::setCatalog(std::shared_ptr<PgDatabaseCatalog> cat)
|
||||||
m_constraintPage->setCatalog(cat);
|
m_constraintPage->setCatalog(cat);
|
||||||
m_indexPage->setCatalog(cat);
|
m_indexPage->setCatalog(cat);
|
||||||
m_triggerPage->setCatalog(cat);
|
m_triggerPage->setCatalog(cat);
|
||||||
|
m_dependentsPage->setCatalog(cat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CatalogTablesPage::setNamespaceFilter(NamespaceFilter filter)
|
void CatalogTablesPage::setNamespaceFilter(NamespaceFilter filter)
|
||||||
|
|
@ -159,6 +165,7 @@ void CatalogTablesPage::selectedTableChanged(const std::optional<PgClass> &table
|
||||||
m_constraintPage->setFilter(table);
|
m_constraintPage->setFilter(table);
|
||||||
m_indexPage->setFilter(table);
|
m_indexPage->setFilter(table);
|
||||||
m_triggerPage->setFilter(table);
|
m_triggerPage->setFilter(table);
|
||||||
|
m_dependentsPage->setFilter(table);
|
||||||
|
|
||||||
updateSqlTab(table);
|
updateSqlTab(table);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ class CatalogIndexPage;
|
||||||
class ColumnPage;
|
class ColumnPage;
|
||||||
class ColumnTableModel;
|
class ColumnTableModel;
|
||||||
class ConstraintModel;
|
class ConstraintModel;
|
||||||
|
class DependantsPage;
|
||||||
class PgClass;
|
class PgClass;
|
||||||
class PgDatabaseCatalog;
|
class PgDatabaseCatalog;
|
||||||
class PgLabTableView;
|
class PgLabTableView;
|
||||||
|
|
@ -48,6 +49,7 @@ private:
|
||||||
CatalogIndexPage *m_indexPage = nullptr;
|
CatalogIndexPage *m_indexPage = nullptr;
|
||||||
PropertiesPage *m_propertiesPage = nullptr;
|
PropertiesPage *m_propertiesPage = nullptr;
|
||||||
TriggerPage *m_triggerPage = nullptr;
|
TriggerPage *m_triggerPage = nullptr;
|
||||||
|
DependantsPage *m_dependentsPage = nullptr;
|
||||||
SqlCodePreview *m_tableSql = nullptr;
|
SqlCodePreview *m_tableSql = nullptr;
|
||||||
|
|
||||||
std::shared_ptr<PgDatabaseCatalog> m_catalog;
|
std::shared_ptr<PgDatabaseCatalog> m_catalog;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "PgConstraintContainer.h"
|
#include "PgConstraintContainer.h"
|
||||||
#include "Pgsql_Col.h"
|
#include "Pgsql_Col.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
std::string PgConstraintContainer::getLoadQuery() const
|
std::string PgConstraintContainer::getLoadQuery() const
|
||||||
{
|
{
|
||||||
|
|
@ -56,9 +57,11 @@ std::vector<PgConstraint> PgConstraintContainer::getFKeyForTableColumn(Oid relid
|
||||||
std::vector<PgConstraint> PgConstraintContainer::getConstraintsForRelation(Oid relid) const
|
std::vector<PgConstraint> PgConstraintContainer::getConstraintsForRelation(Oid relid) const
|
||||||
{
|
{
|
||||||
std::vector<PgConstraint> result;
|
std::vector<PgConstraint> result;
|
||||||
for (const auto &e : m_container)
|
// for (const auto &e : m_container)
|
||||||
if (e.relid == relid)
|
// if (e.relid == relid)
|
||||||
result.push_back(e);
|
// result.push_back(e);
|
||||||
|
std::copy_if(m_container.begin(), m_container.end(), std::back_inserter(result),
|
||||||
|
[relid] (auto && item) { return item.relid == relid; });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,3 +76,14 @@ std::optional<PgConstraint> PgConstraintContainer::getPrimaryForRelation(Oid rel
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<PgConstraint> PgConstraintContainer::getReferencedForRelation(Oid relid) const
|
||||||
|
{
|
||||||
|
std::vector<PgConstraint> result;
|
||||||
|
// for (const auto &e : m_container)
|
||||||
|
// if (e.frelid == relid)
|
||||||
|
// result.push_back(e);
|
||||||
|
std::copy_if(m_container.begin(), m_container.end(), std::back_inserter(result),
|
||||||
|
[relid] (auto && item) { return item.frelid == relid; });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ public:
|
||||||
|
|
||||||
std::vector<PgConstraint> getConstraintsForRelation(Oid relid) const;
|
std::vector<PgConstraint> getConstraintsForRelation(Oid relid) const;
|
||||||
std::optional<PgConstraint> getPrimaryForRelation(Oid relid) const;
|
std::optional<PgConstraint> getPrimaryForRelation(Oid relid) const;
|
||||||
|
std::vector<PgConstraint> getReferencedForRelation(Oid relid) const;
|
||||||
protected:
|
protected:
|
||||||
virtual PgConstraint loadElem(const Pgsql::Row &row) override;
|
virtual PgConstraint loadElem(const Pgsql::Row &row) override;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue