Added page with the types (no details yet)
This commit is contained in:
parent
bdef76ed8a
commit
4c175d8c2c
16 changed files with 418 additions and 11 deletions
|
|
@ -22,7 +22,7 @@ QVariant BaseTableModel::data(const QModelIndex &index, int role) const
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant BaseTableModel::getDataMeaning(const QModelIndex &index) const
|
QVariant BaseTableModel::getDataMeaning(const QModelIndex &) const
|
||||||
{
|
{
|
||||||
return static_cast<int>(DataMeaningNormal);
|
return static_cast<int>(DataMeaningNormal);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include "widgets/CatalogNamespacePage.h"
|
#include "widgets/CatalogNamespacePage.h"
|
||||||
#include "widgets/CatalogSequencesPage.h"
|
#include "widgets/CatalogSequencesPage.h"
|
||||||
#include "widgets/CatalogTablesPage.h"
|
#include "widgets/CatalogTablesPage.h"
|
||||||
|
#include "widgets/CatalogTypesPage.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QTabWidget>
|
#include <QTabWidget>
|
||||||
|
|
@ -20,6 +21,7 @@ CatalogInspector::CatalogInspector(std::shared_ptr<OpenDatabase> open_database,
|
||||||
m_tablesPage = new CatalogTablesPage(this);
|
m_tablesPage = new CatalogTablesPage(this);
|
||||||
m_functionsPage = new CatalogFunctionsPage(this);
|
m_functionsPage = new CatalogFunctionsPage(this);
|
||||||
m_sequencesPage = new CatalogSequencesPage(this);
|
m_sequencesPage = new CatalogSequencesPage(this);
|
||||||
|
m_typesPage = new CatalogTypesPage(this);
|
||||||
|
|
||||||
auto layout = new QVBoxLayout(this);
|
auto layout = new QVBoxLayout(this);
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
|
@ -28,6 +30,7 @@ CatalogInspector::CatalogInspector(std::shared_ptr<OpenDatabase> open_database,
|
||||||
m_tabWidget->addTab(m_tablesPage, "");
|
m_tabWidget->addTab(m_tablesPage, "");
|
||||||
m_tabWidget->addTab(m_functionsPage, "");
|
m_tabWidget->addTab(m_functionsPage, "");
|
||||||
m_tabWidget->addTab(m_sequencesPage, "");
|
m_tabWidget->addTab(m_sequencesPage, "");
|
||||||
|
m_tabWidget->addTab(m_typesPage, "");
|
||||||
|
|
||||||
setCatalog(open_database->catalog());
|
setCatalog(open_database->catalog());
|
||||||
retranslateUi(false);
|
retranslateUi(false);
|
||||||
|
|
@ -45,6 +48,8 @@ void CatalogInspector::retranslateUi(bool all)
|
||||||
QApplication::translate("CatalogInspector", "Functions", nullptr));
|
QApplication::translate("CatalogInspector", "Functions", nullptr));
|
||||||
m_tabWidget->setTabText(m_tabWidget->indexOf(m_sequencesPage),
|
m_tabWidget->setTabText(m_tabWidget->indexOf(m_sequencesPage),
|
||||||
QApplication::translate("CatalogInspector", "Sequences", nullptr));
|
QApplication::translate("CatalogInspector", "Sequences", nullptr));
|
||||||
|
m_tabWidget->setTabText(m_tabWidget->indexOf(m_typesPage),
|
||||||
|
QApplication::translate("CatalogInspector", "Types", nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
CatalogInspector::~CatalogInspector()
|
CatalogInspector::~CatalogInspector()
|
||||||
|
|
@ -58,6 +63,7 @@ void CatalogInspector::setCatalog(std::shared_ptr<PgDatabaseCatalog> cat)
|
||||||
m_tablesPage->setCatalog(cat);
|
m_tablesPage->setCatalog(cat);
|
||||||
m_functionsPage->setCatalog(cat);
|
m_functionsPage->setCatalog(cat);
|
||||||
m_sequencesPage->setCatalog(cat);
|
m_sequencesPage->setCatalog(cat);
|
||||||
|
m_typesPage->setCatalog(cat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CatalogInspector::setNamespaceFilter(NamespaceFilter filter)
|
void CatalogInspector::setNamespaceFilter(NamespaceFilter filter)
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ class CatalogFunctionsPage;
|
||||||
class CatalogSequencesPage;
|
class CatalogSequencesPage;
|
||||||
class CatalogTablesPage;
|
class CatalogTablesPage;
|
||||||
class CatalogNamespacePage;
|
class CatalogNamespacePage;
|
||||||
|
class CatalogTypesPage;
|
||||||
class OpenDatabase;
|
class OpenDatabase;
|
||||||
class PgDatabaseCatalog;
|
class PgDatabaseCatalog;
|
||||||
class QTabWidget;
|
class QTabWidget;
|
||||||
|
|
@ -29,6 +30,7 @@ private:
|
||||||
CatalogTablesPage *m_tablesPage = nullptr;
|
CatalogTablesPage *m_tablesPage = nullptr;
|
||||||
CatalogFunctionsPage *m_functionsPage = nullptr;
|
CatalogFunctionsPage *m_functionsPage = nullptr;
|
||||||
CatalogSequencesPage *m_sequencesPage = nullptr;
|
CatalogSequencesPage *m_sequencesPage = nullptr;
|
||||||
|
CatalogTypesPage *m_typesPage = nullptr;
|
||||||
std::shared_ptr<PgDatabaseCatalog> m_catalog;
|
std::shared_ptr<PgDatabaseCatalog> m_catalog;
|
||||||
|
|
||||||
void retranslateUi(bool all = true);
|
void retranslateUi(bool all = true);
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ ColumnPage::ColumnPage(QWidget *parent)
|
||||||
m_tableView->setItemDelegateForColumn(ColumnTableModel::TypeCol, new QStyledItemDelegate(this));
|
m_tableView->setItemDelegateForColumn(ColumnTableModel::TypeCol, new QStyledItemDelegate(this));
|
||||||
m_tableView->setModel(m_sortFilterProxy);
|
m_tableView->setModel(m_sortFilterProxy);
|
||||||
m_tableView->setSortingEnabled(true);
|
m_tableView->setSortingEnabled(true);
|
||||||
m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
// m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
m_sortFilterProxy->sort(ColumnTableModel::AttnumCol, Qt::AscendingOrder);
|
m_sortFilterProxy->sort(ColumnTableModel::AttnumCol, Qt::AscendingOrder);
|
||||||
|
|
||||||
connect(m_tableView->selectionModel(), &QItemSelectionModel::selectionChanged,
|
connect(m_tableView->selectionModel(), &QItemSelectionModel::selectionChanged,
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ void PropertyProxyModel::setActiveRow(const QModelIndex &row)
|
||||||
QVector<int>() << Qt::DisplayRole);
|
QVector<int>() << Qt::DisplayRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt::ItemFlags PropertyProxyModel::flags(const QModelIndex &index) const
|
Qt::ItemFlags PropertyProxyModel::flags(const QModelIndex &) const
|
||||||
{
|
{
|
||||||
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,6 @@ QVariant RolesTableModel::getData(const QModelIndex &index) const
|
||||||
v = authid.bypassRls;
|
v = authid.bypassRls;
|
||||||
break;
|
break;
|
||||||
case ConnlimitCol:
|
case ConnlimitCol:
|
||||||
// todo lookup tablespace name
|
|
||||||
v = authid.connLimit;
|
v = authid.connLimit;
|
||||||
break;
|
break;
|
||||||
case ValidUntilCol:
|
case ValidUntilCol:
|
||||||
|
|
|
||||||
101
pglab/TypeModel.cpp
Normal file
101
pglab/TypeModel.cpp
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
#include "TypeModel.h"
|
||||||
|
#include "catalog/PgDatabaseCatalog.h"
|
||||||
|
#include "catalog/PgNamespace.h"
|
||||||
|
#include "catalog/PgTypeContainer.h"
|
||||||
|
|
||||||
|
TypeModel::TypeModel(QObject * parent)
|
||||||
|
: QAbstractTableModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant TypeModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
if (orientation == Qt::Horizontal) {
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
switch (section) {
|
||||||
|
case NameCol: return tr("Name");
|
||||||
|
case SchemaCol: return tr("Schema");
|
||||||
|
case OwnerCol: return tr("Owner");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void TypeModel::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat)
|
||||||
|
{
|
||||||
|
if (cat != m_catalog) {
|
||||||
|
m_catalog = cat;
|
||||||
|
refreshConnection = connect(m_catalog.get(), &PgDatabaseCatalog::refreshed,
|
||||||
|
this, &TypeModel::refresh);
|
||||||
|
}
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
//void TypeModel::setNamespaceFilter(NamespaceFilter filter)
|
||||||
|
//{
|
||||||
|
// m_namespaceFilter = filter;
|
||||||
|
// refresh();
|
||||||
|
//}
|
||||||
|
|
||||||
|
void TypeModel::refresh()
|
||||||
|
{
|
||||||
|
if (!m_catalog)
|
||||||
|
return;
|
||||||
|
|
||||||
|
beginResetModel();
|
||||||
|
|
||||||
|
auto && typs = m_catalog->types();
|
||||||
|
m_types.clear();
|
||||||
|
for (auto&& s : *typs) {
|
||||||
|
// bool add = false;
|
||||||
|
// switch (m_namespaceFilter) {
|
||||||
|
// case NamespaceFilter::User:
|
||||||
|
// add = !s.ns().isSystemCatalog();
|
||||||
|
// break;
|
||||||
|
// case NamespaceFilter::PgCatalog:
|
||||||
|
// add = s.ns().objectName() == "pg_catalog";
|
||||||
|
// break;
|
||||||
|
// case NamespaceFilter::InformationSchema:
|
||||||
|
// add = s.ns().objectName() == "information_schema";
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// if (add)
|
||||||
|
m_types.push_back(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
PgType TypeModel::typ(int row) const
|
||||||
|
{
|
||||||
|
return m_types.at(static_cast<size_t>(row));
|
||||||
|
}
|
||||||
|
|
||||||
|
int TypeModel::rowCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_types.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
int TypeModel::columnCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return colCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant TypeModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (m_types.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
int row = index.row();
|
||||||
|
auto && seq = m_types.at(static_cast<size_t>(row));
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
switch (index.column()) {
|
||||||
|
case NameCol: return seq.objectName();
|
||||||
|
case SchemaCol: return seq.nsName();
|
||||||
|
case OwnerCol: return seq.ownerName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
40
pglab/TypeModel.h
Normal file
40
pglab/TypeModel.h
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef TYPEMODEL_H
|
||||||
|
#define TYPEMODEL_H
|
||||||
|
|
||||||
|
#include <QAbstractTableModel>
|
||||||
|
#include "catalog/PgType.h"
|
||||||
|
|
||||||
|
class TypeModel : public QAbstractTableModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum e_Columns : int {
|
||||||
|
NameCol,
|
||||||
|
SchemaCol,
|
||||||
|
OwnerCol,
|
||||||
|
|
||||||
|
colCount
|
||||||
|
};
|
||||||
|
|
||||||
|
TypeModel(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 setNamespaceFilter(NamespaceFilter filter);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
PgType typ(int row) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<const PgDatabaseCatalog> m_catalog;
|
||||||
|
std::vector<PgType> m_types;
|
||||||
|
//NamespaceFilter m_namespaceFilter = NamespaceFilter::User;
|
||||||
|
QMetaObject::Connection refreshConnection;
|
||||||
|
|
||||||
|
void refresh();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -87,7 +87,8 @@ PropertyProxyModel.cpp \
|
||||||
widgets/CatalogConstraintPage.cpp \
|
widgets/CatalogConstraintPage.cpp \
|
||||||
widgets/CatalogTablesPage.cpp \
|
widgets/CatalogTablesPage.cpp \
|
||||||
widgets/CatalogFunctionsPage.cpp \
|
widgets/CatalogFunctionsPage.cpp \
|
||||||
widgets/CatalogSequencesPage.cpp
|
widgets/CatalogSequencesPage.cpp \
|
||||||
|
widgets/CatalogTypesPage.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
ConnectionConfigurationWidget.h \
|
ConnectionConfigurationWidget.h \
|
||||||
|
|
@ -160,7 +161,8 @@ CustomDataRole.h \
|
||||||
widgets/CatalogTablesPage.h \
|
widgets/CatalogTablesPage.h \
|
||||||
widgets/CatalogFunctionsPage.h \
|
widgets/CatalogFunctionsPage.h \
|
||||||
widgets/CatalogSequencesPage.h \
|
widgets/CatalogSequencesPage.h \
|
||||||
NamespaceFilter.h
|
NamespaceFilter.h \
|
||||||
|
widgets/CatalogTypesPage.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
ConnectionManagerWindow.ui \
|
ConnectionManagerWindow.ui \
|
||||||
|
|
|
||||||
78
pglab/widgets/CatalogTypesPage.cpp
Normal file
78
pglab/widgets/CatalogTypesPage.cpp
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
#include "CatalogTypesPage.h"
|
||||||
|
#include "ResultTableModelUtil.h"
|
||||||
|
#include "CustomFilterSortModel.h"
|
||||||
|
#include "CustomDataRole.h"
|
||||||
|
#include "PgLabItemDelegate.h"
|
||||||
|
#include "catalog/PgType.h"
|
||||||
|
#include "model/TypeSelectionItemModel.h"
|
||||||
|
#include "SqlCodePreview.h"
|
||||||
|
#include "PgLabTableView.h"
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
CatalogTypesPage::CatalogTypesPage(QWidget *parent)
|
||||||
|
: QSplitter(Qt::Horizontal, parent)
|
||||||
|
{
|
||||||
|
m_typeTable = new PgLabTableView(this);
|
||||||
|
m_definitionView = new SqlCodePreview(this);
|
||||||
|
|
||||||
|
// build widget tree
|
||||||
|
// add top level widgets to splitter
|
||||||
|
addWidget(m_typeTable);
|
||||||
|
addWidget(m_definitionView);
|
||||||
|
|
||||||
|
m_model = new TypeModel(this);
|
||||||
|
m_sortFilterProxy = new CustomFilterSortModel(this);
|
||||||
|
m_sortFilterProxy->setSourceModel(m_model);
|
||||||
|
m_typeTable->setModel(m_sortFilterProxy);
|
||||||
|
m_typeTable->setSortingEnabled(true);
|
||||||
|
m_typeTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
|
m_typeTable->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
|
|
||||||
|
connect(m_typeTable->selectionModel(), &QItemSelectionModel::currentRowChanged, this,
|
||||||
|
&CatalogTypesPage::typeTable_currentRowChanged);
|
||||||
|
connect(m_model, &TypeModel::modelReset,
|
||||||
|
[this] () { selectedTypeChanged({}); });
|
||||||
|
|
||||||
|
retranslateUi();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CatalogTypesPage::retranslateUi()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CatalogTypesPage::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat)
|
||||||
|
{
|
||||||
|
m_catalog = cat;
|
||||||
|
m_model->setTypeList(cat->types());
|
||||||
|
m_typeTable->resizeColumnsToContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CatalogTypesPage::typeTable_currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous)
|
||||||
|
{
|
||||||
|
if (current.row() != previous.row()) {
|
||||||
|
if (current.isValid()) {
|
||||||
|
auto source_index = m_sortFilterProxy->mapToSource(current);
|
||||||
|
auto proc = m_model->typ(source_index.row());
|
||||||
|
selectedTypeChanged(proc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
selectedTypeChanged({});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CatalogTypesPage::selectedTypeChanged(const std::optional<PgType> &typ)
|
||||||
|
{
|
||||||
|
updateSqlTab(typ);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CatalogTypesPage::updateSqlTab(const std::optional<PgType> &typ)
|
||||||
|
{
|
||||||
|
if (!typ.has_value()) {
|
||||||
|
m_definitionView->clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QString create_sql = typ->createSql();
|
||||||
|
|
||||||
|
m_definitionView->setPlainText(create_sql);
|
||||||
|
}
|
||||||
34
pglab/widgets/CatalogTypesPage.h
Normal file
34
pglab/widgets/CatalogTypesPage.h
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QSplitter>
|
||||||
|
|
||||||
|
class PgLabTableView;
|
||||||
|
class PgDatabaseCatalog;
|
||||||
|
class TypeModel;
|
||||||
|
class CustomFilterSortModel;
|
||||||
|
class SqlCodePreview;
|
||||||
|
class PgType;
|
||||||
|
|
||||||
|
|
||||||
|
class CatalogTypesPage : public QSplitter
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
CatalogTypesPage(QWidget *parent = nullptr);
|
||||||
|
void setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat);
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void typeTable_currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||||
|
private:
|
||||||
|
PgLabTableView *m_typeTable = nullptr;
|
||||||
|
//QTabWidget *m_detailTabs = nullptr;
|
||||||
|
SqlCodePreview *m_definitionView = nullptr;
|
||||||
|
TypeModel *m_model = nullptr;
|
||||||
|
CustomFilterSortModel *m_sortFilterProxy = nullptr;
|
||||||
|
std::shared_ptr<const PgDatabaseCatalog> m_catalog;
|
||||||
|
|
||||||
|
void retranslateUi();
|
||||||
|
void selectedTypeChanged(const std::optional<PgType> &seq);
|
||||||
|
void updateSqlTab(const std::optional<PgType> &seq);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -12,7 +12,10 @@ void operator<<(TypCategory &s, const Pgsql::Value &v)
|
||||||
case 'B':
|
case 'B':
|
||||||
s = TypCategory::Boolean;
|
s = TypCategory::Boolean;
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'C':
|
||||||
|
s = TypCategory::Composite;
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
s = TypCategory::DateTime;
|
s = TypCategory::DateTime;
|
||||||
break;
|
break;
|
||||||
case 'E':
|
case 'E':
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "TypeSelectionItemModel.h"
|
#include "TypeSelectionItemModel.h"
|
||||||
|
//#include "CustomDataRole.h"
|
||||||
#include "catalog/PgTypeContainer.h"
|
#include "catalog/PgTypeContainer.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
@ -56,7 +57,7 @@ void TypeSelectionItemModel::setTypeList(std::shared_ptr<const PgTypeContainer>
|
||||||
std::sort(m_types.begin(), m_types.end());
|
std::sort(m_types.begin(), m_types.end());
|
||||||
}
|
}
|
||||||
//emit dataChanged(this->createIndex(0, 0), this->createIndex(types->count(), 0), QVector<int>() << Qt::DisplayRole);
|
//emit dataChanged(this->createIndex(0, 0), this->createIndex(types->count(), 0), QVector<int>() << Qt::DisplayRole);
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------
|
// ----------------
|
||||||
|
|
@ -82,6 +83,9 @@ int TypeModel::columnCount(const QModelIndex &/*parent*/) const
|
||||||
|
|
||||||
QVariant TypeModel::data(const QModelIndex &index, int role) const
|
QVariant TypeModel::data(const QModelIndex &index, int role) const
|
||||||
{
|
{
|
||||||
|
// if (role == CustomDataTypeRole)
|
||||||
|
// return getType(index.column());
|
||||||
|
|
||||||
if (index.isValid()) {
|
if (index.isValid()) {
|
||||||
int row = index.row();
|
int row = index.row();
|
||||||
int column = index.column();
|
int column = index.column();
|
||||||
|
|
@ -91,15 +95,90 @@ QVariant TypeModel::data(const QModelIndex &index, int role) const
|
||||||
switch (column) {
|
switch (column) {
|
||||||
case OidCol: return elem.oid();
|
case OidCol: return elem.oid();
|
||||||
case NameCol: return elem.objectName();
|
case NameCol: return elem.objectName();
|
||||||
|
case NamespaceCol: return elem.nsName();
|
||||||
|
case OwnerCol: return elem.ownerName();
|
||||||
|
case CategoryCol: return TypCategoryString(elem.category);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TypeModel::TypCategoryString(TypCategory tc)
|
||||||
|
{
|
||||||
|
switch (tc) {
|
||||||
|
case TypCategory::Array:
|
||||||
|
return tr("array");
|
||||||
|
case TypCategory::Boolean:
|
||||||
|
return tr("boolean");
|
||||||
|
case TypCategory::Composite:
|
||||||
|
return tr("composite");
|
||||||
|
case TypCategory::DateTime:
|
||||||
|
return tr("datetime");
|
||||||
|
case TypCategory::Enum:
|
||||||
|
return tr("enum");
|
||||||
|
case TypCategory::Geometric:
|
||||||
|
return tr("geometric");
|
||||||
|
case TypCategory::NetworkAddress:
|
||||||
|
return tr("networkaddress");
|
||||||
|
case TypCategory::Numeric:
|
||||||
|
return tr("numeric");
|
||||||
|
case TypCategory::Pseudo:
|
||||||
|
return tr("pseude");
|
||||||
|
case TypCategory::Range:
|
||||||
|
return tr("range");
|
||||||
|
case TypCategory::String:
|
||||||
|
return tr("string");
|
||||||
|
case TypCategory::Timespan:
|
||||||
|
return tr("timespan");
|
||||||
|
case TypCategory::UserDefined:
|
||||||
|
return tr("user");
|
||||||
|
case TypCategory::BitString:
|
||||||
|
return tr("bitstring");
|
||||||
|
case TypCategory::Unknown:
|
||||||
|
return tr("unknown");
|
||||||
|
}
|
||||||
|
return "?";
|
||||||
|
}
|
||||||
|
|
||||||
|
Oid TypeModel::getType(int column) const
|
||||||
|
{
|
||||||
|
switch (column) {
|
||||||
|
case OidCol:
|
||||||
|
return Pgsql::oid_oid;
|
||||||
|
case NameCol:
|
||||||
|
case NamespaceCol:
|
||||||
|
case OwnerCol:
|
||||||
|
case CategoryCol:
|
||||||
|
return Pgsql::varchar_oid;
|
||||||
|
}
|
||||||
|
return InvalidOid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeModel::setTypeList(std::shared_ptr<const PgTypeContainer> types)
|
void TypeModel::setTypeList(std::shared_ptr<const PgTypeContainer> types)
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
m_types = types;
|
m_types = types;
|
||||||
endResetModel();
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
PgType TypeModel::typ(int row) const
|
||||||
|
{
|
||||||
|
return m_types->getByIdx(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant TypeModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
if (orientation == Qt::Horizontal) {
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
switch (section) {
|
||||||
|
case OidCol: return tr("Oid");
|
||||||
|
case NameCol: return tr("Name");
|
||||||
|
case NamespaceCol: return tr("Schema");
|
||||||
|
case OwnerCol: return tr("Owner");
|
||||||
|
case CategoryCol: return tr("Category");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "catalog/PgType.h"
|
||||||
|
|
||||||
class PgTypeContainer;
|
class PgTypeContainer;
|
||||||
|
|
||||||
|
|
@ -28,19 +29,27 @@ public:
|
||||||
enum e_Columns : int {
|
enum e_Columns : int {
|
||||||
OidCol,
|
OidCol,
|
||||||
NameCol, //
|
NameCol, //
|
||||||
|
NamespaceCol,
|
||||||
|
OwnerCol,
|
||||||
|
CategoryCol,
|
||||||
colCount
|
colCount
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit TypeModel(QObject *parent = 0);
|
explicit TypeModel(QObject *parent = 0);
|
||||||
|
|
||||||
void setTypeList(std::shared_ptr<const PgTypeContainer> types);
|
void setTypeList(std::shared_ptr<const PgTypeContainer> types);
|
||||||
|
PgType typ(int row) const;
|
||||||
|
|
||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
QVariant headerData(int section, Qt::Orientation orientation, int role) 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 = Qt::DisplayRole) const override;
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<const PgTypeContainer> m_types;
|
std::shared_ptr<const PgTypeContainer> m_types;
|
||||||
|
|
||||||
|
static QString TypCategoryString(TypCategory tc);
|
||||||
|
Oid getType(int column) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,48 @@ QString ConvertToMultiLineRawCppString(const QString &in)
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class Token {
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
Code,
|
||||||
|
StringLiteral,
|
||||||
|
SingleLineComment,
|
||||||
|
MultiLineComment
|
||||||
|
};
|
||||||
|
|
||||||
|
const Type type;
|
||||||
|
/// Depends on type
|
||||||
|
/// Code: literal copy of the matched code
|
||||||
|
/// StringLiteral: the contents of the string literal, escapes have been unescaped
|
||||||
|
/// *Comment, the text in the comment
|
||||||
|
const QString data;
|
||||||
|
|
||||||
|
Token(Type type, QString data)
|
||||||
|
: type(type)
|
||||||
|
, data(data)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Tokenizer to get SQL out of a piece of programming language code
|
||||||
|
///
|
||||||
|
/// It works by ignoring most input and only get's triggered by string literals
|
||||||
|
/// and comments. It does return tokens for the code in between just so
|
||||||
|
class ProgLangTokenizer {
|
||||||
|
public:
|
||||||
|
ProgLangTokenizer(const QString &in)
|
||||||
|
: input(in)
|
||||||
|
{}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const QString input;
|
||||||
|
int position = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
QString ConvertLangToSqlString(const QString &in)
|
QString ConvertLangToSqlString(const QString &in)
|
||||||
{
|
{
|
||||||
// Assume mostly C++ for now but allow some other things like
|
// Assume mostly C++ for now but allow some other things like
|
||||||
|
|
@ -232,6 +274,7 @@ QString ConvertLangToSqlString(const QString &in)
|
||||||
WHITESPACE,
|
WHITESPACE,
|
||||||
PREFIX,
|
PREFIX,
|
||||||
IN_STRING,
|
IN_STRING,
|
||||||
|
SingleLineComment,
|
||||||
END,
|
END,
|
||||||
ERROR
|
ERROR
|
||||||
} state = WHITESPACE;
|
} state = WHITESPACE;
|
||||||
|
|
|
||||||
|
|
@ -60,3 +60,14 @@ TEST(ConvertLangToSqlString, testSemiColon)
|
||||||
auto output = ConvertLangToSqlString(in);
|
auto output = ConvertLangToSqlString(in);
|
||||||
ASSERT_EQ(output, expected);
|
ASSERT_EQ(output, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ConvertLangToSqlString, testComment)
|
||||||
|
{
|
||||||
|
QString in(R"__( "SELECT * " // comment
|
||||||
|
"FROM t"; )__");
|
||||||
|
QString expected(R"__(SELECT *
|
||||||
|
FROM t)__");
|
||||||
|
|
||||||
|
auto output = ConvertLangToSqlString(in);
|
||||||
|
ASSERT_EQ(output, expected);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue