Updating of detail tabs besides list of tables works correctly again.

Had stopped working because the catalog now behaves a little different,
returning nullptr instead of an invalid element.
This commit is contained in:
eelke 2018-11-18 20:24:27 +01:00
parent fcb191f2cc
commit 52011a9842
12 changed files with 114 additions and 92 deletions

View file

@ -11,35 +11,56 @@
#include "SqlFormattingUtils.h" #include "SqlFormattingUtils.h"
#include <QBrush> #include <QBrush>
void ColumnTableModel::setData(std::shared_ptr<const PgDatabaseCatalog> cat, const PgClass &table) namespace {
// Filter dropped and system columns but keep the oid column
bool ColumnFilterWithOidsPred(PgAttribute &e)
{
return e.isdropped || (e.num <= 0 && e.name != "oid");
}
// Filter dropped and system columns
bool ColumnFilterWithoutOidsPred(PgAttribute &e)
{
return e.isdropped || e.num <= 0;
}
}
void ColumnTableModel::setData(std::shared_ptr<const PgDatabaseCatalog> cat, const std::optional<PgClass> &table)
{ {
beginResetModel(); beginResetModel();
SCOPE_EXIT { endResetModel(); }; SCOPE_EXIT { endResetModel(); };
m_table = table; m_table = table;
m_catalog = cat; m_catalog = cat;
m_columns = cat->attributes()->getColumnsForRelation(table.oid); if (m_table) {
m_columns = cat->attributes()->getColumnsForRelation(table->oid);
// hide system columns // hide system and dropped columns
auto si = table.hasoids auto column_filter_pred = table->hasoids ? ColumnFilterWithOidsPred : ColumnFilterWithoutOidsPred;
? std::remove_if(m_columns.begin(), m_columns.end(), auto si = std::remove_if(m_columns.begin(), m_columns.end(), column_filter_pred);
[](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 // move columns to end and remove them
m_columns.erase(si, m_columns.end()); m_columns.erase(si, m_columns.end());
// sort remaining columns by order in table // sort remaining columns by order in table
std::sort(m_columns.begin(), m_columns.end(), std::sort(m_columns.begin(), m_columns.end(),
[] (auto &l, auto &r) -> bool { return l.num < r.num; }); [] (auto &l, auto &r) -> bool { return l.num < r.num; });
}
else
m_columns.clear();
m_indexes = m_catalog->indexes()->getIndexesForTable(table.oid);
if (m_table) {
m_indexes = m_catalog->indexes()->getIndexesForTable(table->oid);
std::sort(m_indexes.begin(), m_indexes.end(), std::sort(m_indexes.begin(), m_indexes.end(),
[] (const auto &l, const auto &r) -> bool [] (const auto &l, const auto &r) -> bool
{ {
return l.isprimary > r.isprimary return l.isprimary > r.isprimary
|| (l.isprimary == r.isprimary && l.indexrelid < r.indexrelid); || (l.isprimary == r.isprimary && l.indexrelid < r.indexrelid);
}); });
}
else
m_indexes.clear();
} }
QVariant ColumnTableModel::headerData(int section, Qt::Orientation orientation, int role) const QVariant ColumnTableModel::headerData(int section, Qt::Orientation orientation, int role) const
@ -224,6 +245,9 @@ QVariant ColumnTableModel::data(const QModelIndex &index, int role) const
if (role == Qt::ForegroundRole && index.column() == TypeCol) { if (role == Qt::ForegroundRole && index.column() == TypeCol) {
QVariant v; QVariant v;
const auto &t = m_columns[index.row()]; const auto &t = m_columns[index.row()];
if (t.typid == InvalidOid)
v = QBrush(Qt::black);
else {
auto c = m_catalog->types()->getByKey(t.typid); auto c = m_catalog->types()->getByKey(t.typid);
switch (c->category) { switch (c->category) {
case TypCategory::Boolean: case TypCategory::Boolean:
@ -252,6 +276,7 @@ QVariant ColumnTableModel::data(const QModelIndex &index, int role) const
default: default:
v = QBrush(Qt::black); v = QBrush(Qt::black);
} }
}
return v; return v;
} }
if (role == Qt::TextAlignmentRole) { if (role == Qt::TextAlignmentRole) {

View file

@ -5,6 +5,7 @@
#include "PgClass.h" #include "PgClass.h"
#include "PgIndex.h" #include "PgIndex.h"
#include <memory> #include <memory>
#include <optional>
#include <vector> #include <vector>
class PgDatabaseCatalog; class PgDatabaseCatalog;
@ -25,7 +26,7 @@ public:
using BaseTableModel::BaseTableModel; using BaseTableModel::BaseTableModel;
void setData(std::shared_ptr<const PgDatabaseCatalog> cat, const PgClass &table); void setData(std::shared_ptr<const PgDatabaseCatalog> cat, const std::optional<PgClass> &table);
// Header: // Header:
QVariant headerData(int section, Qt::Orientation orientation, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
@ -42,7 +43,7 @@ protected:
using t_Columns = std::vector<PgAttribute>; using t_Columns = std::vector<PgAttribute>;
std::shared_ptr<const PgDatabaseCatalog> m_catalog; std::shared_ptr<const PgDatabaseCatalog> m_catalog;
PgClass m_table; std::optional<PgClass> m_table;
t_Columns m_columns; t_Columns m_columns;
std::vector<PgIndex> m_indexes; std::vector<PgIndex> m_indexes;

View file

@ -12,42 +12,23 @@ ConstraintModel::ConstraintModel(QObject *parent)
void ConstraintModel::setData(std::shared_ptr<const PgDatabaseCatalog> cat, const PgClass &table) void ConstraintModel::setData(std::shared_ptr<const PgDatabaseCatalog> cat, const std::optional<PgClass> &table)
{ {
beginResetModel(); beginResetModel();
SCOPE_EXIT { endResetModel(); }; SCOPE_EXIT { endResetModel(); };
m_table = table; m_table = table;
m_catalog = cat; m_catalog = cat;
m_constraints = cat->constraints()->getConstraintsForRelation(table.oid); if (table) {
m_constraints = cat->constraints()->getConstraintsForRelation(table->oid);
std::sort(m_constraints.begin(), m_constraints.end(), std::sort(m_constraints.begin(), m_constraints.end(),
[] (auto &l, auto &r) { [] (auto &l, auto &r) {
return l.type < r.type || return l.type < r.type ||
(l.type == r.type && l.name < r.name); (l.type == r.type && l.name < r.name);
}); });
}
// // hide system columns else
// auto si = table.hasoids m_constraints.clear();
// ? 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 ConstraintModel::headerData(int section, Qt::Orientation orientation, int role) const

View file

@ -5,6 +5,7 @@
#include "PgClass.h" #include "PgClass.h"
#include "PgConstraint.h" #include "PgConstraint.h"
#include <QAbstractTableModel> #include <QAbstractTableModel>
#include <optional>
#include <vector> #include <vector>
class PgDatabaseCatalog; class PgDatabaseCatalog;
@ -23,7 +24,7 @@ public:
explicit ConstraintModel(QObject *parent = nullptr); explicit ConstraintModel(QObject *parent = nullptr);
void setData(std::shared_ptr<const PgDatabaseCatalog> cat, const PgClass &table); void setData(std::shared_ptr<const PgDatabaseCatalog> cat, const std::optional<PgClass> &table);
// Header: // Header:
@ -43,7 +44,7 @@ protected:
private: private:
std::shared_ptr<const PgDatabaseCatalog> m_catalog; std::shared_ptr<const PgDatabaseCatalog> m_catalog;
PgClass m_table; std::optional<PgClass> m_table;
using t_Constraints = std::vector<PgConstraint>; using t_Constraints = std::vector<PgConstraint>;
t_Constraints m_constraints; t_Constraints m_constraints;

View file

@ -5,15 +5,17 @@
#include "ScopeGuard.h" #include "ScopeGuard.h"
#include "CustomDataRole.h" #include "CustomDataRole.h"
void IndexModel::setData(std::shared_ptr<const PgDatabaseCatalog> cat, const PgClass &table) void IndexModel::setData(std::shared_ptr<const PgDatabaseCatalog> cat, const std::optional<PgClass> &table)
{ {
beginResetModel(); beginResetModel();
SCOPE_EXIT { endResetModel(); }; SCOPE_EXIT { endResetModel(); };
m_catalog = cat; m_catalog = cat;
m_table = table; m_table = table;
if (table)
m_indexes = cat->indexes()->getIndexesForTable(table.oid); m_indexes = cat->indexes()->getIndexesForTable(table->oid);
else
m_indexes.clear();
} }
int IndexModel::rowCount(const QModelIndex &/*parent*/) const int IndexModel::rowCount(const QModelIndex &/*parent*/) const

View file

@ -5,6 +5,7 @@
#include "PgClass.h" #include "PgClass.h"
#include "PgIndex.h" #include "PgIndex.h"
#include <memory> #include <memory>
#include <optional>
#include <vector> #include <vector>
@ -36,7 +37,7 @@ public:
// comment // comment
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
void setData(std::shared_ptr<const PgDatabaseCatalog> cat, const PgClass &table); void setData(std::shared_ptr<const PgDatabaseCatalog> cat, const std::optional<PgClass> &table);
// Basic functionality: // Basic functionality:
@ -52,7 +53,7 @@ protected:
private: private:
std::shared_ptr<const PgDatabaseCatalog> m_catalog; std::shared_ptr<const PgDatabaseCatalog> m_catalog;
PgClass m_table; std::optional<PgClass> m_table;
using t_Indexes = std::vector<PgIndex>; using t_Indexes = std::vector<PgIndex>;
t_Indexes m_indexes; t_Indexes m_indexes;

View file

@ -139,21 +139,29 @@ void TablesPage::setCatalog(std::shared_ptr<PgDatabaseCatalog> cat)
void TablesPage::tableListTable_currentRowChanged(const QModelIndex &current, const QModelIndex &previous) void TablesPage::tableListTable_currentRowChanged(const QModelIndex &current, const QModelIndex &previous)
{ {
if (current.row() != previous.row()) { if (current.row() != previous.row()) {
if (current.isValid()) {
PgClass table = m_tablesModel->getTable(current.row()); PgClass table = m_tablesModel->getTable(current.row());
selectedTableChanged(table); selectedTableChanged(table);
} }
else
selectedTableChanged({});
}
} }
void TablesPage::tableListTable_layoutChanged(const QList<QPersistentModelIndex> &, QAbstractItemModel::LayoutChangeHint ) void TablesPage::tableListTable_layoutChanged(const QList<QPersistentModelIndex> &, QAbstractItemModel::LayoutChangeHint )
{ {
auto&& index = ui->tableListTable->selectionModel()->currentIndex(); auto&& index = ui->tableListTable->selectionModel()->currentIndex();
if (index.isValid()) {
PgClass table = m_tablesModel->getTable(index.row()); PgClass table = m_tablesModel->getTable(index.row());
selectedTableChanged(table); selectedTableChanged(table);
}
else
selectedTableChanged({});
} }
void TablesPage::selectedTableChanged(const PgClass & table) void TablesPage::selectedTableChanged(const std::optional<PgClass> &table)
{ {
m_columnsModel->setData(m_catalog, table); m_columnsModel->setData(m_catalog, table);
ui->columnsTable->resizeColumnsToContents(); ui->columnsTable->resizeColumnsToContents();

View file

@ -3,6 +3,7 @@
#include <QWidget> #include <QWidget>
#include <memory> #include <memory>
#include <optional>
#include <QItemSelection> #include <QItemSelection>
namespace Ui { namespace Ui {
@ -25,7 +26,7 @@ class TablesPage : public QWidget
Q_OBJECT Q_OBJECT
public: public:
explicit TablesPage(MainWindow *parent = 0); explicit TablesPage(MainWindow *parent = nullptr);
~TablesPage(); ~TablesPage();
void setCatalog(std::shared_ptr<PgDatabaseCatalog> cat); void setCatalog(std::shared_ptr<PgDatabaseCatalog> cat);
@ -46,7 +47,7 @@ private:
void retranslateUi(bool all = true); void retranslateUi(bool all = true);
QWidget* addDetailTab(QWidget *contents); QWidget* addDetailTab(QWidget *contents);
void selectedTableChanged(const PgClass & table); void selectedTableChanged(const std::optional<PgClass> &table);
private slots: private slots:
void tableListTable_currentRowChanged(const QModelIndex &current, const QModelIndex &previous); void tableListTable_currentRowChanged(const QModelIndex &current, const QModelIndex &previous);

View file

@ -45,9 +45,9 @@ void TriggerPage::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat)
} }
void TriggerPage::setFilter(const PgClass &cls) void TriggerPage::setFilter(const std::optional<PgClass> &cls)
{ {
m_sortFilterProxy->setOidFilterTable(cls.oid, FirstHiddenValue); m_sortFilterProxy->setOidFilterTable(cls ? cls->oid : InvalidOid, FirstHiddenValue);
} }

View file

@ -3,6 +3,7 @@
#include <QSplitter> #include <QSplitter>
#include <memory> #include <memory>
#include <optional>
class QTableView; class QTableView;
class SqlCodePreview; class SqlCodePreview;
@ -20,7 +21,7 @@ public:
// TriggerPage(QWidget *parent = nullptr); // TriggerPage(QWidget *parent = nullptr);
void setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat); void setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat);
void setFilter(const PgClass &cls); void setFilter(const std::optional<PgClass> &cls);
signals: signals:
public slots: public slots:

View file

@ -20,6 +20,7 @@ public:
int32_t typmod = -1; int32_t typmod = -1;
bool notnull = false; bool notnull = false;
bool hasdef = false; bool hasdef = false;
bool isdropped = false;
Oid collation = InvalidOid; Oid collation = InvalidOid;
QString acl; QString acl;
QString options; QString options;

View file

@ -10,7 +10,7 @@ std::string PgAttributeContainer::getLoadQuery() const
{ {
return R"__( return R"__(
SELECT attrelid, attname, atttypid, attstattarget, SELECT attrelid, attname, atttypid, attstattarget,
attnum, attndims, atttypmod, attnotnull, atthasdef, attnum, attndims, atttypmod, attnotnull, atthasdef, attisdropped,
attcollation, attacl, attoptions, pg_get_expr(adbin, adrelid) AS def_value attcollation, attacl, attoptions, pg_get_expr(adbin, adrelid) AS def_value
FROM pg_catalog.pg_attribute FROM pg_catalog.pg_attribute
LEFT JOIN pg_attrdef ON attrelid=adrelid AND attnum=adnum)__"; LEFT JOIN pg_attrdef ON attrelid=adrelid AND attnum=adnum)__";
@ -21,7 +21,7 @@ PgAttribute PgAttributeContainer::loadElem(const Pgsql::Row &row)
Pgsql::Col col(row); Pgsql::Col col(row);
PgAttribute v; PgAttribute v;
col >> v.relid >> v.name >> v.typid >> v.stattarget col >> v.relid >> v.name >> v.typid >> v.stattarget
>> v.num >> v.ndims >> v.typmod >> v.notnull >> v.hasdef >> v.num >> v.ndims >> v.typmod >> v.notnull >> v.hasdef >> v.isdropped
>> v.collation >> v.acl >> v.options >> v.defaultValue; >> v.collation >> v.acl >> v.options >> v.defaultValue;
return v; return v;
} }