Restructuring catalog tabs

- Moved detail tabs of table to their own components
- Table list has become seperate component on seperate tab
- Table list does not use designer anymore
- Moved sequences and functions tabs into the catalog inspector
This commit is contained in:
eelke 2019-02-09 09:49:27 +01:00
parent a704332342
commit 42432b06a9
31 changed files with 598 additions and 472 deletions

View file

@ -1,154 +1,64 @@
#include "CatalogInspector.h" #include "CatalogInspector.h"
#include "ui_TablesPage.h"
#include "catalog/PgAttribute.h"
#include "catalog/PgDatabaseCatalog.h"
#include "catalog/PgIndexContainer.h"
#include "catalog/PgTriggerContainer.h"
#include "ColumnPage.h"
#include "ColumnTableModel.h"
#include "ConstraintModel.h"
#include "IconColumnDelegate.h"
#include "IndexModel.h"
#include "OpenDatabase.h" #include "OpenDatabase.h"
#include "PgLabItemDelegate.h"
#include "PropertiesPage.h"
#include "ResultTableModelUtil.h"
#include "SqlFormattingUtils.h"
#include "SqlSyntaxHighlighter.h"
#include "TriggerPage.h"
#include "UserConfiguration.h" #include "UserConfiguration.h"
#include "SqlCodePreview.h"
#include <QStringBuilder>
#include <unordered_set>
#include "plugin_support/IPluginContentWidgetContext.h" #include "plugin_support/IPluginContentWidgetContext.h"
#include "widgets/CatalogFunctionsPage.h"
#include "widgets/CatalogSequencesPage.h"
#include "widgets/CatalogTablesPage.h"
#include <QApplication>
#include <QTabWidget>
#include <QStringBuilder>
#include <QVBoxLayout>
#include <unordered_set>
CatalogInspector::CatalogInspector(IPluginContentWidgetContext *context_, QWidget *parent) CatalogInspector::CatalogInspector(IPluginContentWidgetContext *context_, QWidget *parent)
: PluginContentWidget(context_, parent) : PluginContentWidget(context_, parent)
, ui(new Ui::TablesPage)
{ {
ui->setupUi(this); m_tabWidget = new QTabWidget(this);
m_tablesPage = new CatalogTablesPage(this);
m_functionsPage = new CatalogFunctionsPage(this);
m_sequencesPage = new CatalogSequencesPage(this);
SetTableViewDefault(ui->tableListTable); auto layout = new QVBoxLayout(this);
m_tablesModel = new TablesTableModel(this); setLayout(layout);
ui->tableListTable->setModel(m_tablesModel); layout->addWidget(m_tabWidget);
ui->tableListTable->setItemDelegate(new PgLabItemDelegate(this)); m_tabWidget->addTab(m_tablesPage, "");
ui->tableListTable->setSortingEnabled(true); m_tabWidget->addTab(m_functionsPage, "");
ui->tableListTable->sortByColumn(0, Qt::AscendingOrder); m_tabWidget->addTab(m_sequencesPage, "");
ui->tableListTable->setSelectionBehavior(QAbstractItemView::SelectRows);
// Constraints
SetTableViewDefault(ui->constraintsTable);
m_constraintModel = new ConstraintModel(this);
ui->constraintsTable->setModel(m_constraintModel);
ui->constraintsTable->setItemDelegateForColumn(0, new IconColumnDelegate(this));
// Indexes
SetTableViewDefault(ui->indexesTable);
m_indexModel = new IndexModel(this);
ui->indexesTable->setModel(m_indexModel);
ui->indexesTable->setItemDelegate(new PgLabItemDelegate(this));
ui->indexesTable->setItemDelegateForColumn(0, new IconColumnDelegate(this));
// Set code editor fonts
QFont code_font = UserConfiguration::instance()->codeFont();
ui->constraintSqlEdit->setFont(code_font);
ui->indexSqlEdit->setFont(code_font);
// Connect signals
// ---------------
// Table selection
connect(ui->tableListTable->selectionModel(), &QItemSelectionModel::currentRowChanged, this,
&CatalogInspector::tableListTable_currentRowChanged);
connect(m_tablesModel, &QAbstractItemModel::layoutChanged,
this, &CatalogInspector::tableListTable_layoutChanged);
//layoutChanged(const QList<QPersistentModelIndex> &parents = ..., QAbstractItemModel::LayoutChangeHint hint = ...)
connect(ui->constraintsTable->selectionModel(), &QItemSelectionModel::selectionChanged, this,
&CatalogInspector::constraintsTable_selectionChanged);
connect(ui->constraintsTable->model(), &QAbstractItemModel::modelReset, this,
&CatalogInspector::constraintsTable_modelReset);
// React to changes in de selected indexes, does not trigger when model is reset
connect(ui->indexesTable->selectionModel(), &QItemSelectionModel::selectionChanged, this,
&CatalogInspector::indexesTable_selectionChanged);
// Capture model reset independently
connect(ui->indexesTable->model(), &QAbstractItemModel::modelReset, this,
&CatalogInspector::indexesTable_modelReset);
// Non designer based code
// - Columns page
m_columnsPage = new ColumnPage(this);
ui->twDetails->insertTab(0, m_columnsPage, "");
// - Properties page
m_propertiesPage = new PropertiesPage(this);
m_propertiesPage->setSourceModel(m_tablesModel);
ui->twDetails->addTab(m_propertiesPage, "");
connect(ui->tableListTable->selectionModel(), &QItemSelectionModel::currentRowChanged,
m_propertiesPage, &PropertiesPage::setActiveRow);
// - Trigger page
m_triggerPage = new TriggerPage(this);
ui->twDetails->addTab(m_triggerPage, "");
// SQL tab
m_sqlCodePreview = new SqlCodePreview(this);
ui->twDetails->addTab(m_sqlCodePreview, "");
// Force focus on columns tab by default
ui->twDetails->setCurrentIndex(0);
auto db = context_->getObject<OpenDatabase>(); auto db = context_->getObject<OpenDatabase>();
setCatalog(db->catalog()); setCatalog(db->catalog());
retranslateUi(false); retranslateUi(false);
} }
void CatalogInspector::retranslateUi(bool all) void CatalogInspector::retranslateUi(bool all)
{ {
if (all) m_tablesPage->retranslateUi(all);
ui->retranslateUi(this);
auto set_tabtext = [this] (QWidget *widget, QString translation) {
ui->twDetails->setTabText(ui->twDetails->indexOf(widget), translation);
};
set_tabtext(m_columnsPage, QApplication::translate("TablesPage", "Columns", nullptr));
set_tabtext(m_propertiesPage, QApplication::translate("TablesPage", "Properties", nullptr));
set_tabtext(m_triggerPage, QApplication::translate("TablesPage", "Triggers", nullptr));
set_tabtext(m_sqlCodePreview, QApplication::translate("TablesPage", "SQL", nullptr));
m_tabWidget->setTabText(m_tabWidget->indexOf(m_tablesPage),
QApplication::translate("CatalogInspector", "Tables", nullptr));
m_tabWidget->setTabText(m_tabWidget->indexOf(m_functionsPage),
QApplication::translate("CatalogInspector", "Functions", nullptr));
m_tabWidget->setTabText(m_tabWidget->indexOf(m_sequencesPage),
QApplication::translate("CatalogInspector", "Sequences", nullptr));
} }
CatalogInspector::~CatalogInspector() CatalogInspector::~CatalogInspector()
{ {
delete ui;
} }
void CatalogInspector::setCatalog(std::shared_ptr<PgDatabaseCatalog> cat) void CatalogInspector::setCatalog(std::shared_ptr<PgDatabaseCatalog> cat)
{ {
m_catalog = cat; m_catalog = cat;
m_tablesModel->setCatalog(cat); m_tablesPage->setCatalog(cat);
ui->tableListTable->resizeColumnsToContents(); m_functionsPage->setCatalog(cat);
m_sequencesPage->setCatalog(cat);
m_triggerPage->setCatalog(cat);
auto highlighter = new SqlSyntaxHighlighter(ui->constraintSqlEdit->document());
highlighter->setTypes(*cat->types());
highlighter = new SqlSyntaxHighlighter(ui->indexSqlEdit->document());
highlighter->setTypes(*cat->types());
} }
void CatalogInspector::setNamespaceFilter(TablesTableModel::NamespaceFilter filter) void CatalogInspector::setNamespaceFilter(TablesTableModel::NamespaceFilter filter)
{ {
m_tablesModel->setNamespaceFilter(filter); m_tablesPage->setNamespaceFilter(filter);
QString hint = "Catalog instpector"; QString hint = "Catalog instpector";
QString caption = "Inspector"; QString caption = "Inspector";
switch (filter) { switch (filter) {
@ -166,147 +76,6 @@ void CatalogInspector::setNamespaceFilter(TablesTableModel::NamespaceFilter filt
context()->setCaption(this, caption, hint); context()->setCaption(this, caption, hint);
} }
void CatalogInspector::tableListTable_currentRowChanged(const QModelIndex &current, const QModelIndex &previous)
{
if (current.row() != previous.row()) {
if (current.isValid()) {
PgClass table = m_tablesModel->getTable(current.row());
selectedTableChanged(table);
}
else
selectedTableChanged({});
}
}
void CatalogInspector::tableListTable_layoutChanged(const QList<QPersistentModelIndex> &, QAbstractItemModel::LayoutChangeHint )
{
auto&& index = ui->tableListTable->selectionModel()->currentIndex();
if (index.isValid()) {
PgClass table = m_tablesModel->getTable(index.row());
selectedTableChanged(table);
}
else
selectedTableChanged({});
}
void CatalogInspector::selectedTableChanged(const std::optional<PgClass> &table)
{
m_columnsPage->setData(m_catalog, table);
m_constraintModel->setData(m_catalog, table);
ui->constraintsTable->resizeColumnsToContents();
ui->constraintsTable->selectionModel()->reset();
m_indexModel->setData(m_catalog, table);
ui->indexesTable->resizeColumnsToContents();
m_triggerPage->setFilter(table);
updateSqlTab(table);
}
void CatalogInspector::constraintsTable_selectionChanged(const QItemSelection &/*selected*/, const QItemSelection &/*deselected*/)
{
const auto indexes = ui->constraintsTable->selectionModel()->selectedIndexes();
std::unordered_set<int> rijen;
for (const auto &e : indexes)
rijen.insert(e.row());
QString drops;
QString creates;
for (auto rij : rijen) {
const PgConstraint constraint = m_constraintModel->constraint(rij);
drops += getDropConstraintDefinition(*m_catalog, constraint) % "\n";
creates += getAlterTableConstraintDefinition(*m_catalog, constraint) % "\n";
}
ui->constraintSqlEdit->setPlainText(drops % "\n" % creates);
}
void CatalogInspector::constraintsTable_modelReset()
{
ui->constraintSqlEdit->clear();
}
void CatalogInspector::indexesTable_selectionChanged(const QItemSelection &/*selected*/, const QItemSelection &/*deselected*/)
{
const auto indexes = ui->indexesTable->selectionModel()->selectedIndexes();
std::unordered_set<int> rijen;
for (const auto &e : indexes)
rijen.insert(e.row());
QString drops;
QString creates;
for (auto rij : rijen) {
const PgIndex index = m_indexModel->getIndex(rij);
drops += index.dropSql() % "\n";
creates += index.createSql() % "\n";
}
ui->indexSqlEdit->setPlainText(drops % "\n" % creates);
}
void CatalogInspector::indexesTable_modelReset()
{
ui->indexSqlEdit->clear();
}
void CatalogInspector::on_tableListTable_doubleClicked(const QModelIndex &index)
{
PgClass table = m_tablesModel->getTable(index.row());
if (table.oid() != InvalidOid) {
context()->moduleAction("pglab.crudpage", "open", {
{ "oid", table.oid() }
});
}
}
void CatalogInspector::updateSqlTab(const std::optional<PgClass> &table)
{
if (!table.has_value()) {
m_sqlCodePreview->clear();
return;
}
QString drop_sql;
QString create_sql;
// create table
create_sql += table->createSql();
// - columns
// - constraints
// table details (inherits etc)
// Indexes
drop_sql += "-- drop Indexes\n";
create_sql += "-- create Indexes\n";
auto && indexes = m_catalog->indexes()->getIndexesForTable(table->oid());
for (auto && index : indexes) {
drop_sql += index.dropSql() % "\n";
create_sql += index.createSql() % "\n";
}
// Triggers
drop_sql += "-- drop Triggers\n";
create_sql += "-- create Triggers\n";
auto && triggers = m_catalog->triggers()->getTriggersForRelation(table->oid());
for (auto && trg : triggers) {
drop_sql += trg.dropSql() % "\n";
create_sql += trg.createSql() % "\n";
}
// Privileges
create_sql += "-- set Privileges\n";
create_sql += table->grantSql() % "\n";
// Comments
create_sql += "-- set Comments table + columns\n";
//
m_sqlCodePreview->setPlainText(drop_sql % "\n\n" % create_sql);
}
void CatalogInspectorModule::init() void CatalogInspectorModule::init()
{ {
registerModuleAction("open", registerModuleAction("open",

View file

@ -3,32 +3,17 @@
#include <QWidget> #include <QWidget>
#include <memory> #include <memory>
#include <optional>
#include <QItemSelection>
#include "TablesTableModel.h" #include "TablesTableModel.h"
#include "plugin_support/PluginContentWidget.h" #include "plugin_support/PluginContentWidget.h"
#include "plugin_support/PluginModule.h" #include "plugin_support/PluginModule.h"
namespace Ui { class CatalogFunctionsPage;
class TablesPage; class CatalogSequencesPage;
} class CatalogTablesPage;
class QTabWidget;
class TablesTableModel; class CatalogInspector : public PluginContentWidget {
class ColumnPage;
class ColumnTableModel;
class ConstraintModel;
class PgDatabaseCatalog;
class NamespaceFilterWidget;
class IndexModel;
class PropertiesPage;
class TriggerPage;
class PgClass;
class SqlCodePreview;
class CatalogInspector : public PluginContentWidget
{
Q_OBJECT Q_OBJECT
public: public:
explicit CatalogInspector(IPluginContentWidgetContext *context, QWidget *parent = nullptr); explicit CatalogInspector(IPluginContentWidgetContext *context, QWidget *parent = nullptr);
~CatalogInspector(); ~CatalogInspector();
@ -36,30 +21,15 @@ public:
void setCatalog(std::shared_ptr<PgDatabaseCatalog> cat); void setCatalog(std::shared_ptr<PgDatabaseCatalog> cat);
void setNamespaceFilter(TablesTableModel::NamespaceFilter filter); void setNamespaceFilter(TablesTableModel::NamespaceFilter filter);
private: private:
Ui::TablesPage *ui; QTabWidget *m_tabWidget = nullptr;
ColumnPage *m_columnsPage; CatalogTablesPage *m_tablesPage = nullptr;
PropertiesPage *m_propertiesPage; CatalogFunctionsPage *m_functionsPage = nullptr;
TriggerPage *m_triggerPage; CatalogSequencesPage *m_sequencesPage = nullptr;
SqlCodePreview *m_sqlCodePreview;
std::shared_ptr<PgDatabaseCatalog> m_catalog; std::shared_ptr<PgDatabaseCatalog> m_catalog;
TablesTableModel* m_tablesModel = nullptr;
ColumnTableModel* m_columnsModel = nullptr;
ConstraintModel* m_constraintModel = nullptr;
IndexModel* m_indexModel = nullptr;
void retranslateUi(bool all = true); void retranslateUi(bool all = true);
void selectedTableChanged(const std::optional<PgClass> &table);
void updateSqlTab(const std::optional<PgClass> &table);
private slots: private slots:
void tableListTable_currentRowChanged(const QModelIndex &current, const QModelIndex &previous);
void tableListTable_layoutChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint);
void constraintsTable_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
void constraintsTable_modelReset();
void indexesTable_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
void indexesTable_modelReset();
void on_tableListTable_doubleClicked(const QModelIndex &index);
}; };
class CatalogInspectorModule: public PluginModule { class CatalogInspectorModule: public PluginModule {

View file

@ -12,8 +12,6 @@
// Pages that should become modules // Pages that should become modules
#include "EditTableWidget.h" #include "EditTableWidget.h"
#include "CodeGenerator.h" #include "CodeGenerator.h"
#include "FunctionsPage.h"
#include "SequencesPage.h"
namespace pg = Pgsql; namespace pg = Pgsql;
@ -76,14 +74,6 @@ void DatabaseWindow::catalogLoaded()
{ "namespace-filter", f } { "namespace-filter", f }
}); });
auto functions_page = new FunctionsPage(this);
functions_page->setCatalog(m_database->catalog());
m_tabWidget->addTab(functions_page, "Functions");
auto sequences_page = new SequencesPage(this);
sequences_page->setCatalog(m_database->catalog());
m_tabWidget->addTab(sequences_page, "Sequences");
newCreateTablePage(); newCreateTablePage();
} catch (const OpenDatabaseException &ex) { } catch (const OpenDatabaseException &ex) {
QMessageBox::critical(this, "Error reading database", ex.text()); QMessageBox::critical(this, "Error reading database", ex.text());

View file

@ -11,7 +11,7 @@
class IconColumnDelegate: public QStyledItemDelegate { class IconColumnDelegate: public QStyledItemDelegate {
public: public:
IconColumnDelegate(QWidget *parent = nullptr); IconColumnDelegate(QWidget *parent = nullptr);
~IconColumnDelegate(); ~IconColumnDelegate() override;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
QSize sizeHint(const QStyleOptionViewItem &option, QSize sizeHint(const QStyleOptionViewItem &option,

View file

@ -1,86 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TablesPage</class>
<widget class="QWidget" name="TablesPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>993</width>
<height>754</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayoutTableView">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QComboBox" name="comboBox"/>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBox_2"/>
</item>
</layout>
</item>
<item>
<widget class="QTableView" name="tableListTable"/>
</item>
</layout>
</widget>
<widget class="QTabWidget" name="twDetails">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tabConstraints">
<attribute name="title">
<string>Constraints</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QSplitter" name="splitter_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QTableView" name="constraintsTable">
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
</widget>
<widget class="QPlainTextEdit" name="constraintSqlEdit"/>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabIndexes">
<attribute name="title">
<string>Indexes</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QSplitter" name="splitter_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QTableView" name="indexesTable"/>
<widget class="QPlainTextEdit" name="indexSqlEdit"/>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -1,47 +1,29 @@
#include "TriggerPage.h" #include "TriggerPage.h"
#include "ResultTableModelUtil.h" #include "ResultTableModelUtil.h"
#include "UserConfiguration.h" #include "UserConfiguration.h"
#include <QTableView>
#include "catalog/PgClass.h" #include "catalog/PgClass.h"
#include "SqlCodePreview.h" #include "SqlCodePreview.h"
#include "TriggerTableModel.h" #include "TriggerTableModel.h"
#include "CustomFilterSortModel.h" #include "CustomFilterSortModel.h"
#include "CustomDataRole.h" #include "CustomDataRole.h"
#include "PgLabItemDelegate.h" #include "PgLabTableView.h"
#include <QStringBuilder> #include <QStringBuilder>
#include <unordered_set> #include <unordered_set>
TriggerPage::TriggerPage(QWidget *parent) TriggerPage::TriggerPage(QWidget *parent)
: QSplitter(Qt::Vertical, parent) : CatalogPageBase(parent)
{ {
m_tableView = new QTableView(this);
m_definitionView = new SqlCodePreview(this);
addWidget(m_tableView);
addWidget(m_definitionView);
SetTableViewDefault(m_tableView);
m_model = new TriggerTableModel(this); m_model = new TriggerTableModel(this);
m_sortFilterProxy = new CustomFilterSortModel(this);
m_sortFilterProxy->setSourceModel(m_model); m_sortFilterProxy->setSourceModel(m_model);
m_tableView->setModel(m_sortFilterProxy);
m_tableView->setSortingEnabled(true);
m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
auto item_delegate = new PgLabItemDelegate(this);
m_tableView->setItemDelegate(item_delegate);
//auto icon_delegate = new IconColumnDelegate(this);
connect(m_tableView->selectionModel(), &QItemSelectionModel::selectionChanged, connect(m_tableView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &TriggerPage::tableView_selectionChanged); this, &TriggerPage::tableView_selectionChanged);
} }
void TriggerPage::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat) void TriggerPage::catalogSet()
{ {
m_catalog = cat; m_model->setCatalog(m_catalog);
m_definitionView->setCatalog(cat);
m_model->setCatalog(cat);
} }
@ -54,10 +36,7 @@ void TriggerPage::setFilter(const std::optional<PgClass> &cls)
void TriggerPage::tableView_selectionChanged(const QItemSelection &/*selected*/, const QItemSelection &/*deselected*/) void TriggerPage::tableView_selectionChanged(const QItemSelection &/*selected*/, const QItemSelection &/*deselected*/)
{ {
auto&& indexes = m_tableView->selectionModel()->selectedIndexes(); auto rijen = selectedRows();
std::unordered_set<int> rijen;
for (const auto &e : indexes)
rijen.insert(m_sortFilterProxy->mapToSource(e).row());
QString drops; QString drops;
QString creates; QString creates;

View file

@ -1,37 +1,27 @@
#ifndef TRIGGERPAGE_H #ifndef TRIGGERPAGE_H
#define TRIGGERPAGE_H #define TRIGGERPAGE_H
#include <QSplitter> #include "widgets/CatalogPageBase.h"
#include <memory>
#include <optional>
class QTableView;
class SqlCodePreview;
class PgDatabaseCatalog;
class PgClass; class PgClass;
class TriggerTableModel; class TriggerTableModel;
class CustomFilterSortModel;
class QItemSelection; class QItemSelection;
class TriggerPage : public QSplitter class TriggerPage : public CatalogPageBase {
{
Q_OBJECT Q_OBJECT
public: public:
explicit TriggerPage(QWidget *parent = nullptr); explicit TriggerPage(QWidget *parent = nullptr);
// TriggerPage(QWidget *parent = nullptr); // TriggerPage(QWidget *parent = nullptr);
void setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat);
void setFilter(const std::optional<PgClass> &cls); void setFilter(const std::optional<PgClass> &cls);
signals: signals:
public slots: public slots:
protected:
void catalogSet() override;
private: private:
QTableView *m_tableView = nullptr;
SqlCodePreview *m_definitionView = nullptr;
TriggerTableModel *m_model = nullptr; TriggerTableModel *m_model = nullptr;
CustomFilterSortModel *m_sortFilterProxy = nullptr;
std::shared_ptr<const PgDatabaseCatalog> m_catalog;
private slots: private slots:
void tableView_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); void tableView_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);

View file

@ -71,12 +71,10 @@ PropertyProxyModel.cpp \
PropertiesPage.cpp \ PropertiesPage.cpp \
PasswordPromptDialog.cpp \ PasswordPromptDialog.cpp \
ProcTableModel.cpp \ ProcTableModel.cpp \
FunctionsPage.cpp \
ColumnPage.cpp \ ColumnPage.cpp \
EditTableWidget.cpp \ EditTableWidget.cpp \
EditColumnTableModel.cpp \ EditColumnTableModel.cpp \
SequenceModel.cpp \ SequenceModel.cpp \
SequencesPage.cpp \
DatabaseWindow.cpp \ DatabaseWindow.cpp \
PgLabTableView.cpp \ PgLabTableView.cpp \
plugin_support/PluginModule.cpp \ plugin_support/PluginModule.cpp \
@ -91,7 +89,13 @@ PropertyProxyModel.cpp \
QueryToolModule.cpp \ QueryToolModule.cpp \
CatalogInspector.cpp \ CatalogInspector.cpp \
plugin_support/StaticAction.cpp \ plugin_support/StaticAction.cpp \
plugin_support/LMainMenu.cpp plugin_support/LMainMenu.cpp \
widgets/CatalogIndexPage.cpp \
widgets/CatalogPageBase.cpp \
widgets/CatalogConstraintPage.cpp \
widgets/CatalogTablesPage.cpp \
widgets/CatalogFunctionsPage.cpp \
widgets/CatalogSequencesPage.cpp
HEADERS += \ HEADERS += \
QueryResultModel.h \ QueryResultModel.h \
@ -140,12 +144,10 @@ CustomDataRole.h \
PropertiesPage.h \ PropertiesPage.h \
PasswordPromptDialog.h \ PasswordPromptDialog.h \
ProcTableModel.h \ ProcTableModel.h \
FunctionsPage.h \
ColumnPage.h \ ColumnPage.h \
EditTableWidget.h \ EditTableWidget.h \
EditColumnTableModel.h \ EditColumnTableModel.h \
SequenceModel.h \ SequenceModel.h \
SequencesPage.h \
DatabaseWindow.h \ DatabaseWindow.h \
PgLabTableView.h \ PgLabTableView.h \
plugin_support/PluginModule.h \ plugin_support/PluginModule.h \
@ -162,7 +164,13 @@ CustomDataRole.h \
QueryToolModule.h \ QueryToolModule.h \
CatalogInspector.h \ CatalogInspector.h \
plugin_support/StaticAction.h \ plugin_support/StaticAction.h \
plugin_support/LMainMenu.h plugin_support/LMainMenu.h \
widgets/CatalogIndexPage.h \
widgets/CatalogPageBase.h \
widgets/CatalogConstraintPage.h \
widgets/CatalogTablesPage.h \
widgets/CatalogFunctionsPage.h \
widgets/CatalogSequencesPage.h
FORMS += \ FORMS += \
ConnectionManagerWindow.ui \ ConnectionManagerWindow.ui \
@ -172,7 +180,6 @@ FORMS += \
BackupDialog.ui \ BackupDialog.ui \
ServerWindow.ui \ ServerWindow.ui \
ProcessStdioWidget.ui \ ProcessStdioWidget.ui \
TablesPage.ui \
NamespaceFilterWidget.ui \ NamespaceFilterWidget.ui \
CrudTab.ui \ CrudTab.ui \
CodeGenerator.ui CodeGenerator.ui

View file

@ -59,6 +59,7 @@ void PluginContentWidgetContextBase::removeContentWidget(PluginContentWidget *wi
m_widgetLst.erase(res); m_widgetLst.erase(res);
} }
void PluginContentWidgetContextBase::addWidgetActionsToToolbar(PluginContentWidget *widget, QToolBar *toolbar) void PluginContentWidgetContextBase::addWidgetActionsToToolbar(PluginContentWidget *widget, QToolBar *toolbar)
{ {
auto && actions = widget->actions(); auto && actions = widget->actions();

View file

@ -8,6 +8,28 @@ class LContextAction;
class QToolBar; class QToolBar;
class QAction; class QAction;
/// Maintains the list of actions added to a toolbar for a specific widget
/// it facilitates the removal of all those actions.
class WidgetToolbarActionList {
public:
QToolBar *m_toolBar;
std::vector<QAction*> m_actions;
void removeAll()
{
// for (auto && a : m_actions)
// m_toolBar->removeAction(a);
}
};
class WidgetToolbarManager {
public:
void addAction(QAction *action, QString section);
private:
};
class LWidgetData { class LWidgetData {
public: public:
LWidgetData(PluginModule *module); LWidgetData(PluginModule *module);
@ -16,6 +38,7 @@ public:
private: private:
PluginModule *m_module; PluginModule *m_module;
WidgetToolbarManager m_toolbarManager;
}; };
/// Provides base implementation of IPluginContentWidgetContext /// Provides base implementation of IPluginContentWidgetContext

View file

@ -27,5 +27,6 @@
<file>icons/constraints/foreignkey.png</file> <file>icons/constraints/foreignkey.png</file>
<file>icons/constraints/primarykey.png</file> <file>icons/constraints/primarykey.png</file>
<file>icons/constraints/unique.png</file> <file>icons/constraints/unique.png</file>
<file>icons/constraints/index.png</file>
</qresource> </qresource>
</RCC> </RCC>

View file

@ -0,0 +1,42 @@
#include "CatalogConstraintPage.h"
#include "ConstraintModel.h"
#include "CustomFilterSortModel.h"
#include "IconColumnDelegate.h"
#include "PgLabTableView.h"
#include "SqlCodePreview.h"
#include <QStringBuilder>
CatalogConstraintPage::CatalogConstraintPage(QWidget *parent)
: CatalogPageBase(parent)
{
m_constraintModel = new ConstraintModel(this);
m_sortFilterProxy->setSourceModel(m_constraintModel);
m_tableView->setItemDelegateForColumn(0, new IconColumnDelegate(this));
connect(m_tableView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &CatalogConstraintPage::tableView_selectionChanged);
}
void CatalogConstraintPage::catalogSet()
{
}
void CatalogConstraintPage::setFilter(const std::optional<PgClass> &cls)
{
m_constraintModel->setData(m_catalog, cls);
m_tableView->resizeColumnsToContents();
}
void CatalogConstraintPage::tableView_selectionChanged(const QItemSelection &/*selected*/, const QItemSelection &/*deselected*/)
{
auto rijen = selectedRows();
QString drops;
QString creates;
for (auto rij : rijen) {
const PgConstraint constraint = m_constraintModel->constraint(rij);
drops += constraint.dropSql() % "\n";
creates += constraint.createSql() % "\n";
}
m_definitionView->setPlainText(drops % "\n" % creates);
}

View file

@ -0,0 +1,29 @@
#ifndef CATALOGCONSTRAINTPAGE_H
#define CATALOGCONSTRAINTPAGE_H
#include "CatalogPageBase.h"
class ConstraintModel;
class PgClass;
class QItemSelection;
class CatalogConstraintPage : public CatalogPageBase {
Q_OBJECT
public:
explicit CatalogConstraintPage(QWidget *parent = nullptr);
void setFilter(const std::optional<PgClass> &cls);
protected:
void catalogSet() override;
private:
ConstraintModel *m_constraintModel = nullptr;
private slots:
void tableView_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
};
#endif // CATALOGCONSTRAINTPAGE_H

View file

@ -1,4 +1,4 @@
#include "FunctionsPage.h" #include "CatalogFunctionsPage.h"
#include "ResultTableModelUtil.h" #include "ResultTableModelUtil.h"
#include "CustomFilterSortModel.h" #include "CustomFilterSortModel.h"
#include "CustomDataRole.h" #include "CustomDataRole.h"
@ -10,7 +10,7 @@
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QTabWidget> #include <QTabWidget>
FunctionsPage::FunctionsPage(QWidget *parent) CatalogFunctionsPage::CatalogFunctionsPage(QWidget *parent)
: QSplitter(Qt::Horizontal, parent) : QSplitter(Qt::Horizontal, parent)
{ {
// create widgets // create widgets
@ -39,12 +39,12 @@ FunctionsPage::FunctionsPage(QWidget *parent)
m_functionTable->setSelectionBehavior(QAbstractItemView::SelectRows); m_functionTable->setSelectionBehavior(QAbstractItemView::SelectRows);
connect(m_functionTable->selectionModel(), &QItemSelectionModel::currentRowChanged, this, connect(m_functionTable->selectionModel(), &QItemSelectionModel::currentRowChanged, this,
&FunctionsPage::functionTable_currentRowChanged); &CatalogFunctionsPage::functionTable_currentRowChanged);
retranslateUi(); retranslateUi();
} }
void FunctionsPage::retranslateUi() void CatalogFunctionsPage::retranslateUi()
{ {
auto set_tabtext = [this] (QWidget *widget, QString translation) { auto set_tabtext = [this] (QWidget *widget, QString translation) {
m_detailTabs->setTabText(m_detailTabs->indexOf(widget), translation); m_detailTabs->setTabText(m_detailTabs->indexOf(widget), translation);
@ -53,13 +53,13 @@ void FunctionsPage::retranslateUi()
set_tabtext(m_definitionView, QApplication::translate("FunctionsPage", "SQL", nullptr)); set_tabtext(m_definitionView, QApplication::translate("FunctionsPage", "SQL", nullptr));
} }
void FunctionsPage::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat) void CatalogFunctionsPage::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat)
{ {
m_catalog = cat; m_catalog = cat;
m_model->setCatalog(cat); m_model->setCatalog(cat);
} }
void FunctionsPage::functionTable_currentRowChanged(const QModelIndex &current, const QModelIndex &previous) void CatalogFunctionsPage::functionTable_currentRowChanged(const QModelIndex &current, const QModelIndex &previous)
{ {
if (current.row() != previous.row()) { if (current.row() != previous.row()) {
if (current.isValid()) { if (current.isValid()) {
@ -73,12 +73,12 @@ void FunctionsPage::functionTable_currentRowChanged(const QModelIndex &current,
} }
} }
void FunctionsPage::selectedProcChanged(const std::optional<PgProc> &proc) void CatalogFunctionsPage::selectedProcChanged(const std::optional<PgProc> &proc)
{ {
updateSqlTab(proc); updateSqlTab(proc);
} }
void FunctionsPage::updateSqlTab(const std::optional<PgProc> &proc) void CatalogFunctionsPage::updateSqlTab(const std::optional<PgProc> &proc)
{ {
if (!proc.has_value()) { if (!proc.has_value()) {
m_definitionView->clear(); m_definitionView->clear();

View file

@ -13,10 +13,10 @@ class QTabWidget;
class SqlCodePreview; class SqlCodePreview;
class PgProc; class PgProc;
class FunctionsPage : public QSplitter { class CatalogFunctionsPage : public QSplitter {
Q_OBJECT Q_OBJECT
public: public:
explicit FunctionsPage(QWidget *parent = nullptr); explicit CatalogFunctionsPage(QWidget *parent = nullptr);
void setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat); void setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat);
signals: signals:

View file

@ -0,0 +1,43 @@
#include "CatalogIndexPage.h"
#include "CustomFilterSortModel.h"
#include "IndexModel.h"
#include "PgLabTableView.h"
#include "SqlCodePreview.h"
#include <QStringBuilder>
#include "IconColumnDelegate.h"
CatalogIndexPage::CatalogIndexPage(QWidget *parent)
: CatalogPageBase(parent)
{
m_indexModel = new IndexModel(this);
m_sortFilterProxy->setSourceModel(m_indexModel);
m_tableView->setItemDelegateForColumn(0, new IconColumnDelegate(this));
connect(m_tableView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &CatalogIndexPage::tableView_selectionChanged);
}
void CatalogIndexPage::catalogSet()
{
}
void CatalogIndexPage::setFilter(const std::optional<PgClass> &cls)
{
m_indexModel->setData(m_catalog, cls);
m_tableView->resizeColumnsToContents();
}
void CatalogIndexPage::tableView_selectionChanged(const QItemSelection &/*selected*/, const QItemSelection &/*deselected*/)
{
auto rijen = selectedRows();
QString drops;
QString creates;
for (auto rij : rijen) {
const PgIndex index = m_indexModel->getIndex(rij);
drops += index.dropSql() % "\n";
creates += index.createSql() % "\n";
}
m_definitionView->setPlainText(drops % "\n" % creates);
}

View file

@ -0,0 +1,29 @@
#ifndef CATALOGINDEXPAGE_H
#define CATALOGINDEXPAGE_H
#include "CatalogPageBase.h"
class IndexModel;
class PgClass;
class QItemSelection;
class CatalogIndexPage : public CatalogPageBase {
Q_OBJECT
public:
explicit CatalogIndexPage(QWidget *parent = nullptr);
void setFilter(const std::optional<PgClass> &cls);
protected:
void catalogSet() override;
private:
IndexModel *m_indexModel = nullptr;
private slots:
void tableView_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
};
#endif // CATALOGINDEXPAGE_H

View file

@ -0,0 +1,35 @@
#include "CatalogPageBase.h"
#include "CustomFilterSortModel.h"
#include "PgLabTableView.h"
#include "SqlCodePreview.h"
CatalogPageBase::CatalogPageBase(QWidget *parent)
: QSplitter(Qt::Vertical, parent)
{
m_tableView = new PgLabTableView(this);
m_definitionView = new SqlCodePreview(this);
addWidget(m_tableView);
addWidget(m_definitionView);
m_sortFilterProxy = new CustomFilterSortModel(this);
m_tableView->setModel(m_sortFilterProxy);
m_tableView->setSortingEnabled(true);
m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
}
void CatalogPageBase::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat)
{
m_catalog = cat;
m_definitionView->setCatalog(m_catalog);
catalogSet();
}
std::unordered_set<int> CatalogPageBase::selectedRows() const
{
auto&& indexes = m_tableView->selectionModel()->selectedIndexes();
std::unordered_set<int> rijen;
for (const auto &e : indexes)
rijen.insert(m_sortFilterProxy->mapToSource(e).row());
return rijen;
}

View file

@ -0,0 +1,32 @@
#ifndef CATALOGPAGEBASE_H
#define CATALOGPAGEBASE_H
#include <QSplitter>
#include <memory>
#include <optional>
#include <unordered_set>
class PgDatabaseCatalog;
class PgLabTableView;
class SqlCodePreview;
class CustomFilterSortModel;
class CatalogPageBase : public QSplitter {
Q_OBJECT
public:
CatalogPageBase(QWidget *parent = nullptr);
void setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat);
protected:
PgLabTableView *m_tableView = nullptr;
SqlCodePreview *m_definitionView = nullptr;
CustomFilterSortModel *m_sortFilterProxy = nullptr;
std::shared_ptr<const PgDatabaseCatalog> m_catalog;
virtual void catalogSet() {}
std::unordered_set<int> selectedRows() const;
};
#endif // CATALOGPAGEBASE_H

View file

@ -1,4 +1,4 @@
#include "SequencesPage.h" #include "CatalogSequencesPage.h"
#include "ResultTableModelUtil.h" #include "ResultTableModelUtil.h"
#include "CustomFilterSortModel.h" #include "CustomFilterSortModel.h"
#include "CustomDataRole.h" #include "CustomDataRole.h"
@ -7,7 +7,8 @@
#include "SqlCodePreview.h" #include "SqlCodePreview.h"
#include "PgLabTableView.h" #include "PgLabTableView.h"
SequencesPage::SequencesPage(QWidget *parent) CatalogSequencesPage::CatalogSequencesPage(QWidget *parent)
: QSplitter(Qt::Horizontal, parent)
{ {
m_sequenceTable = new PgLabTableView(this); m_sequenceTable = new PgLabTableView(this);
m_definitionView = new SqlCodePreview(this); m_definitionView = new SqlCodePreview(this);
@ -25,12 +26,12 @@ SequencesPage::SequencesPage(QWidget *parent)
m_sequenceTable->setSelectionBehavior(QAbstractItemView::SelectRows); m_sequenceTable->setSelectionBehavior(QAbstractItemView::SelectRows);
connect(m_sequenceTable->selectionModel(), &QItemSelectionModel::currentRowChanged, this, connect(m_sequenceTable->selectionModel(), &QItemSelectionModel::currentRowChanged, this,
&SequencesPage::sequenceTable_currentRowChanged); &CatalogSequencesPage::sequenceTable_currentRowChanged);
retranslateUi(); retranslateUi();
} }
void SequencesPage::retranslateUi() void CatalogSequencesPage::retranslateUi()
{ {
// auto set_tabtext = [this] (QWidget *widget, QString translation) { // auto set_tabtext = [this] (QWidget *widget, QString translation) {
// m_detailTabs->setTabText(m_detailTabs->indexOf(widget), translation); // m_detailTabs->setTabText(m_detailTabs->indexOf(widget), translation);
@ -39,13 +40,13 @@ void SequencesPage::retranslateUi()
// set_tabtext(m_definitionView, QApplication::translate("FunctionsPage", "SQL", nullptr)); // set_tabtext(m_definitionView, QApplication::translate("FunctionsPage", "SQL", nullptr));
} }
void SequencesPage::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat) void CatalogSequencesPage::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat)
{ {
m_catalog = cat; m_catalog = cat;
m_model->setCatalog(cat); m_model->setCatalog(cat);
} }
void SequencesPage::sequenceTable_currentRowChanged(const QModelIndex &current, const QModelIndex &previous) void CatalogSequencesPage::sequenceTable_currentRowChanged(const QModelIndex &current, const QModelIndex &previous)
{ {
if (current.row() != previous.row()) { if (current.row() != previous.row()) {
if (current.isValid()) { if (current.isValid()) {
@ -59,12 +60,12 @@ void SequencesPage::sequenceTable_currentRowChanged(const QModelIndex &current,
} }
} }
void SequencesPage::selectedSequenceChanged(const std::optional<PgSequence> &seq) void CatalogSequencesPage::selectedSequenceChanged(const std::optional<PgSequence> &seq)
{ {
updateSqlTab(seq); updateSqlTab(seq);
} }
void SequencesPage::updateSqlTab(const std::optional<PgSequence> &seq) void CatalogSequencesPage::updateSqlTab(const std::optional<PgSequence> &seq)
{ {
if (!seq.has_value()) { if (!seq.has_value()) {
m_definitionView->clear(); m_definitionView->clear();

View file

@ -9,15 +9,13 @@ class PgLabTableView;
class PgDatabaseCatalog; class PgDatabaseCatalog;
class SequenceModel; class SequenceModel;
class CustomFilterSortModel; class CustomFilterSortModel;
//class QTabWidget;
class SqlCodePreview; class SqlCodePreview;
class PgSequence; class PgSequence;
class CatalogSequencesPage : public QSplitter {
class SequencesPage : public QSplitter {
Q_OBJECT Q_OBJECT
public: public:
SequencesPage(QWidget *parent = nullptr); CatalogSequencesPage(QWidget *parent = nullptr);
void setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat); void setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat);
public slots: public slots:

View file

@ -0,0 +1,189 @@
#include "CatalogTablesPage.h"
#include "ColumnPage.h"
#include "ColumnTableModel.h"
#include "ConstraintModel.h"
#include "PgLabTableView.h"
#include "PropertiesPage.h"
#include "ResultTableModelUtil.h"
#include "SqlCodePreview.h"
#include "TriggerPage.h"
#include "catalog/PgIndexContainer.h"
#include "catalog/PgTriggerContainer.h"
#include "widgets/CatalogConstraintPage.h"
#include "widgets/CatalogIndexPage.h"
#include <QApplication>
#include <QStringBuilder>
#include <QTableWidget>
CatalogTablesPage::CatalogTablesPage(QWidget *parent)
: QSplitter(Qt::Horizontal, parent)
{
m_tableView = new PgLabTableView(this);
m_detailsTabs = new QTabWidget(this);
// Populate splitter
addWidget(m_tableView);
addWidget(m_detailsTabs);
// Setup model(s)
m_tablesModel = new TablesTableModel(this);
m_tableView->setModel(m_tablesModel);
// - Columns page
m_columnsPage = new ColumnPage(this);
m_detailsTabs->addTab(m_columnsPage, "");
// constrainst
m_constraintPage = new CatalogConstraintPage(this);
m_detailsTabs->addTab(m_constraintPage, "");
// - Index page
m_indexPage = new CatalogIndexPage(this);
m_detailsTabs->addTab(m_indexPage, "");
// - Properties page
m_propertiesPage = new PropertiesPage(this);
m_propertiesPage->setSourceModel(m_tablesModel);
m_detailsTabs->addTab(m_propertiesPage, "");
connect(m_tableView->selectionModel(), &QItemSelectionModel::currentRowChanged,
m_propertiesPage, &PropertiesPage::setActiveRow);
// - Trigger page
m_triggerPage = new TriggerPage(this);
m_detailsTabs->addTab(m_triggerPage, "");
// SQL tab
m_tableSql = new SqlCodePreview(this);
m_detailsTabs->addTab(m_tableSql, "");
// Force focus on columns tab by default
m_detailsTabs->setCurrentIndex(0);
// Signals
connect(m_tableView->selectionModel(), &QItemSelectionModel::currentRowChanged, this,
&CatalogTablesPage::tableListTable_currentRowChanged);
connect(m_tablesModel, &QAbstractItemModel::layoutChanged,
this, &CatalogTablesPage::tableListTable_layoutChanged);
}
void CatalogTablesPage::retranslateUi(bool all)
{
auto set_tabtext = [this] (QWidget *widget, QString translation) {
m_detailsTabs->setTabText(m_detailsTabs->indexOf(widget), translation);
};
set_tabtext(m_columnsPage, QApplication::translate("TablesPage", "Columns", nullptr));
set_tabtext(m_constraintPage, QApplication::translate("TablesPage", "Constraints", nullptr));
set_tabtext(m_indexPage, QApplication::translate("TablesPage", "Indexes", nullptr));
set_tabtext(m_propertiesPage, QApplication::translate("TablesPage", "Properties", nullptr));
set_tabtext(m_triggerPage, QApplication::translate("TablesPage", "Triggers", nullptr));
set_tabtext(m_tableSql, QApplication::translate("TablesPage", "SQL", nullptr));
}
void CatalogTablesPage::setCatalog(std::shared_ptr<PgDatabaseCatalog> cat)
{
m_catalog = cat;
m_tablesModel->setCatalog(cat);
m_tableView->resizeColumnsToContents();
m_constraintPage->setCatalog(cat);
m_indexPage->setCatalog(cat);
m_triggerPage->setCatalog(cat);
}
void CatalogTablesPage::setNamespaceFilter(TablesTableModel::NamespaceFilter filter)
{
m_tablesModel->setNamespaceFilter(filter);
}
void CatalogTablesPage::tableListTable_currentRowChanged(const QModelIndex &current, const QModelIndex &previous)
{
if (current.row() != previous.row()) {
if (current.isValid()) {
PgClass table = m_tablesModel->getTable(current.row());
selectedTableChanged(table);
}
else
selectedTableChanged({});
}
}
void CatalogTablesPage::tableListTable_layoutChanged(const QList<QPersistentModelIndex> &, QAbstractItemModel::LayoutChangeHint )
{
auto&& index = m_tableView->selectionModel()->currentIndex();
if (index.isValid()) {
PgClass table = m_tablesModel->getTable(index.row());
selectedTableChanged(table);
}
else
selectedTableChanged({});
}
void CatalogTablesPage::on_tableListTable_doubleClicked(const QModelIndex &index)
{
PgClass table = m_tablesModel->getTable(index.row());
if (table.oid() != InvalidOid) {
// context()->moduleAction("pglab.crudpage", "open", {
// { "oid", table.oid() }
// });
}
}
void CatalogTablesPage::selectedTableChanged(const std::optional<PgClass> &table)
{
m_columnsPage->setData(m_catalog, table);
m_constraintPage->setFilter(table);
m_indexPage->setFilter(table);
m_triggerPage->setFilter(table);
updateSqlTab(table);
}
void CatalogTablesPage::updateSqlTab(const std::optional<PgClass> &table)
{
if (!table.has_value()) {
m_tableSql->clear();
return;
}
QString drop_sql;
QString create_sql;
// create table
create_sql += table->createSql();
// - columns
// - constraints
// table details (inherits etc)
// Indexes
drop_sql += "-- drop Indexes\n";
create_sql += "-- create Indexes\n";
auto && indexes = m_catalog->indexes()->getIndexesForTable(table->oid());
for (auto && index : indexes) {
drop_sql += index.dropSql() % "\n";
create_sql += index.createSql() % "\n";
}
// Triggers
drop_sql += "-- drop Triggers\n";
create_sql += "-- create Triggers\n";
auto && triggers = m_catalog->triggers()->getTriggersForRelation(table->oid());
for (auto && trg : triggers) {
drop_sql += trg.dropSql() % "\n";
create_sql += trg.createSql() % "\n";
}
// Privileges
create_sql += "-- set Privileges\n";
create_sql += table->grantSql() % "\n";
// Comments
create_sql += "-- set Comments table + columns\n";
//
m_tableSql->setPlainText(drop_sql % "\n\n" % create_sql);
}

View file

@ -0,0 +1,57 @@
#ifndef CATALOGTABLESPAGE_H
#define CATALOGTABLESPAGE_H
#include <QSplitter>
#include <memory>
#include "TablesTableModel.h"
class CatalogConstraintPage;
class CatalogIndexPage;
class ColumnPage;
class ColumnTableModel;
class ConstraintModel;
class PgClass;
class PgDatabaseCatalog;
class PgLabTableView;
class PropertiesPage;
class QTabWidget;
class SqlCodePreview;
class TablesTableModel;
class TriggerPage;
class CatalogTablesPage: public QSplitter {
Q_OBJECT
public:
explicit CatalogTablesPage(QWidget * parent = nullptr);
void setCatalog(std::shared_ptr<PgDatabaseCatalog> cat);
void setNamespaceFilter(TablesTableModel::NamespaceFilter filter);
void retranslateUi(bool all = true);
private:
PgLabTableView *m_tableView = nullptr;
TablesTableModel* m_tablesModel = nullptr;
// Details
QTabWidget *m_detailsTabs = nullptr;
ColumnPage *m_columnsPage = nullptr;
CatalogConstraintPage *m_constraintPage = nullptr;
CatalogIndexPage *m_indexPage = nullptr;
PropertiesPage *m_propertiesPage = nullptr;
TriggerPage *m_triggerPage = nullptr;
SqlCodePreview *m_tableSql = nullptr;
std::shared_ptr<PgDatabaseCatalog> m_catalog;
void selectedTableChanged(const std::optional<PgClass> &table);
void updateSqlTab(const std::optional<PgClass> &table);
private slots:
void tableListTable_currentRowChanged(const QModelIndex &current, const QModelIndex &previous);
void tableListTable_layoutChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint);
void on_tableListTable_doubleClicked(const QModelIndex &index);
};
#endif // CATALOGTABLESPAGE_H

View file

@ -1,4 +1,5 @@
#include "PgConstraint.h" #include "PgConstraint.h"
#include "SqlFormattingUtils.h"
void operator<<(ConstraintType &s, const Pgsql::Value &v) void operator<<(ConstraintType &s, const Pgsql::Value &v)
{ {
@ -172,3 +173,13 @@ QString PgConstraint::typeName() const
{ {
return "CONSTRAINT"; return "CONSTRAINT";
} }
QString PgConstraint::dropSql() const
{
return getDropConstraintDefinition(catalog(), *this);
}
QString PgConstraint::createSql() const
{
return getAlterTableConstraintDefinition(catalog(), *this);
}

View file

@ -77,6 +77,9 @@ public:
using PgNamespaceObject::PgNamespaceObject; using PgNamespaceObject::PgNamespaceObject;
QString typeName() const override; QString typeName() const override;
QString dropSql() const override;
QString createSql() const override;
}; };

View file

@ -245,7 +245,7 @@ QString PgProc::argSigList(const bool forScript) const
} }
const QString& PgProc::createSql() const QString PgProc::createSql() const
{ {
if (createSqlCache.isEmpty()) { if (createSqlCache.isEmpty()) {
QString sql; QString sql;

View file

@ -86,7 +86,7 @@ public:
); );
const std::vector<Arg>& args() const; const std::vector<Arg>& args() const;
const QString& createSql() const; QString createSql() const override;
QString argListWithNames(bool multiline = false) const; QString argListWithNames(bool multiline = false) const;
QString argSigList(const bool forScript = false) const; QString argSigList(const bool forScript = false) const;
QString volatility() const; QString volatility() const;

View file

@ -91,3 +91,13 @@ QString PgServerObject::aclAllPattern() const
{ {
return {}; return {};
} }
QString PgServerObject::dropSql() const
{
return {};
}
QString PgServerObject::createSql() const
{
return {};
}

View file

@ -41,6 +41,9 @@ public:
* @return A string containing all posible privileges for this type of object. * @return A string containing all posible privileges for this type of object.
*/ */
virtual QString aclAllPattern() const; virtual QString aclAllPattern() const;
virtual QString dropSql() const;
virtual QString createSql() const;
private: private:
Oid m_ownerOid = InvalidOid; Oid m_ownerOid = InvalidOid;
const PgAuthId * m_owner; const PgAuthId * m_owner;

View file

@ -5,7 +5,7 @@
#include "SqlFormattingUtils.h" #include "SqlFormattingUtils.h"
#include <QStringBuilder> #include <QStringBuilder>
QString PgTrigger::dropSql() QString PgTrigger::dropSql() const
{ {
if (m_dropSql.isEmpty()) { if (m_dropSql.isEmpty()) {
auto&& fqtablename = catalog().classes()->getByKey(relid)->fullyQualifiedQuotedObjectName(); // genFQTableName(catalog(), *catalog().classes()->getByKey(relid)); auto&& fqtablename = catalog().classes()->getByKey(relid)->fullyQualifiedQuotedObjectName(); // genFQTableName(catalog(), *catalog().classes()->getByKey(relid));
@ -15,7 +15,7 @@ QString PgTrigger::dropSql()
return m_dropSql; return m_dropSql;
} }
QString PgTrigger::createSql() QString PgTrigger::createSql() const
{ {
if (m_createSql.isEmpty()) { if (m_createSql.isEmpty()) {
auto&& fqtablename = catalog().classes()->getByKey(relid)->fullyQualifiedQuotedObjectName(); //genFQTableName(catalog(), *catalog().classes()->getByKey(relid)); auto&& fqtablename = catalog().classes()->getByKey(relid)->fullyQualifiedQuotedObjectName(); //genFQTableName(catalog(), *catalog().classes()->getByKey(relid));

View file

@ -47,8 +47,8 @@ public:
static constexpr int TriggerTypeTruncate = (1 << 5); static constexpr int TriggerTypeTruncate = (1 << 5);
static constexpr int TriggerTypeInstead = (1 << 6); static constexpr int TriggerTypeInstead = (1 << 6);
QString dropSql(); QString dropSql() const override;
QString createSql(); QString createSql() const override;
bool isRow() const { return type & TriggerTypeRow; } bool isRow() const { return type & TriggerTypeRow; }
bool isBefore() const { return type & TriggerTypeBefore; } bool isBefore() const { return type & TriggerTypeBefore; }
QString typeFireWhen() const; QString typeFireWhen() const;