poc Add support for reloading the catalog
Reload works and the column page reacts correctly. Others to be checked and fixed.
This commit is contained in:
parent
83122e89df
commit
60d8f36328
8 changed files with 89 additions and 40 deletions
|
|
@ -34,6 +34,7 @@ ColumnPage::ColumnPage(QWidget *parent)
|
|||
|
||||
connect(m_tableView->selectionModel(), &QItemSelectionModel::selectionChanged,
|
||||
this, &ColumnPage::tableView_selectionChanged);
|
||||
connect(m_columnModel, &ColumnTableModel::modelReset, m_definitionView, &SqlCodePreview::clear);
|
||||
}
|
||||
|
||||
void ColumnPage::setData(std::shared_ptr<const PgDatabaseCatalog> cat, const std::optional<PgClass> &cls)
|
||||
|
|
@ -43,7 +44,6 @@ void ColumnPage::setData(std::shared_ptr<const PgDatabaseCatalog> cat, const std
|
|||
m_columnModel->setData(cat, cls);
|
||||
m_Class = cls;
|
||||
m_tableView->resizeColumnsToContents();
|
||||
m_definitionView->setPlainText("");
|
||||
}
|
||||
|
||||
void ColumnPage::tableView_selectionChanged(const QItemSelection &/*selected*/, const QItemSelection &/*deselected*/)
|
||||
|
|
|
|||
|
|
@ -31,38 +31,12 @@ namespace {
|
|||
|
||||
void ColumnTableModel::setData(std::shared_ptr<const PgDatabaseCatalog> cat, const std::optional<PgClass> &table)
|
||||
{
|
||||
beginResetModel();
|
||||
SCOPE_EXIT { endResetModel(); };
|
||||
|
||||
m_table = table;
|
||||
if (cat != m_catalog) {
|
||||
m_catalog = cat;
|
||||
if (m_table) {
|
||||
m_columns = cat->attributes()->getColumnsForRelation(table->oid());
|
||||
// hide system and dropped columns
|
||||
auto column_filter_pred = table->hasoids ? ColumnFilterWithOidsPred : ColumnFilterWithoutOidsPred;
|
||||
auto si = std::remove_if(m_columns.begin(), m_columns.end(), column_filter_pred);
|
||||
// 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; });
|
||||
refreshConnection = connect(m_catalog.get(), &PgDatabaseCatalog::refreshed, this, &ColumnTableModel::refresh);
|
||||
}
|
||||
else
|
||||
m_columns.clear();
|
||||
|
||||
|
||||
if (m_table) {
|
||||
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.oid() < r.oid());
|
||||
});
|
||||
}
|
||||
else
|
||||
m_indexes.clear();
|
||||
m_table = table;
|
||||
refresh();
|
||||
}
|
||||
|
||||
QVariant ColumnTableModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
|
|
@ -245,6 +219,42 @@ QString ColumnTableModel::getFKey(const PgAttribute &column) const
|
|||
return result;
|
||||
}
|
||||
|
||||
void ColumnTableModel::refresh()
|
||||
{
|
||||
beginResetModel();
|
||||
SCOPE_EXIT { endResetModel(); };
|
||||
|
||||
if (m_table) {
|
||||
m_columns = m_catalog->attributes()->getColumnsForRelation(m_table->oid());
|
||||
// hide system and dropped columns
|
||||
auto column_filter_pred = m_table->hasoids ? ColumnFilterWithOidsPred : ColumnFilterWithoutOidsPred;
|
||||
auto si = std::remove_if(m_columns.begin(), m_columns.end(), column_filter_pred);
|
||||
// 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; });
|
||||
}
|
||||
else
|
||||
m_columns.clear();
|
||||
|
||||
|
||||
if (m_table) {
|
||||
m_indexes = m_catalog->indexes()->getIndexesForTable(m_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.oid() < r.oid());
|
||||
});
|
||||
}
|
||||
else
|
||||
m_indexes.clear();
|
||||
|
||||
emit
|
||||
}
|
||||
|
||||
QVariant ColumnTableModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (role == Qt::ForegroundRole && index.column() == TypeCol) {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "BaseTableModel.h"
|
||||
#include "catalog/PgAttribute.h"
|
||||
#include "catalog/PgDatabaseCatalog.h"
|
||||
#include "catalog/PgClass.h"
|
||||
#include "catalog/PgIndex.h"
|
||||
#include <memory>
|
||||
|
|
@ -13,6 +14,7 @@ class PgDatabaseCatalog;
|
|||
class PgAttribute;
|
||||
|
||||
class ColumnTableModel: public BaseTableModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum e_Columns : int {
|
||||
AttnumCol,
|
||||
|
|
@ -49,8 +51,15 @@ protected:
|
|||
t_Columns m_columns;
|
||||
std::vector<PgIndex> m_indexes;
|
||||
|
||||
QMetaObject::Connection refreshConnection;
|
||||
|
||||
QString getFKey(const PgAttribute &column) const;
|
||||
|
||||
|
||||
|
||||
private slots:
|
||||
/// Retrieves required data from catalog, called everytime it might have changed
|
||||
void refresh();
|
||||
};
|
||||
|
||||
#endif // COLUMNTABLEMODEL_H
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "CrudTab.h"
|
||||
#include "widgets/CatalogTablesPage.h"
|
||||
#include "OpenDatabase.h"
|
||||
#include "catalog/PgDatabaseCatalog.h"
|
||||
#include "ConnectionController.h"
|
||||
#include "MasterController.h"
|
||||
#include "TaskExecutor.h"
|
||||
|
|
@ -221,6 +222,11 @@ void DatabaseWindow::createActions()
|
|||
action->setObjectName("actionPasteLangString");
|
||||
action->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_V));
|
||||
}
|
||||
{
|
||||
QIcon icon;
|
||||
auto action = actionRefreshCatalog = new QAction(icon, tr("Refresh"), this);
|
||||
action->setObjectName("actionRefreshCatalog");
|
||||
}
|
||||
{
|
||||
QIcon icon;
|
||||
icon.addFile(QString::fromUtf8(":/icons/script_save.png"), QSize(), QIcon::Normal, QIcon::On);
|
||||
|
|
@ -278,6 +284,11 @@ void DatabaseWindow::initMenus()
|
|||
actionCancelQuery
|
||||
});
|
||||
|
||||
menuCatalog = mb->addMenu(tr("Catalog"));
|
||||
menuCatalog->addActions({
|
||||
actionRefreshCatalog
|
||||
});
|
||||
|
||||
menuWindow = mb->addMenu(tr("Window"));
|
||||
menuWindow->addActions({
|
||||
actionInspectUserSchemas,
|
||||
|
|
@ -500,6 +511,11 @@ void DatabaseWindow::on_actionPasteLangString_triggered()
|
|||
}
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionRefreshCatalog_triggered()
|
||||
{
|
||||
m_database->refresh();
|
||||
}
|
||||
|
||||
void DatabaseWindow::on_actionSaveSql_triggered()
|
||||
{
|
||||
auto query_tool = GetActiveQueryTool();
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ private:
|
|||
QAction *actionNewSql = nullptr;
|
||||
QAction *actionOpenSql = nullptr;
|
||||
QAction *actionPasteLangString = nullptr;
|
||||
QAction *actionRefreshCatalog = nullptr;
|
||||
QAction *actionSaveSql = nullptr;
|
||||
QAction *actionSaveSqlAs = nullptr;
|
||||
QAction *actionSaveCopyOfSqlAs = nullptr;
|
||||
|
|
@ -87,6 +88,7 @@ private:
|
|||
QMenu *menuFile = nullptr;
|
||||
QMenu *menuHelp = nullptr;
|
||||
QMenu *menuQuery = nullptr;
|
||||
QMenu *menuCatalog = nullptr;
|
||||
QMenu *menuWindow = nullptr;
|
||||
|
||||
|
||||
|
|
@ -140,6 +142,7 @@ private slots:
|
|||
void on_actionNewSql_triggered();
|
||||
void on_actionOpenSql_triggered();
|
||||
void on_actionPasteLangString_triggered();
|
||||
void on_actionRefreshCatalog_triggered();
|
||||
void on_actionSaveSql_triggered();
|
||||
void on_actionSaveSqlAs_triggered();
|
||||
void on_actionSaveCopyOfSqlAs_triggered();
|
||||
|
|
|
|||
|
|
@ -27,14 +27,7 @@ OpenDatabase::~OpenDatabase() = default;
|
|||
|
||||
void OpenDatabase::Init()
|
||||
{
|
||||
Pgsql::Connection conn;
|
||||
std::string connstr = m_config.connectionString().toStdString();
|
||||
if (conn.connect(connstr.c_str())) {
|
||||
m_catalog->loadAll(conn, nullptr);
|
||||
}
|
||||
else {
|
||||
qDebug() << "Connect failed connstr: " << connstr.c_str();
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
std::shared_ptr<PgDatabaseCatalog> OpenDatabase::catalog()
|
||||
|
|
@ -51,3 +44,15 @@ TypeSelectionItemModel* OpenDatabase::typeSelectionModel()
|
|||
}
|
||||
return m_typeSelectionModel;
|
||||
}
|
||||
|
||||
void OpenDatabase::refresh()
|
||||
{
|
||||
Pgsql::Connection conn;
|
||||
std::string connstr = m_config.connectionString().toStdString();
|
||||
if (conn.connect(connstr.c_str())) {
|
||||
m_catalog->loadAll(conn, nullptr);
|
||||
}
|
||||
else {
|
||||
qDebug() << "Connect failed connstr: " << connstr.c_str();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public:
|
|||
|
||||
std::shared_ptr<PgDatabaseCatalog> catalog();
|
||||
TypeSelectionItemModel* typeSelectionModel();
|
||||
void refresh();
|
||||
|
||||
const ConnectionConfig& config() const { return m_config; }
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -32,6 +32,11 @@ class PgInheritsContainer;
|
|||
class PgLanguageContainer;
|
||||
class PgSequenceContainer;
|
||||
|
||||
/// Manages all the catalog data for the database so the program
|
||||
/// can efficiently retrieve information from memory.
|
||||
///
|
||||
/// All the containers are created once during the first load. After
|
||||
/// that they are reused on reload so signals will stay connected.
|
||||
class PgDatabaseCatalog: public QObject, public std::enable_shared_from_this<PgDatabaseCatalog> {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue