2017-12-10 14:20:45 +01:00
|
|
|
|
#include "TablesPage.h"
|
2017-12-10 08:17:07 +01:00
|
|
|
|
#include "ui_TablesPage.h"
|
|
|
|
|
|
|
2018-12-16 10:17:59 +01:00
|
|
|
|
#include "catalog/PgAttribute.h"
|
|
|
|
|
|
#include "catalog/PgDatabaseCatalog.h"
|
2018-12-27 12:15:37 +01:00
|
|
|
|
#include "catalog/PgIndexContainer.h"
|
|
|
|
|
|
#include "catalog/PgTriggerContainer.h"
|
2018-11-29 20:21:36 +01:00
|
|
|
|
#include "ColumnPage.h"
|
2017-12-12 20:13:53 +01:00
|
|
|
|
#include "ColumnTableModel.h"
|
2017-12-30 12:57:55 +01:00
|
|
|
|
#include "ConstraintModel.h"
|
|
|
|
|
|
#include "IconColumnDelegate.h"
|
2018-01-06 21:22:22 +01:00
|
|
|
|
#include "IndexModel.h"
|
2018-12-28 12:55:11 +01:00
|
|
|
|
#include "DatabaseWindow.h"
|
2018-10-07 19:40:06 +02:00
|
|
|
|
#include "PgLabItemDelegate.h"
|
2018-10-20 10:58:42 +02:00
|
|
|
|
#include "PropertiesPage.h"
|
2018-10-07 19:40:06 +02:00
|
|
|
|
#include "ResultTableModelUtil.h"
|
2018-01-06 21:22:22 +01:00
|
|
|
|
#include "SqlFormattingUtils.h"
|
|
|
|
|
|
#include "SqlSyntaxHighlighter.h"
|
2018-10-07 19:40:06 +02:00
|
|
|
|
#include "TriggerPage.h"
|
|
|
|
|
|
#include "UserConfiguration.h"
|
2018-11-30 18:41:38 +01:00
|
|
|
|
#include "SqlCodePreview.h"
|
2018-01-06 21:22:22 +01:00
|
|
|
|
#include <QStringBuilder>
|
2018-12-23 08:39:38 +01:00
|
|
|
|
#include <unordered_set>
|
2017-12-10 14:20:45 +01:00
|
|
|
|
|
2018-12-28 12:55:11 +01:00
|
|
|
|
TablesPage::TablesPage(DatabaseWindow *parent)
|
2018-01-09 20:39:43 +01:00
|
|
|
|
: QWidget(parent)
|
|
|
|
|
|
, ui(new Ui::TablesPage)
|
|
|
|
|
|
, m_window(parent)
|
2017-12-10 08:17:07 +01:00
|
|
|
|
{
|
|
|
|
|
|
ui->setupUi(this);
|
2017-12-10 14:20:45 +01:00
|
|
|
|
|
2017-12-12 20:13:53 +01:00
|
|
|
|
SetTableViewDefault(ui->tableListTable);
|
2017-12-10 14:20:45 +01:00
|
|
|
|
m_tablesModel = new TablesTableModel(this);
|
|
|
|
|
|
ui->tableListTable->setModel(m_tablesModel);
|
2018-11-04 11:26:20 +01:00
|
|
|
|
ui->tableListTable->setItemDelegate(new PgLabItemDelegate(this));
|
2018-07-07 09:57:59 +02:00
|
|
|
|
ui->tableListTable->setSortingEnabled(true);
|
|
|
|
|
|
ui->tableListTable->sortByColumn(0, Qt::AscendingOrder);
|
2018-10-21 13:47:38 +02:00
|
|
|
|
ui->tableListTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
2017-12-10 14:20:45 +01:00
|
|
|
|
|
2018-10-07 19:40:06 +02:00
|
|
|
|
// Constraints
|
2017-12-30 12:57:55 +01:00
|
|
|
|
SetTableViewDefault(ui->constraintsTable);
|
|
|
|
|
|
m_constraintModel = new ConstraintModel(this);
|
|
|
|
|
|
ui->constraintsTable->setModel(m_constraintModel);
|
2018-11-04 11:26:20 +01:00
|
|
|
|
ui->constraintsTable->setItemDelegateForColumn(0, new IconColumnDelegate(this));
|
2017-12-30 12:57:55 +01:00
|
|
|
|
|
2018-10-07 19:40:06 +02:00
|
|
|
|
// Indexes
|
2018-01-06 21:22:22 +01:00
|
|
|
|
SetTableViewDefault(ui->indexesTable);
|
|
|
|
|
|
m_indexModel = new IndexModel(this);
|
|
|
|
|
|
ui->indexesTable->setModel(m_indexModel);
|
2018-11-04 11:26:20 +01:00
|
|
|
|
ui->indexesTable->setItemDelegate(new PgLabItemDelegate(this));
|
|
|
|
|
|
ui->indexesTable->setItemDelegateForColumn(0, new IconColumnDelegate(this));
|
2018-09-02 10:30:30 +00:00
|
|
|
|
|
2018-10-07 19:40:06 +02:00
|
|
|
|
// Set code editor fonts
|
|
|
|
|
|
QFont code_font = UserConfiguration::instance()->codeFont();
|
|
|
|
|
|
ui->constraintSqlEdit->setFont(code_font);
|
|
|
|
|
|
ui->indexSqlEdit->setFont(code_font);
|
2018-01-06 21:22:22 +01:00
|
|
|
|
|
2017-12-29 08:39:08 +01:00
|
|
|
|
|
2018-12-29 10:56:24 +01:00
|
|
|
|
|
|
|
|
|
|
|
2018-10-07 19:40:06 +02:00
|
|
|
|
// Connect signals
|
|
|
|
|
|
// ---------------
|
2018-08-05 11:57:27 +02:00
|
|
|
|
// Table selection
|
2017-12-12 20:13:53 +01:00
|
|
|
|
connect(ui->tableListTable->selectionModel(), &QItemSelectionModel::currentRowChanged, this,
|
2018-01-06 21:33:24 +01:00
|
|
|
|
&TablesPage::tableListTable_currentRowChanged);
|
2018-01-06 21:22:22 +01:00
|
|
|
|
|
2018-10-21 13:47:38 +02:00
|
|
|
|
connect(m_tablesModel, &QAbstractItemModel::layoutChanged,
|
|
|
|
|
|
this, &TablesPage::tableListTable_layoutChanged);
|
|
|
|
|
|
|
|
|
|
|
|
//layoutChanged(const QList<QPersistentModelIndex> &parents = ..., QAbstractItemModel::LayoutChangeHint hint = ...)
|
|
|
|
|
|
|
2018-01-06 21:22:22 +01:00
|
|
|
|
connect(ui->constraintsTable->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
2018-01-06 21:33:24 +01:00
|
|
|
|
&TablesPage::constraintsTable_selectionChanged);
|
2018-08-05 11:57:27 +02:00
|
|
|
|
connect(ui->constraintsTable->model(), &QAbstractItemModel::modelReset, this,
|
|
|
|
|
|
&TablesPage::constraintsTable_modelReset);
|
2017-12-12 20:13:53 +01:00
|
|
|
|
|
2018-08-05 11:57:27 +02:00
|
|
|
|
// React to changes in de selected indexes, does not trigger when model is reset
|
2018-04-08 09:04:38 +02:00
|
|
|
|
connect(ui->indexesTable->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
|
|
|
|
|
&TablesPage::indexesTable_selectionChanged);
|
2018-08-05 11:57:27 +02:00
|
|
|
|
// Capture model reset independently
|
|
|
|
|
|
connect(ui->indexesTable->model(), &QAbstractItemModel::modelReset, this,
|
|
|
|
|
|
&TablesPage::indexesTable_modelReset);
|
2018-04-08 09:04:38 +02:00
|
|
|
|
|
2018-10-07 19:40:06 +02:00
|
|
|
|
// Non designer based code
|
2018-11-29 20:21:36 +01:00
|
|
|
|
// - Columns page
|
|
|
|
|
|
m_columnsPage = new ColumnPage(this);
|
|
|
|
|
|
ui->twDetails->insertTab(0, m_columnsPage, "");
|
|
|
|
|
|
|
2018-10-21 13:47:38 +02:00
|
|
|
|
// - Properties page
|
2018-10-20 10:58:42 +02:00
|
|
|
|
m_propertiesPage = new PropertiesPage(this);
|
2018-10-21 13:47:38 +02:00
|
|
|
|
m_propertiesPage->setSourceModel(m_tablesModel);
|
2018-11-29 20:21:36 +01:00
|
|
|
|
ui->twDetails->addTab(m_propertiesPage, "");
|
2018-10-21 13:47:38 +02:00
|
|
|
|
connect(ui->tableListTable->selectionModel(), &QItemSelectionModel::currentRowChanged,
|
|
|
|
|
|
m_propertiesPage, &PropertiesPage::setActiveRow);
|
2018-10-20 10:58:42 +02:00
|
|
|
|
|
2018-10-21 13:47:38 +02:00
|
|
|
|
// - Trigger page
|
2018-10-07 19:40:06 +02:00
|
|
|
|
m_triggerPage = new TriggerPage(this);
|
2018-11-29 20:21:36 +01:00
|
|
|
|
ui->twDetails->addTab(m_triggerPage, "");
|
2018-10-20 10:58:42 +02:00
|
|
|
|
|
2018-11-30 18:41:38 +01:00
|
|
|
|
// SQL tab
|
|
|
|
|
|
m_sqlCodePreview = new SqlCodePreview(this);
|
|
|
|
|
|
ui->twDetails->addTab(m_sqlCodePreview, "");
|
|
|
|
|
|
|
2018-12-16 12:47:31 +01:00
|
|
|
|
// Force focus on columns tab by default
|
|
|
|
|
|
ui->twDetails->setCurrentIndex(0);
|
|
|
|
|
|
|
2018-10-07 19:40:06 +02:00
|
|
|
|
retranslateUi(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void TablesPage::retranslateUi(bool all)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (all)
|
|
|
|
|
|
ui->retranslateUi(this);
|
|
|
|
|
|
|
2018-11-30 18:41:38 +01:00
|
|
|
|
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));
|
|
|
|
|
|
|
2017-12-12 20:13:53 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TablesPage::~TablesPage()
|
|
|
|
|
|
{
|
|
|
|
|
|
delete ui;
|
2017-12-10 14:20:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TablesPage::setCatalog(std::shared_ptr<PgDatabaseCatalog> cat)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_catalog = cat;
|
|
|
|
|
|
m_tablesModel->setCatalog(cat);
|
2017-12-19 19:55:12 +01:00
|
|
|
|
ui->tableListTable->resizeColumnsToContents();
|
2018-10-07 19:40:06 +02:00
|
|
|
|
|
|
|
|
|
|
m_triggerPage->setCatalog(cat);
|
2018-01-06 21:22:22 +01:00
|
|
|
|
|
|
|
|
|
|
auto highlighter = new SqlSyntaxHighlighter(ui->constraintSqlEdit->document());
|
|
|
|
|
|
highlighter->setTypes(*cat->types());
|
2018-04-08 09:04:38 +02:00
|
|
|
|
highlighter = new SqlSyntaxHighlighter(ui->indexSqlEdit->document());
|
|
|
|
|
|
highlighter->setTypes(*cat->types());
|
2017-12-10 08:17:07 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-12-29 10:56:24 +01:00
|
|
|
|
void TablesPage::setNamespaceFilter(TablesTableModel::NamespaceFilter filter)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_tablesModel->setNamespaceFilter(filter);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-10-21 13:47:38 +02:00
|
|
|
|
|
2018-01-06 21:33:24 +01:00
|
|
|
|
void TablesPage::tableListTable_currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous)
|
2017-12-10 08:17:07 +01:00
|
|
|
|
{
|
2017-12-12 20:13:53 +01:00
|
|
|
|
if (current.row() != previous.row()) {
|
2018-11-18 20:24:27 +01:00
|
|
|
|
if (current.isValid()) {
|
|
|
|
|
|
PgClass table = m_tablesModel->getTable(current.row());
|
|
|
|
|
|
selectedTableChanged(table);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
selectedTableChanged({});
|
2018-10-21 13:47:38 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-12-30 12:57:55 +01:00
|
|
|
|
|
2018-01-06 21:22:22 +01:00
|
|
|
|
|
2018-10-21 13:47:38 +02:00
|
|
|
|
void TablesPage::tableListTable_layoutChanged(const QList<QPersistentModelIndex> &, QAbstractItemModel::LayoutChangeHint )
|
|
|
|
|
|
{
|
|
|
|
|
|
auto&& index = ui->tableListTable->selectionModel()->currentIndex();
|
2018-11-18 20:24:27 +01:00
|
|
|
|
if (index.isValid()) {
|
|
|
|
|
|
PgClass table = m_tablesModel->getTable(index.row());
|
|
|
|
|
|
selectedTableChanged(table);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
selectedTableChanged({});
|
2018-10-21 13:47:38 +02:00
|
|
|
|
}
|
2018-10-07 19:40:06 +02:00
|
|
|
|
|
2018-10-21 13:47:38 +02:00
|
|
|
|
|
2018-11-18 20:24:27 +01:00
|
|
|
|
void TablesPage::selectedTableChanged(const std::optional<PgClass> &table)
|
2018-10-21 13:47:38 +02:00
|
|
|
|
{
|
2018-11-29 20:21:36 +01:00
|
|
|
|
m_columnsPage->setData(m_catalog, table);
|
2018-10-21 13:47:38 +02:00
|
|
|
|
|
|
|
|
|
|
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);
|
2018-01-06 21:22:22 +01:00
|
|
|
|
|
2018-11-30 18:41:38 +01:00
|
|
|
|
updateSqlTab(table);
|
|
|
|
|
|
}
|
2018-01-06 21:22:22 +01:00
|
|
|
|
|
2018-01-15 13:31:37 +01:00
|
|
|
|
void TablesPage::constraintsTable_selectionChanged(const QItemSelection &/*selected*/, const QItemSelection &/*deselected*/)
|
2018-01-06 21:22:22 +01:00
|
|
|
|
{
|
|
|
|
|
|
const auto indexes = ui->constraintsTable->selectionModel()->selectedIndexes();
|
2018-12-23 08:39:38 +01:00
|
|
|
|
std::unordered_set<int> rijen;
|
2018-08-05 11:57:27 +02:00
|
|
|
|
for (const auto &e : indexes)
|
2018-04-08 09:04:38 +02:00
|
|
|
|
rijen.insert(e.row());
|
|
|
|
|
|
|
2018-01-06 21:22:22 +01:00
|
|
|
|
QString drops;
|
|
|
|
|
|
QString creates;
|
|
|
|
|
|
for (auto rij : rijen) {
|
|
|
|
|
|
const PgConstraint constraint = m_constraintModel->constraint(rij);
|
|
|
|
|
|
drops += getDropConstraintDefinition(*m_catalog, constraint) % "\n";
|
2018-11-30 18:41:38 +01:00
|
|
|
|
creates += getAlterTableConstraintDefinition(*m_catalog, constraint) % "\n";
|
2017-12-12 20:13:53 +01:00
|
|
|
|
}
|
2018-01-06 21:22:22 +01:00
|
|
|
|
ui->constraintSqlEdit->setPlainText(drops % "\n" % creates);
|
2017-12-10 08:17:07 +01:00
|
|
|
|
}
|
2018-01-09 20:39:43 +01:00
|
|
|
|
|
2018-08-05 11:57:27 +02:00
|
|
|
|
void TablesPage::constraintsTable_modelReset()
|
|
|
|
|
|
{
|
|
|
|
|
|
ui->constraintSqlEdit->clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-04-08 09:04:38 +02:00
|
|
|
|
void TablesPage::indexesTable_selectionChanged(const QItemSelection &/*selected*/, const QItemSelection &/*deselected*/)
|
|
|
|
|
|
{
|
|
|
|
|
|
const auto indexes = ui->indexesTable->selectionModel()->selectedIndexes();
|
2018-12-23 08:39:38 +01:00
|
|
|
|
std::unordered_set<int> rijen;
|
2018-08-05 11:57:27 +02:00
|
|
|
|
for (const auto &e : indexes)
|
2018-04-08 09:04:38 +02:00
|
|
|
|
rijen.insert(e.row());
|
|
|
|
|
|
|
|
|
|
|
|
QString drops;
|
|
|
|
|
|
QString creates;
|
|
|
|
|
|
for (auto rij : rijen) {
|
|
|
|
|
|
const PgIndex index = m_indexModel->getIndex(rij);
|
2018-11-30 18:41:38 +01:00
|
|
|
|
drops += index.dropSql() % "\n";
|
|
|
|
|
|
creates += index.createSql() % "\n";
|
2018-04-08 09:04:38 +02:00
|
|
|
|
}
|
|
|
|
|
|
ui->indexSqlEdit->setPlainText(drops % "\n" % creates);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-08-05 11:57:27 +02:00
|
|
|
|
void TablesPage::indexesTable_modelReset()
|
|
|
|
|
|
{
|
|
|
|
|
|
ui->indexSqlEdit->clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-09 20:39:43 +01:00
|
|
|
|
void TablesPage::on_tableListTable_doubleClicked(const QModelIndex &index)
|
|
|
|
|
|
{
|
|
|
|
|
|
PgClass table = m_tablesModel->getTable(index.row());
|
2018-11-25 19:45:06 +01:00
|
|
|
|
if (table.oid() != InvalidOid) {
|
2018-01-09 20:39:43 +01:00
|
|
|
|
m_window->newCrudPage(table);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2018-11-30 18:41:38 +01:00
|
|
|
|
|
|
|
|
|
|
void TablesPage::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";
|
2018-12-27 12:15:37 +01:00
|
|
|
|
auto && triggers = m_catalog->triggers()->getTriggersForRelation(table->oid());
|
|
|
|
|
|
for (auto && trg : triggers) {
|
|
|
|
|
|
drop_sql += trg.dropSql() % "\n";
|
|
|
|
|
|
create_sql += trg.createSql() % "\n";
|
|
|
|
|
|
}
|
2018-11-30 18:41:38 +01:00
|
|
|
|
|
|
|
|
|
|
// Privileges
|
|
|
|
|
|
create_sql += "-- set Privileges\n";
|
2018-12-27 12:15:37 +01:00
|
|
|
|
create_sql += table->grantSql() % "\n";
|
2018-11-30 18:41:38 +01:00
|
|
|
|
|
|
|
|
|
|
// Comments
|
|
|
|
|
|
create_sql += "-- set Comments table + columns\n";
|
|
|
|
|
|
//
|
|
|
|
|
|
m_sqlCodePreview->setPlainText(drop_sql % "\n\n" % create_sql);
|
|
|
|
|
|
}
|