diff --git a/pglab/CustomDataRole.h b/pglab/CustomDataRole.h new file mode 100644 index 0000000..dccd92e --- /dev/null +++ b/pglab/CustomDataRole.h @@ -0,0 +1,10 @@ +#ifndef CUSTOMDATAROLE_H +#define CUSTOMDATAROLE_H + +#include + +enum CustomDataRole { + CustomDataTypeRole = Qt::UserRole, +}; + +#endif // CUSTOMDATAROLE_H diff --git a/pglab/IndexModel.cpp b/pglab/IndexModel.cpp index 93adc16..4e41fa3 100644 --- a/pglab/IndexModel.cpp +++ b/pglab/IndexModel.cpp @@ -3,6 +3,7 @@ #include "PgIndexContainer.h" #include "Pgsql_oids.h" #include "ScopeGuard.h" +#include "CustomDataRole.h" void IndexModel::setData(std::shared_ptr 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; } diff --git a/pglab/PgLabItemDelegate.cpp b/pglab/PgLabItemDelegate.cpp index 0806003..73ea803 100644 --- a/pglab/PgLabItemDelegate.cpp +++ b/pglab/PgLabItemDelegate.cpp @@ -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(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, diff --git a/pglab/PgLabItemDelegate.h b/pglab/PgLabItemDelegate.h index a1322cc..d11701b 100644 --- a/pglab/PgLabItemDelegate.h +++ b/pglab/PgLabItemDelegate.h @@ -3,6 +3,12 @@ #include +/** 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: diff --git a/pglab/PropertyProxyModel.cpp b/pglab/PropertyProxyModel.cpp new file mode 100644 index 0000000..1448a3d --- /dev/null +++ b/pglab/PropertyProxyModel.cpp @@ -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() << Qt::DisplayRole); +} diff --git a/pglab/PropertyProxyModel.h b/pglab/PropertyProxyModel.h new file mode 100644 index 0000000..4d3ea9b --- /dev/null +++ b/pglab/PropertyProxyModel.h @@ -0,0 +1,35 @@ +#ifndef HORIZONTALPROXYMODEL_H +#define HORIZONTALPROXYMODEL_H + +#include + +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 diff --git a/pglab/TablesPage.cpp b/pglab/TablesPage.cpp index 1ba5897..9f33e57 100644 --- a/pglab/TablesPage.cpp +++ b/pglab/TablesPage.cpp @@ -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); diff --git a/pglab/TablesPage.ui b/pglab/TablesPage.ui index 4481693..0df84f6 100644 --- a/pglab/TablesPage.ui +++ b/pglab/TablesPage.ui @@ -1,4 +1,4 @@ - + TablesPage @@ -13,7 +13,7 @@ Form - + @@ -38,7 +38,7 @@ - 0 + 3 @@ -90,6 +90,11 @@ Properties + + + + + diff --git a/pglab/TablesTableModel.cpp b/pglab/TablesTableModel.cpp index 41e42ec..cf38f0a 100644 --- a/pglab/TablesTableModel.cpp +++ b/pglab/TablesTableModel.cpp @@ -5,13 +5,12 @@ #include "PgNamespace.h" #include "PgNamespaceContainer.h" #include "Pgsql_declare.h" +#include "CustomDataRole.h" #include TablesTableModel::TablesTableModel(QObject *parent) - : BaseTableModel(parent) -{ - -} + : QAbstractTableModel(parent) +{} void TablesTableModel::setCatalog(std::shared_ptr 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(); } diff --git a/pglab/TablesTableModel.h b/pglab/TablesTableModel.h index 2c9b16e..1277c82 100644 --- a/pglab/TablesTableModel.h +++ b/pglab/TablesTableModel.h @@ -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; @@ -48,6 +44,8 @@ private: std::shared_ptr 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); }; diff --git a/pglab/pglab.pro b/pglab/pglab.pro index 3058c10..aac271b 100644 --- a/pglab/pglab.pro +++ b/pglab/pglab.pro @@ -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 \ diff --git a/pglablib/PgClass.h b/pglablib/PgClass.h index 82f86b0..6ee7984 100644 --- a/pglablib/PgClass.h +++ b/pglablib/PgClass.h @@ -51,8 +51,8 @@ public: bool ispopulated; int frozenxid; int minmxid; - QString acl; - QString options; + std::vector acl; + std::vector options; bool operator==(Oid _oid) const { return oid == _oid; } bool operator==(const QString &n) const { return name == n; } diff --git a/pglablib/PgClassContainer.cpp b/pglablib/PgClassContainer.cpp index 2accb33..701dc68 100644 --- a/pglablib/PgClassContainer.cpp +++ b/pglablib/PgClassContainer.cpp @@ -3,6 +3,7 @@ #include "Pgsql_Col.h" #include "PgDatabaseCatalog.h" #include "PgNamespaceContainer.h" +#include 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(std::back_inserter(v.acl), Pgsql::NullHandling::Ignore); + col.getAsArray(std::back_inserter(v.options), Pgsql::NullHandling::Ignore); auto cat = m_catalogue.lock(); auto ns = cat->namespaces()->getByKey(v.relnamespace); diff --git a/pglablib/PgDatabaseCatalog.cpp b/pglablib/PgDatabaseCatalog.cpp index e2eff8b..007fa2b 100644 --- a/pglablib/PgDatabaseCatalog.cpp +++ b/pglablib/PgDatabaseCatalog.cpp @@ -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 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 PgDatabaseCatalog::namespaces() cons return m_namespaces; } +std::shared_ptr PgDatabaseCatalog::tablespaces() const +{ + return m_tablespaces; +} + std::shared_ptr PgDatabaseCatalog::types() const { return m_types; diff --git a/pglablib/PgDatabaseCatalog.h b/pglablib/PgDatabaseCatalog.h index 1389322..ca1869c 100644 --- a/pglablib/PgDatabaseCatalog.h +++ b/pglablib/PgDatabaseCatalog.h @@ -21,6 +21,7 @@ class PgDatabaseContainer; class PgIndexContainer; class PgNamespaceContainer; class PgAmContainer; +class PgTablespaceContainer; class PgTypeContainer; class PgDatabaseCatalog: public std::enable_shared_from_this { @@ -37,6 +38,7 @@ public: const QString& serverVersionString() const; int serverVersion() const; + const QString& getDBName() const { return m_dbName; } std::shared_ptr attributes() const; std::shared_ptr authIds() const; @@ -46,10 +48,13 @@ public: std::shared_ptr indexes() const; std::shared_ptr ams() const; std::shared_ptr namespaces() const; + std::shared_ptr tablespaces() const; std::shared_ptr types() const; + private: QString m_serverVersionString; int m_serverVersion; + QString m_dbName; std::shared_ptr m_attributes; std::shared_ptr m_authIds; @@ -59,6 +64,7 @@ private: std::shared_ptr m_indexes; std::shared_ptr m_ams; std::shared_ptr m_namespaces; + std::shared_ptr m_tablespaces; std::shared_ptr m_types; template diff --git a/pglablib/PgDatabaseContainer.h b/pglablib/PgDatabaseContainer.h index 2cf856a..e7bcf1f 100644 --- a/pglablib/PgDatabaseContainer.h +++ b/pglablib/PgDatabaseContainer.h @@ -18,7 +18,6 @@ public: virtual std::string getLoadQuery() const override; virtual void load(const Pgsql::Result &res) override; - private: }; diff --git a/pglablib/PgTablespace.cpp b/pglablib/PgTablespace.cpp new file mode 100644 index 0000000..48709aa --- /dev/null +++ b/pglablib/PgTablespace.cpp @@ -0,0 +1,4 @@ +#include "PgTablespace.h" + +PgTablespace::PgTablespace() +{} diff --git a/pglablib/PgTablespace.h b/pglablib/PgTablespace.h new file mode 100644 index 0000000..cf50c64 --- /dev/null +++ b/pglablib/PgTablespace.h @@ -0,0 +1,24 @@ +#ifndef PGTABLESPACE_H +#define PGTABLESPACE_H + +#include +#include +#include + +class PgTablespace { +public: + Oid oid = InvalidOid; + QString name; + Oid owner = InvalidOid; + std::vector acl; + std::vector 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 diff --git a/pglablib/PgTablespaceContainer.cpp b/pglablib/PgTablespaceContainer.cpp new file mode 100644 index 0000000..092056e --- /dev/null +++ b/pglablib/PgTablespaceContainer.cpp @@ -0,0 +1,25 @@ +#include "PgTablespaceContainer.h" +#include "Pgsql_Connection.h" +#include "Pgsql_Col.h" +#include "Pgsql_declare.h" +#include "PgDatabaseCatalog.h" +#include + +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(std::back_inserter(v.acl), Pgsql::NullHandling::Ignore); + col.getAsArray(std::back_inserter(v.options), Pgsql::NullHandling::Ignore); + return v; +} diff --git a/pglablib/PgTablespaceContainer.h b/pglablib/PgTablespaceContainer.h new file mode 100644 index 0000000..5f427f4 --- /dev/null +++ b/pglablib/PgTablespaceContainer.h @@ -0,0 +1,24 @@ +#ifndef PGTABLESPACECONTAINER_H +#define PGTABLESPACECONTAINER_H + +#include "PgContainer.h" +#include "PgTablespace.h" + +namespace Pgsql { + + class Result; + +} + + +class PgTablespaceContainer: public PgContainer { +public: + using PgContainer::PgContainer; + + virtual std::string getLoadQuery() const override; +protected: + PgTablespace loadElem(const Pgsql::Row &row) override; +private: +}; + +#endif // PGTABLESPACECONTAINER_H diff --git a/pglablib/pglablib.pro b/pglablib/pglablib.pro index 3e33c70..8c4047c 100644 --- a/pglablib/pglablib.pro +++ b/pglablib/pglablib.pro @@ -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 diff --git a/pgsql/Pgsql_Connection.cpp b/pgsql/Pgsql_Connection.cpp index 728e18d..db22689 100644 --- a/pgsql/Pgsql_Connection.cpp +++ b/pgsql/Pgsql_Connection.cpp @@ -263,3 +263,8 @@ void Connection::notifyReceiveFunc(void *arg, const PGresult *result) Connection *c = reinterpret_cast(arg); c->notifyReceiver(result); } + +QString Connection::getDBName() const +{ + return QString::fromUtf8(PQdb(conn)); +} diff --git a/pgsql/Pgsql_Connection.h b/pgsql/Pgsql_Connection.h index c9fd189..bbe34de 100644 --- a/pgsql/Pgsql_Connection.h +++ b/pgsql/Pgsql_Connection.h @@ -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 notifyReceiver; diff --git a/pgsql/Pgsql_oids.h b/pgsql/Pgsql_oids.h index 295ef5c..4be5687 100644 --- a/pgsql/Pgsql_oids.h +++ b/pgsql/Pgsql_oids.h @@ -177,6 +177,13 @@ namespace Pgsql { static Oid elem() { return timestamptz_oid; } static Oid array() { return timestamptz_array_oid; } }; + + template <> + class OidFor { + public: + static Oid elem() { return text_oid; } + static Oid array() { return text_array_oid; } + }; // template <> // class OidFor<> { // public: