Flexible models #76
24 changed files with 333 additions and 51 deletions
10
pglab/CustomDataRole.h
Normal file
10
pglab/CustomDataRole.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef CUSTOMDATAROLE_H
|
||||
#define CUSTOMDATAROLE_H
|
||||
|
||||
#include <Qt>
|
||||
|
||||
enum CustomDataRole {
|
||||
CustomDataTypeRole = Qt::UserRole,
|
||||
};
|
||||
|
||||
#endif // CUSTOMDATAROLE_H
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
#include "PgIndexContainer.h"
|
||||
#include "Pgsql_oids.h"
|
||||
#include "ScopeGuard.h"
|
||||
#include "CustomDataRole.h"
|
||||
|
||||
void IndexModel::setData(std::shared_ptr<const PgDatabaseCatalog> cat, const PgClass &table)
|
||||
{
|
||||
|
|
@ -96,7 +97,7 @@ QVariant IndexModel::data(const QModelIndex &index, int role) const
|
|||
QVariant v;
|
||||
if (role == Qt::DisplayRole)
|
||||
v = getData(index);
|
||||
else if (role == Qt::UserRole)
|
||||
else if (role == CustomDataTypeRole)
|
||||
v = getType(index.column());
|
||||
return v;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ void PgLabItemDelegate::initStyleOption(QStyleOptionViewItem *option,
|
|||
Oid oid = InvalidOid;
|
||||
value = index.data(Qt::UserRole); // get OID
|
||||
if (value.isValid())
|
||||
oid = value.toInt(); //getType(index.column());
|
||||
oid = value.toUInt(); //getType(index.column());
|
||||
|
||||
value = index.data(Qt::DisplayRole);
|
||||
|
||||
|
|
@ -112,7 +112,7 @@ void PgLabItemDelegate::initStyleOption(QStyleOptionViewItem *option,
|
|||
// option->backgroundBrush = qvariant_cast<QBrush>(index.data(Qt::BackgroundRole));
|
||||
|
||||
// disable style animations for checkboxes etc. within itemviews (QTBUG-30146)
|
||||
option->styleObject = 0;
|
||||
option->styleObject = nullptr;
|
||||
}
|
||||
|
||||
void PgLabItemDelegate::paint(QPainter *painter,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,12 @@
|
|||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
/** Delegate for rendering SQL data types in tableviews
|
||||
*
|
||||
* This delegate removes the need for the model to provide formatting information
|
||||
* which in many cases solely based on the datatype so this delegate can determine
|
||||
* on its own what the correct formatting is.
|
||||
*/
|
||||
class PgLabItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
104
pglab/PropertyProxyModel.cpp
Normal file
104
pglab/PropertyProxyModel.cpp
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
#include "PropertyProxyModel.h"
|
||||
/*
|
||||
* Code borrowed from: https://stackoverflow.com/questions/21653253/how-to-change-orientation-of-qt-tableview
|
||||
*
|
||||
* Originally it was called Horizontal_proxy_model however some adjustments were made to it.
|
||||
* Instead of the column headers becoming row headers we now convert them to the first column.
|
||||
* The second column show the values of a single row from the source model. Which is determined
|
||||
* by the setActiveRow call.
|
||||
*/
|
||||
|
||||
|
||||
PropertyProxyModel::PropertyProxyModel(QObject *parent)
|
||||
: QIdentityProxyModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QModelIndex PropertyProxyModel::mapToSource(const QModelIndex &proxyIndex) const
|
||||
{
|
||||
if (sourceModel()) {
|
||||
if (activeRow >= 0) {
|
||||
if (proxyIndex.column() == valueColumn) {
|
||||
return sourceModel()->index(activeRow, proxyIndex.row());
|
||||
}
|
||||
}
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex PropertyProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
|
||||
{
|
||||
if (activeRow >= 0) {
|
||||
if (sourceIndex.row() == activeRow) {
|
||||
return index(sourceIndex.column(), valueColumn);
|
||||
}
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex PropertyProxyModel::index(int row, int column, const QModelIndex &) const
|
||||
{
|
||||
return createIndex(row, column, nullptr);
|
||||
}
|
||||
|
||||
QModelIndex PropertyProxyModel::parent(const QModelIndex &) const
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
int PropertyProxyModel::rowCount(const QModelIndex &) const
|
||||
{
|
||||
return sourceModel() ? sourceModel()->columnCount() : 0;
|
||||
}
|
||||
|
||||
int PropertyProxyModel::columnCount(const QModelIndex &) const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
QVariant PropertyProxyModel::headerData(
|
||||
int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
// if (!sourceModel()) {
|
||||
// return QVariant();
|
||||
// }
|
||||
// Qt::Orientation new_orientation = orientation == Qt::Horizontal ?
|
||||
// Qt::Vertical : Qt::Horizontal;
|
||||
// return sourceModel()->headerData(section, new_orientation, role);
|
||||
if (orientation == Qt::Horizontal) {
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch (section) {
|
||||
case 0:
|
||||
return tr("Property");
|
||||
case 1:
|
||||
return tr("Value");
|
||||
}
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant PropertyProxyModel::data(const QModelIndex &proxyIndex, int role) const
|
||||
{
|
||||
auto sm = sourceModel();
|
||||
if (sm) {
|
||||
switch (proxyIndex.column()) {
|
||||
case 0:
|
||||
// return source header data
|
||||
return sm->headerData(proxyIndex.row(), Qt::Horizontal, role);
|
||||
case 1:
|
||||
// return value if activeRow is set
|
||||
if (activeRow >= 0) {
|
||||
return QIdentityProxyModel::data(proxyIndex, role);
|
||||
}
|
||||
}
|
||||
}
|
||||
//return d->model->data(mapToSource(proxyIndex), role);
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void PropertyProxyModel::setActiveRow(const QModelIndex &row)
|
||||
{
|
||||
activeRow = row.isValid() ? row.row() : -1;
|
||||
emit dataChanged(index(0, valueColumn), index(rowCount(QModelIndex()), valueColumn), QVector<int>() << Qt::DisplayRole);
|
||||
}
|
||||
35
pglab/PropertyProxyModel.h
Normal file
35
pglab/PropertyProxyModel.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef HORIZONTALPROXYMODEL_H
|
||||
#define HORIZONTALPROXYMODEL_H
|
||||
|
||||
#include <QIdentityProxyModel>
|
||||
|
||||
class PropertyProxyModel : public QIdentityProxyModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PropertyProxyModel(QObject * parent = nullptr);
|
||||
QModelIndex mapToSource(const QModelIndex &proxyIndex) const;
|
||||
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
|
||||
QModelIndex parent(const QModelIndex &child) const;
|
||||
int rowCount(const QModelIndex &parent) const;
|
||||
int columnCount(const QModelIndex &parent) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||
QVariant data(const QModelIndex &proxyIndex, int role) const;
|
||||
|
||||
public Q_SLOTS:
|
||||
/** Updates the model (and view) to show the values for row
|
||||
*
|
||||
* The column part of the index is not used QModelIndex is used to make is eacy to connect to
|
||||
* QItemSelectionModel::currentRowChanged
|
||||
*/
|
||||
void setActiveRow(const QModelIndex &row);
|
||||
|
||||
private:
|
||||
enum Columns {
|
||||
propertyColumn = 0,
|
||||
valueColumn
|
||||
};
|
||||
int activeRow = -1;
|
||||
};
|
||||
|
||||
#endif // HORIZONTALPROXYMODEL_H
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
#include "ResultTableModelUtil.h"
|
||||
#include "ColumnTableModel.h"
|
||||
#include "ConstraintModel.h"
|
||||
//#include "NamespaceFilterWidget.h"
|
||||
#include "PropertyProxyModel.h"
|
||||
#include "IconColumnDelegate.h"
|
||||
#include "IndexModel.h"
|
||||
#include "SqlFormattingUtils.h"
|
||||
|
|
@ -24,9 +24,13 @@ TablesPage::TablesPage(MainWindow *parent)
|
|||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
auto pglab_delegate = new PgLabItemDelegate(this);
|
||||
auto icon_delegate = new IconColumnDelegate(this);
|
||||
|
||||
SetTableViewDefault(ui->tableListTable);
|
||||
m_tablesModel = new TablesTableModel(this);
|
||||
ui->tableListTable->setModel(m_tablesModel);
|
||||
ui->tableListTable->setItemDelegate(pglab_delegate);
|
||||
ui->tableListTable->setSortingEnabled(true);
|
||||
ui->tableListTable->sortByColumn(0, Qt::AscendingOrder);
|
||||
|
||||
|
|
@ -36,9 +40,8 @@ TablesPage::TablesPage(MainWindow *parent)
|
|||
|
||||
SetTableViewDefault(ui->constraintsTable);
|
||||
m_constraintModel = new ConstraintModel(this);
|
||||
auto delegate = new IconColumnDelegate(this);
|
||||
ui->constraintsTable->setModel(m_constraintModel);
|
||||
ui->constraintsTable->setItemDelegateForColumn(0, delegate);
|
||||
ui->constraintsTable->setItemDelegateForColumn(0, icon_delegate);
|
||||
|
||||
QFont font;
|
||||
font.setFamily("Source Code Pro");
|
||||
|
|
@ -50,8 +53,18 @@ TablesPage::TablesPage(MainWindow *parent)
|
|||
SetTableViewDefault(ui->indexesTable);
|
||||
m_indexModel = new IndexModel(this);
|
||||
ui->indexesTable->setModel(m_indexModel);
|
||||
ui->indexesTable->setItemDelegate(new PgLabItemDelegate(ui->indexesTable));
|
||||
ui->indexesTable->setItemDelegateForColumn(0, delegate);
|
||||
ui->indexesTable->setItemDelegate(pglab_delegate);
|
||||
ui->indexesTable->setItemDelegateForColumn(0, icon_delegate);
|
||||
|
||||
PropertyProxyModel* property_model = new PropertyProxyModel(this);
|
||||
property_model->setSourceModel(m_tablesModel);
|
||||
SetTableViewDefault(ui->tablePropertiesTable);
|
||||
ui->tablePropertiesTable->setModel(property_model);
|
||||
ui->tablePropertiesTable->setItemDelegate(pglab_delegate);
|
||||
|
||||
connect(ui->tableListTable->selectionModel(), &QItemSelectionModel::currentRowChanged,
|
||||
property_model, &PropertyProxyModel::setActiveRow);
|
||||
|
||||
|
||||
//m_namespaceFilterWidget = new NamespaceFilterWidget(this);
|
||||
//ui->verticalLayoutTableView->addWidget(m_namespaceFilterWidget);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TablesPage</class>
|
||||
<widget class="QWidget" name="TablesPage">
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
</widget>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>3</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="columnsTab">
|
||||
<attribute name="title">
|
||||
|
|
@ -90,6 +90,11 @@
|
|||
<attribute name="title">
|
||||
<string>Properties</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutProperties">
|
||||
<item>
|
||||
<widget class="QTableView" name="tablePropertiesTable"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="statisticsTab">
|
||||
<attribute name="title">
|
||||
|
|
|
|||
|
|
@ -5,13 +5,12 @@
|
|||
#include "PgNamespace.h"
|
||||
#include "PgNamespaceContainer.h"
|
||||
#include "Pgsql_declare.h"
|
||||
#include "CustomDataRole.h"
|
||||
#include <QBrush>
|
||||
|
||||
TablesTableModel::TablesTableModel(QObject *parent)
|
||||
: BaseTableModel(parent)
|
||||
{
|
||||
|
||||
}
|
||||
: QAbstractTableModel(parent)
|
||||
{}
|
||||
|
||||
void TablesTableModel::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat)
|
||||
{
|
||||
|
|
@ -166,11 +165,11 @@ QVariant TablesTableModel::getData(const QModelIndex &index) const
|
|||
v = getTablespaceDisplayString(*m_catalog, t.tablespace);
|
||||
break;
|
||||
case OptionsCol:
|
||||
v = t.options;
|
||||
//v = t.options;
|
||||
break;
|
||||
// case AclCol:
|
||||
// v = t.acl;
|
||||
// break;
|
||||
// case AclCol:
|
||||
// v = t.acl;
|
||||
// break;
|
||||
}
|
||||
|
||||
return v;
|
||||
|
|
@ -195,19 +194,9 @@ QString TablesTableModel::formatTableName(const PgClass &cls) const
|
|||
|
||||
QVariant TablesTableModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
|
||||
if (role == Qt::ForegroundRole) {
|
||||
|
||||
const auto &t = m_tables[index.row()];
|
||||
auto ns = m_catalog->namespaces()->getByKey(t.relnamespace);
|
||||
if (ns.isSystemCatalog()) {
|
||||
switch (index.column()) {
|
||||
case NameCol:
|
||||
case NamespaceCol:
|
||||
return QBrush(Qt::blue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return BaseTableModel::data(index, role);
|
||||
if (role == Qt::DisplayRole)
|
||||
return getData(index);
|
||||
else if (role == CustomDataTypeRole)
|
||||
return getType(index.column());
|
||||
return QVariant();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@
|
|||
class PgClass;
|
||||
class PgDatabaseCatalog;
|
||||
|
||||
class TablesTableModel: public BaseTableModel
|
||||
{
|
||||
class TablesTableModel: public QAbstractTableModel {
|
||||
public:
|
||||
enum e_Columns : int {
|
||||
NameCol, ///< either table, ns.table or table (ns) depending on settings/filters
|
||||
|
|
@ -38,9 +37,6 @@ public:
|
|||
virtual QVariant data(const QModelIndex &index, int role) const override;
|
||||
PgClass getTable(int row) const;
|
||||
Oid getTableOid(int row) const;
|
||||
protected:
|
||||
virtual Oid getType(int column) const override;
|
||||
virtual QVariant getData(const QModelIndex &index) const override;
|
||||
|
||||
private:
|
||||
using t_Tables = std::vector<PgClass>;
|
||||
|
|
@ -48,6 +44,8 @@ private:
|
|||
std::shared_ptr<const PgDatabaseCatalog> m_catalog;
|
||||
t_Tables m_tables;
|
||||
|
||||
Oid getType(int column) const;
|
||||
QVariant getData(const QModelIndex &index) const;
|
||||
QString formatTableName(const PgClass &cls) const;
|
||||
void doSort(int so);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@ SOURCES += main.cpp\
|
|||
Module.cpp \
|
||||
EditorGutter.cpp \
|
||||
CodeEditor.cpp \
|
||||
PlgPage.cpp
|
||||
PlgPage.cpp \
|
||||
PropertyProxyModel.cpp
|
||||
|
||||
HEADERS += \
|
||||
QueryResultModel.h \
|
||||
|
|
@ -119,7 +120,9 @@ HEADERS += \
|
|||
EditorGutter.h \
|
||||
CodeEditor.h \
|
||||
PlgPage.h \
|
||||
AbstractCommand.h
|
||||
AbstractCommand.h \
|
||||
PropertyProxyModel.h \
|
||||
CustomDataRole.h
|
||||
|
||||
FORMS += mainwindow.ui \
|
||||
ConnectionManagerWindow.ui \
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ public:
|
|||
bool ispopulated;
|
||||
int frozenxid;
|
||||
int minmxid;
|
||||
QString acl;
|
||||
QString options;
|
||||
std::vector<QString> acl;
|
||||
std::vector<QString> options;
|
||||
|
||||
bool operator==(Oid _oid) const { return oid == _oid; }
|
||||
bool operator==(const QString &n) const { return name == n; }
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "Pgsql_Col.h"
|
||||
#include "PgDatabaseCatalog.h"
|
||||
#include "PgNamespaceContainer.h"
|
||||
#include <iterator>
|
||||
|
||||
std::string PgClassContainer::getLoadQuery() const
|
||||
{
|
||||
|
|
@ -21,8 +22,10 @@ PgClass PgClassContainer::loadElem(const Pgsql::Row &row)
|
|||
col >> v.oid >> v.name >> v.relnamespace >> v.type >> v.oftype
|
||||
>> v.owner >> v.am >> v.filenode >> v.tablespace >> v.pages_est
|
||||
>> v.tuples_est >> v.toastrelid >> v.isshared >> v.persistence
|
||||
>> v.kind >> v.hasoids >> v.ispopulated >> v.frozenxid >> v.minmxid
|
||||
>> v.acl >> v.options;
|
||||
>> v.kind >> v.hasoids >> v.ispopulated >> v.frozenxid >> v.minmxid;
|
||||
|
||||
col.getAsArray<QString>(std::back_inserter(v.acl), Pgsql::NullHandling::Ignore);
|
||||
col.getAsArray<QString>(std::back_inserter(v.options), Pgsql::NullHandling::Ignore);
|
||||
|
||||
auto cat = m_catalogue.lock();
|
||||
auto ns = cat->namespaces()->getByKey(v.relnamespace);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "PgDatabaseContainer.h"
|
||||
#include "PgIndexContainer.h"
|
||||
#include "PgNamespaceContainer.h"
|
||||
#include "PgTablespaceContainer.h"
|
||||
#include "PgTypeContainer.h"
|
||||
#include "Pgsql_Connection.h"
|
||||
#include "Pgsql_oids.h"
|
||||
|
|
@ -36,7 +37,6 @@ QString getRoleDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
|||
{
|
||||
QString name = getRoleNameFromOid(cat, oid);
|
||||
return name;
|
||||
// return QString("%1 (%2)").arg(name).arg(oid);
|
||||
}
|
||||
|
||||
QString getNamespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
||||
|
|
@ -71,7 +71,12 @@ QString getIndexDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
|||
QString getTablespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
||||
{
|
||||
// TODO load list and lookup name
|
||||
return QString("ts %1").arg(oid);
|
||||
if (oid == 0) {
|
||||
auto dbname = cat.getDBName();
|
||||
oid = cat.databases()->getByName(dbname).tablespace;
|
||||
}
|
||||
auto ts = cat.tablespaces()->getByKey(oid);
|
||||
return ts.name;
|
||||
}
|
||||
|
||||
QString getTypeDisplayString(const PgDatabaseCatalog &cat, Oid oid, int32_t typmod)
|
||||
|
|
@ -129,11 +134,14 @@ void PgDatabaseCatalog::loadAll(Pgsql::Connection &conn,
|
|||
std::function<bool(int, int)> progress_callback)
|
||||
{
|
||||
loadInfo(conn);
|
||||
const int count = 10;
|
||||
const int count = 11;
|
||||
int n = 0;
|
||||
if (progress_callback && !progress_callback(++n, count))
|
||||
return;
|
||||
load2(m_namespaces, conn);
|
||||
if (progress_callback && !progress_callback(++n, count))
|
||||
return;
|
||||
load2(m_tablespaces, conn);
|
||||
if (progress_callback && !progress_callback(++n, count))
|
||||
return;
|
||||
load2(m_classes, conn); // needs namespaces
|
||||
|
|
@ -172,6 +180,8 @@ void PgDatabaseCatalog::loadInfo(Pgsql::Connection &conn)
|
|||
if (r && r.resultStatus() == PGRES_TUPLES_OK)
|
||||
if (r.rows() == 1)
|
||||
m_serverVersionString = r.get(0, 0).asQString();
|
||||
|
||||
m_dbName = conn.getDBName();
|
||||
}
|
||||
|
||||
void load(Pgsql::Connection &conn, IPgContainter &pg_cont)
|
||||
|
|
@ -245,6 +255,11 @@ std::shared_ptr<const PgNamespaceContainer> PgDatabaseCatalog::namespaces() cons
|
|||
return m_namespaces;
|
||||
}
|
||||
|
||||
std::shared_ptr<const PgTablespaceContainer> PgDatabaseCatalog::tablespaces() const
|
||||
{
|
||||
return m_tablespaces;
|
||||
}
|
||||
|
||||
std::shared_ptr<const PgTypeContainer> PgDatabaseCatalog::types() const
|
||||
{
|
||||
return m_types;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ class PgDatabaseContainer;
|
|||
class PgIndexContainer;
|
||||
class PgNamespaceContainer;
|
||||
class PgAmContainer;
|
||||
class PgTablespaceContainer;
|
||||
class PgTypeContainer;
|
||||
|
||||
class PgDatabaseCatalog: public std::enable_shared_from_this<PgDatabaseCatalog> {
|
||||
|
|
@ -37,6 +38,7 @@ public:
|
|||
|
||||
const QString& serverVersionString() const;
|
||||
int serverVersion() const;
|
||||
const QString& getDBName() const { return m_dbName; }
|
||||
|
||||
std::shared_ptr<const PgAttributeContainer> attributes() const;
|
||||
std::shared_ptr<const PgAuthIdContainer> authIds() const;
|
||||
|
|
@ -46,10 +48,13 @@ public:
|
|||
std::shared_ptr<const PgIndexContainer> indexes() const;
|
||||
std::shared_ptr<const PgAmContainer> ams() const;
|
||||
std::shared_ptr<const PgNamespaceContainer> namespaces() const;
|
||||
std::shared_ptr<const PgTablespaceContainer> tablespaces() const;
|
||||
std::shared_ptr<const PgTypeContainer> types() const;
|
||||
|
||||
private:
|
||||
QString m_serverVersionString;
|
||||
int m_serverVersion;
|
||||
QString m_dbName;
|
||||
|
||||
std::shared_ptr<PgAttributeContainer> m_attributes;
|
||||
std::shared_ptr<PgAuthIdContainer> m_authIds;
|
||||
|
|
@ -59,6 +64,7 @@ private:
|
|||
std::shared_ptr<PgIndexContainer> m_indexes;
|
||||
std::shared_ptr<PgAmContainer> m_ams;
|
||||
std::shared_ptr<PgNamespaceContainer> m_namespaces;
|
||||
std::shared_ptr<PgTablespaceContainer> m_tablespaces;
|
||||
std::shared_ptr<PgTypeContainer> m_types;
|
||||
|
||||
template <typename T>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ public:
|
|||
|
||||
virtual std::string getLoadQuery() const override;
|
||||
virtual void load(const Pgsql::Result &res) override;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
|
|
|||
4
pglablib/PgTablespace.cpp
Normal file
4
pglablib/PgTablespace.cpp
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#include "PgTablespace.h"
|
||||
|
||||
PgTablespace::PgTablespace()
|
||||
{}
|
||||
24
pglablib/PgTablespace.h
Normal file
24
pglablib/PgTablespace.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef PGTABLESPACE_H
|
||||
#define PGTABLESPACE_H
|
||||
|
||||
#include <QString>
|
||||
#include <libpq-fe.h>
|
||||
#include <vector>
|
||||
|
||||
class PgTablespace {
|
||||
public:
|
||||
Oid oid = InvalidOid;
|
||||
QString name;
|
||||
Oid owner = InvalidOid;
|
||||
std::vector<QString> acl;
|
||||
std::vector<QString> options;
|
||||
|
||||
PgTablespace();
|
||||
|
||||
bool operator==(Oid _oid) const { return oid == _oid; }
|
||||
//bool operator==(const QString &n) const { return name == n; }
|
||||
bool operator<(Oid _oid) const { return oid < _oid; }
|
||||
bool operator<(const PgTablespace &rhs) const { return oid < rhs.oid; }
|
||||
};
|
||||
|
||||
#endif // PGTABLESPACE_H
|
||||
25
pglablib/PgTablespaceContainer.cpp
Normal file
25
pglablib/PgTablespaceContainer.cpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#include "PgTablespaceContainer.h"
|
||||
#include "Pgsql_Connection.h"
|
||||
#include "Pgsql_Col.h"
|
||||
#include "Pgsql_declare.h"
|
||||
#include "PgDatabaseCatalog.h"
|
||||
#include <iterator>
|
||||
|
||||
std::string PgTablespaceContainer::getLoadQuery() const
|
||||
{
|
||||
return
|
||||
R"__SQL__(
|
||||
SELECT oid, spcname, spcowner, spcacl, spcoptions
|
||||
FROM pg_tablespace
|
||||
)__SQL__";
|
||||
}
|
||||
|
||||
PgTablespace PgTablespaceContainer::loadElem(const Pgsql::Row &row)
|
||||
{
|
||||
Pgsql::Col col(row);
|
||||
PgTablespace v;
|
||||
col >> v.oid >> v.name >> v.owner;
|
||||
col.getAsArray<QString>(std::back_inserter(v.acl), Pgsql::NullHandling::Ignore);
|
||||
col.getAsArray<QString>(std::back_inserter(v.options), Pgsql::NullHandling::Ignore);
|
||||
return v;
|
||||
}
|
||||
24
pglablib/PgTablespaceContainer.h
Normal file
24
pglablib/PgTablespaceContainer.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef PGTABLESPACECONTAINER_H
|
||||
#define PGTABLESPACECONTAINER_H
|
||||
|
||||
#include "PgContainer.h"
|
||||
#include "PgTablespace.h"
|
||||
|
||||
namespace Pgsql {
|
||||
|
||||
class Result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
class PgTablespaceContainer: public PgContainer<PgTablespace> {
|
||||
public:
|
||||
using PgContainer<PgTablespace>::PgContainer;
|
||||
|
||||
virtual std::string getLoadQuery() const override;
|
||||
protected:
|
||||
PgTablespace loadElem(const Pgsql::Row &row) override;
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // PGTABLESPACECONTAINER_H
|
||||
|
|
@ -55,7 +55,9 @@ SOURCES += \
|
|||
QueryGenerator.cpp \
|
||||
PgAm.cpp \
|
||||
PgAmContainer.cpp \
|
||||
PgObject.cpp
|
||||
PgObject.cpp \
|
||||
PgTablespace.cpp \
|
||||
PgTablespaceContainer.cpp
|
||||
|
||||
HEADERS += \
|
||||
Pglablib.h \
|
||||
|
|
@ -88,7 +90,9 @@ HEADERS += \
|
|||
QueryGenerator.h \
|
||||
PgAm.h \
|
||||
PgAmContainer.h \
|
||||
PgObject.h
|
||||
PgObject.h \
|
||||
PgTablespace.h \
|
||||
PgTablespaceContainer.h
|
||||
|
||||
unix {
|
||||
target.path = /usr/lib
|
||||
|
|
|
|||
|
|
@ -263,3 +263,8 @@ void Connection::notifyReceiveFunc(void *arg, const PGresult *result)
|
|||
Connection *c = reinterpret_cast<Connection *>(arg);
|
||||
c->notifyReceiver(result);
|
||||
}
|
||||
|
||||
QString Connection::getDBName() const
|
||||
{
|
||||
return QString::fromUtf8(PQdb(conn));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,6 +124,8 @@ namespace Pgsql {
|
|||
QString escapeLiteral(const QString &literal);
|
||||
std::string escapeIdentifier(const std::string_view &ident);
|
||||
QString escapeIdentifier(const QString &ident);
|
||||
|
||||
QString getDBName() const;
|
||||
private:
|
||||
PGconn *conn = nullptr;
|
||||
std::function<void(const PGresult *)> notifyReceiver;
|
||||
|
|
|
|||
|
|
@ -177,6 +177,13 @@ namespace Pgsql {
|
|||
static Oid elem() { return timestamptz_oid; }
|
||||
static Oid array() { return timestamptz_array_oid; }
|
||||
};
|
||||
|
||||
template <>
|
||||
class OidFor<QString> {
|
||||
public:
|
||||
static Oid elem() { return text_oid; }
|
||||
static Oid array() { return text_array_oid; }
|
||||
};
|
||||
// template <>
|
||||
// class OidFor<> {
|
||||
// public:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue