WIP: Added page showing list of functions.
Only list is shown, still working on details.
This commit is contained in:
parent
7db859737a
commit
840af1e0a9
19 changed files with 635 additions and 92 deletions
|
|
@ -58,7 +58,8 @@ HEADERS += PasswordManager.h \
|
||||||
SqlAstSelectList.h \
|
SqlAstSelectList.h \
|
||||||
SqlAstSelectListEntry.h \
|
SqlAstSelectListEntry.h \
|
||||||
SqlAstSelect.h \
|
SqlAstSelect.h \
|
||||||
SqlAstExpression.h
|
SqlAstExpression.h \
|
||||||
|
std_utils.h
|
||||||
|
|
||||||
unix {
|
unix {
|
||||||
target.path = /usr/lib
|
target.path = /usr/lib
|
||||||
|
|
|
||||||
14
core/std_utils.h
Normal file
14
core/std_utils.h
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef STD_UTILS_H
|
||||||
|
#define STD_UTILS_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
const T& value_or(const std::vector<T> &vec, const size_t index, const T &def)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= vec.size())
|
||||||
|
return def;
|
||||||
|
return vec[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // STD_UTILS_H
|
||||||
40
pglab/FunctionsPage.cpp
Normal file
40
pglab/FunctionsPage.cpp
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
#include "FunctionsPage.h"
|
||||||
|
#include "ResultTableModelUtil.h"
|
||||||
|
#include "CustomFilterSortModel.h"
|
||||||
|
#include "CustomDataRole.h"
|
||||||
|
#include "PgLabItemDelegate.h"
|
||||||
|
#include "ProcTableModel.h"
|
||||||
|
#include <QTableView>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
FunctionsPage::FunctionsPage(QWidget *parent) : QWidget(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
m_functionTable = new QTableView(this);
|
||||||
|
SetTableViewDefault(m_functionTable);
|
||||||
|
|
||||||
|
m_model = new ProcTableModel(this);
|
||||||
|
m_sortFilterProxy = new CustomFilterSortModel(this);
|
||||||
|
m_sortFilterProxy->setSourceModel(m_model);
|
||||||
|
m_functionTable->setModel(m_sortFilterProxy);
|
||||||
|
m_functionTable->setSortingEnabled(true);
|
||||||
|
m_functionTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
|
|
||||||
|
auto item_delegate = new PgLabItemDelegate(this);
|
||||||
|
m_functionTable->setItemDelegate(item_delegate);
|
||||||
|
|
||||||
|
auto mainLayout = new QVBoxLayout;
|
||||||
|
mainLayout->addWidget(m_functionTable);
|
||||||
|
setLayout(mainLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FunctionsPage::retranslateUi(bool all)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FunctionsPage::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat)
|
||||||
|
{
|
||||||
|
m_catalog = cat;
|
||||||
|
m_model->setCatalog(cat);
|
||||||
|
}
|
||||||
32
pglab/FunctionsPage.h
Normal file
32
pglab/FunctionsPage.h
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef FUNCTIONSPAGE_H
|
||||||
|
#define FUNCTIONSPAGE_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class QTableView;
|
||||||
|
class PgDatabaseCatalog;
|
||||||
|
class ProcTableModel;
|
||||||
|
class CustomFilterSortModel;
|
||||||
|
|
||||||
|
class FunctionsPage : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit FunctionsPage(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
void setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat);
|
||||||
|
signals:
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTableView *m_functionTable = nullptr;
|
||||||
|
ProcTableModel *m_model = nullptr;
|
||||||
|
CustomFilterSortModel *m_sortFilterProxy = nullptr;
|
||||||
|
std::shared_ptr<const PgDatabaseCatalog> m_catalog;
|
||||||
|
|
||||||
|
void retranslateUi(bool all = true);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FUNCTIONSPAGE_H
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "ui_MainWindow.h"
|
#include "ui_MainWindow.h"
|
||||||
#include "TablesPage.h"
|
#include "TablesPage.h"
|
||||||
|
#include "FunctionsPage.h"
|
||||||
|
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
|
@ -103,8 +104,10 @@ void MainWindow::catalogLoaded()
|
||||||
auto tt = new TablesPage(this);
|
auto tt = new TablesPage(this);
|
||||||
tt->setCatalog(m_database->catalog());
|
tt->setCatalog(m_database->catalog());
|
||||||
ui->tabWidget->addTab(tt, "Tables");
|
ui->tabWidget->addTab(tt, "Tables");
|
||||||
ui->tabWidget->setCurrentWidget(tt);
|
|
||||||
|
|
||||||
|
auto functions_page = new FunctionsPage(this);
|
||||||
|
functions_page->setCatalog(m_database->catalog());
|
||||||
|
ui->tabWidget->addTab(functions_page, "Functions");
|
||||||
|
|
||||||
newSqlPage();
|
newSqlPage();
|
||||||
} catch (std::runtime_error &ex) {
|
} catch (std::runtime_error &ex) {
|
||||||
|
|
|
||||||
90
pglab/ProcTableModel.cpp
Normal file
90
pglab/ProcTableModel.cpp
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
#include "ProcTableModel.h"
|
||||||
|
#include "PgDatabaseCatalog.h"
|
||||||
|
#include "PgProcContainer.h"
|
||||||
|
#include "CustomDataRole.h"
|
||||||
|
|
||||||
|
ProcTableModel::ProcTableModel(QObject *parent)
|
||||||
|
: QAbstractTableModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ProcTableModel::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 NamespaceCol: return tr("Schema");
|
||||||
|
case OwnerCol: return tr("Owner");
|
||||||
|
case LangCol: return tr("Language");
|
||||||
|
case AclCol: return tr("ACL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcTableModel::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat)
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
|
||||||
|
m_catalog = cat;
|
||||||
|
m_procs = cat->procs();
|
||||||
|
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ProcTableModel::rowCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return m_procs ? static_cast<int>(m_procs->count()) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ProcTableModel::columnCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return colCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ProcTableModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (role == Qt::DisplayRole)
|
||||||
|
return getData(index);
|
||||||
|
else if (role == CustomDataTypeRole)
|
||||||
|
return getType(index.column());
|
||||||
|
// else if (role == FirstHiddenValue) {
|
||||||
|
// auto&& t = m_triggers->getByIdx(index.row());
|
||||||
|
// return t.relid; //
|
||||||
|
// }
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
PgProc ProcTableModel::proc(int row) const
|
||||||
|
{
|
||||||
|
return m_procs->getByIdx(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
Oid ProcTableModel::getType(int ) const
|
||||||
|
{
|
||||||
|
// switch (column) {
|
||||||
|
// case NameCol: return tr("Name");
|
||||||
|
// case NamespaceCol: return tr("Schema");
|
||||||
|
// case OwnerCol: return tr("Owner");
|
||||||
|
// case LangCol: return tr("Language");
|
||||||
|
// return Pgsql::bool_oid;
|
||||||
|
// }
|
||||||
|
return Pgsql::varchar_oid;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ProcTableModel::getData(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
auto&& t = m_procs->getByIdx(index.row());
|
||||||
|
switch (index.column()) {
|
||||||
|
case NameCol: return t.name;
|
||||||
|
case NamespaceCol: return t.schemaOid();
|
||||||
|
case OwnerCol: return t.owner;
|
||||||
|
case LangCol: return t.lang;
|
||||||
|
case AclCol: return t.acl;
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
56
pglab/ProcTableModel.h
Normal file
56
pglab/ProcTableModel.h
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
#ifndef PROCTABLEMODEL_H
|
||||||
|
#define PROCTABLEMODEL_H
|
||||||
|
|
||||||
|
#include <QAbstractTableModel>
|
||||||
|
#include "PgClass.h"
|
||||||
|
#include "PgProc.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class PgDatabaseCatalog;
|
||||||
|
class PgProcContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The ProcTableModel class
|
||||||
|
*
|
||||||
|
* Hidden values:
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ProcTableModel: public QAbstractTableModel {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
//using QAbstractTableModel::QAbstractTableModel;
|
||||||
|
|
||||||
|
enum e_Columns : int {
|
||||||
|
NameCol, //
|
||||||
|
NamespaceCol, // Schema
|
||||||
|
OwnerCol,
|
||||||
|
LangCol,
|
||||||
|
AclCol,
|
||||||
|
|
||||||
|
colCount
|
||||||
|
};
|
||||||
|
|
||||||
|
ProcTableModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||||
|
void setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat);
|
||||||
|
|
||||||
|
// Basic functionality:
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
|
||||||
|
virtual QVariant data(const QModelIndex &index, int role) const override;
|
||||||
|
|
||||||
|
PgProc proc(int row) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<const PgDatabaseCatalog> m_catalog;
|
||||||
|
std::shared_ptr<const PgProcContainer> m_procs;
|
||||||
|
|
||||||
|
Oid getType(int column) const;
|
||||||
|
QVariant getData(const QModelIndex &index) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // PROCTABLEMODEL_H
|
||||||
|
|
@ -92,32 +92,19 @@ void TablesTableModel::doSort(int )
|
||||||
|
|
||||||
QVariant TablesTableModel::headerData(int section, Qt::Orientation orientation, int role) const
|
QVariant TablesTableModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
{
|
{
|
||||||
QVariant v;
|
|
||||||
if (orientation == Qt::Horizontal) {
|
if (orientation == Qt::Horizontal) {
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
switch (section) {
|
switch (section) {
|
||||||
case NameCol:
|
case NameCol: return tr("Name");
|
||||||
v = tr("Name");
|
case NamespaceCol: return tr("Schema");
|
||||||
break;
|
case OwnerCol: return tr("Owner");
|
||||||
case NamespaceCol:
|
case TablespaceCol: return tr("Tablespace");
|
||||||
v = tr("Schema");
|
case OptionsCol: return tr("Options");
|
||||||
break;
|
case AclCol: return tr("ACL");
|
||||||
case OwnerCol:
|
|
||||||
v = tr("Owner");
|
|
||||||
break;
|
|
||||||
case TablespaceCol:
|
|
||||||
v = tr("Tablespace");
|
|
||||||
break;
|
|
||||||
case OptionsCol:
|
|
||||||
v = tr("Options");
|
|
||||||
break;
|
|
||||||
// case AclCol:
|
|
||||||
// v = tr("ACL");
|
|
||||||
// break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v;
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Basic functionality:
|
// Basic functionality:
|
||||||
|
|
@ -140,7 +127,7 @@ Oid TablesTableModel::getType(int column) const
|
||||||
case NameCol:
|
case NameCol:
|
||||||
case NamespaceCol:
|
case NamespaceCol:
|
||||||
case OptionsCol:
|
case OptionsCol:
|
||||||
// case AclCol:
|
case AclCol:
|
||||||
default:
|
default:
|
||||||
oid = Pgsql::varchar_oid;
|
oid = Pgsql::varchar_oid;
|
||||||
}
|
}
|
||||||
|
|
@ -149,30 +136,17 @@ Oid TablesTableModel::getType(int column) const
|
||||||
|
|
||||||
QVariant TablesTableModel::getData(const QModelIndex &index) const
|
QVariant TablesTableModel::getData(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
QVariant v;
|
|
||||||
const auto &t = m_tables[index.row()];
|
const auto &t = m_tables[index.row()];
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case NameCol:
|
case NameCol: return t.name; //formatTableName(t);
|
||||||
v = t.name; //formatTableName(t);
|
case NamespaceCol: return getNamespaceDisplayString(*m_catalog, t.relnamespace);
|
||||||
break;
|
case OwnerCol: return getRoleDisplayString(*m_catalog, t.owner);
|
||||||
case NamespaceCol:
|
case TablespaceCol: return getTablespaceDisplayString(*m_catalog, t.tablespace);
|
||||||
v = getNamespaceDisplayString(*m_catalog, t.relnamespace);
|
case OptionsCol: break;
|
||||||
break;
|
case AclCol: return t.acl;
|
||||||
case OwnerCol:
|
|
||||||
v = getRoleDisplayString(*m_catalog, t.owner);
|
|
||||||
break;
|
|
||||||
case TablespaceCol:
|
|
||||||
v = getTablespaceDisplayString(*m_catalog, t.tablespace);
|
|
||||||
break;
|
|
||||||
case OptionsCol:
|
|
||||||
//v = t.options;
|
|
||||||
break;
|
|
||||||
// case AclCol:
|
|
||||||
// v = t.acl;
|
|
||||||
// break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
PgClass TablesTableModel::getTable(int row) const
|
PgClass TablesTableModel::getTable(int row) const
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ public:
|
||||||
OwnerCol,
|
OwnerCol,
|
||||||
TablespaceCol,
|
TablespaceCol,
|
||||||
OptionsCol,
|
OptionsCol,
|
||||||
//AclCol,
|
AclCol,
|
||||||
colCount };
|
colCount };
|
||||||
|
|
||||||
TablesTableModel(QObject *parent);
|
TablesTableModel(QObject *parent);
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,9 @@ PropertyProxyModel.cpp \
|
||||||
SqlCodePreview.cpp \
|
SqlCodePreview.cpp \
|
||||||
CustomFilterSortModel.cpp \
|
CustomFilterSortModel.cpp \
|
||||||
PropertiesPage.cpp \
|
PropertiesPage.cpp \
|
||||||
PasswordPromptDialog.cpp
|
PasswordPromptDialog.cpp \
|
||||||
|
ProcTableModel.cpp \
|
||||||
|
FunctionsPage.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
QueryResultModel.h \
|
QueryResultModel.h \
|
||||||
|
|
@ -132,7 +134,9 @@ CustomDataRole.h \
|
||||||
SqlCodePreview.h \
|
SqlCodePreview.h \
|
||||||
CustomFilterSortModel.h \
|
CustomFilterSortModel.h \
|
||||||
PropertiesPage.h \
|
PropertiesPage.h \
|
||||||
PasswordPromptDialog.h
|
PasswordPromptDialog.h \
|
||||||
|
ProcTableModel.h \
|
||||||
|
FunctionsPage.h
|
||||||
|
|
||||||
FORMS += mainwindow.ui \
|
FORMS += mainwindow.ui \
|
||||||
ConnectionManagerWindow.ui \
|
ConnectionManagerWindow.ui \
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ public:
|
||||||
bool ispopulated;
|
bool ispopulated;
|
||||||
int frozenxid;
|
int frozenxid;
|
||||||
int minmxid;
|
int minmxid;
|
||||||
std::vector<QString> acl;
|
QString acl;
|
||||||
std::vector<QString> options;
|
std::vector<QString> options;
|
||||||
|
|
||||||
bool operator==(Oid _oid) const { return oid == _oid; }
|
bool operator==(Oid _oid) const { return oid == _oid; }
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,283 @@
|
||||||
#include "PgProc.h"
|
#include "PgProc.h"
|
||||||
|
#include "std_utils.h"
|
||||||
|
#include "SqlFormattingUtils.h"
|
||||||
|
#include "PgDatabaseCatalog.h"
|
||||||
|
#include "PgTypeContainer.h"
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
Arg::Mode CharToArgMode(char c)
|
||||||
|
{
|
||||||
|
switch (c) {
|
||||||
|
case 'i': return Arg::In;
|
||||||
|
case 'o': return Arg::Out;
|
||||||
|
case 'b': return Arg::InOut;
|
||||||
|
case 'v': return Arg::Variadic;
|
||||||
|
case 't': return Arg::Table;
|
||||||
|
}
|
||||||
|
throw std::runtime_error("Unexpected value for pg_proc.proargmodes");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ArgModeToString(Arg::Mode m)
|
||||||
|
{
|
||||||
|
switch (m) {
|
||||||
|
case Arg::In: return "IN";
|
||||||
|
case Arg::Out: return "OUT";
|
||||||
|
case Arg::InOut: return "INOUT";
|
||||||
|
case Arg::Variadic: return "VARIADIC";
|
||||||
|
case Arg::Table: return "TABLE";
|
||||||
|
}
|
||||||
|
throw std::runtime_error("Unexpected value for Arg::Mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<QString> getArrayFromCommaSeparatedList(const QString &str)
|
||||||
|
{
|
||||||
|
std::vector<QString> res;
|
||||||
|
const int len = str.length();
|
||||||
|
if (len == 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
// setup start state for parsing
|
||||||
|
int index = 0, brackets = 0, start_array = 0;
|
||||||
|
bool single_quote = false, double_quote = false;
|
||||||
|
|
||||||
|
for(; index < len; index++) {
|
||||||
|
QChar ch = str[index];
|
||||||
|
if (!double_quote && ch == L'\'')
|
||||||
|
single_quote = !single_quote;
|
||||||
|
else if (!single_quote && ch == L'"')
|
||||||
|
double_quote = !double_quote;
|
||||||
|
else if (!double_quote && !single_quote && ch == L'(')
|
||||||
|
brackets++;
|
||||||
|
else if (!double_quote && !single_quote && ch == L')')
|
||||||
|
brackets--;
|
||||||
|
else if (!double_quote && !single_quote && brackets == 0 && ch == L',') {
|
||||||
|
if (index != start_array)
|
||||||
|
res.push_back(str.mid(start_array, index - 1).trimmed());
|
||||||
|
else
|
||||||
|
res.push_back(QString());
|
||||||
|
start_array = index + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (double_quote || single_quote || brackets != 0)
|
||||||
|
throw std::runtime_error("Error parsing comma seperated array");
|
||||||
|
|
||||||
|
|
||||||
|
// Add last value to array
|
||||||
|
res.push_back(str.right(start_array).trimmed());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
QString PgProc::objectName() const
|
QString PgProc::objectName() const
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PgProc::setArgs(
|
||||||
|
std::vector<Oid> argtypes,
|
||||||
|
std::vector<Oid> allargtypes,
|
||||||
|
std::vector<char> argmodes,
|
||||||
|
std::vector<QString> argnames,
|
||||||
|
std::optional<QString> argdefaults
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// When all args are of type IN allargtypes is empty and only argtypes is filled
|
||||||
|
const std::vector<Oid> &types = allargtypes.empty() ? argtypes : allargtypes;
|
||||||
|
const size_t count = types.size();
|
||||||
|
m_args.clear();
|
||||||
|
m_args.reserve(count);
|
||||||
|
for (size_t index = 0; index < count; ++index) {
|
||||||
|
// we "forget" the default here because it is easier
|
||||||
|
// to apply them in reverse order when we have already
|
||||||
|
// filled the list
|
||||||
|
m_args.emplace_back(
|
||||||
|
types[index],
|
||||||
|
CharToArgMode(value_or(argmodes, index, 'i')),
|
||||||
|
value_or(argnames, index, QString()),
|
||||||
|
""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
auto defaults_array = getArrayFromCommaSeparatedList(argdefaults.value_or(QString()));
|
||||||
|
|
||||||
|
// Apply defaults from end to start to IN en INOUT parameters (others can't have a default)
|
||||||
|
size_t arg_idx = m_args.size() - 1;
|
||||||
|
for (auto def_iter = defaults_array.rbegin(); def_iter != defaults_array.rend(); ++def_iter) {
|
||||||
|
// skip arguments with wrong mode
|
||||||
|
while (m_args[arg_idx].mode != Arg::In && m_args[arg_idx].mode != Arg::InOut)
|
||||||
|
if (arg_idx == 0) throw std::runtime_error("Error processing defaults");
|
||||||
|
else --arg_idx;
|
||||||
|
m_args[arg_idx].def = *def_iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<Arg>& PgProc::args() const
|
||||||
|
{
|
||||||
|
return m_args;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PgProc::argListWithNames(bool multiline) const
|
||||||
|
{
|
||||||
|
QString args;
|
||||||
|
size_t nArgs = 0;
|
||||||
|
|
||||||
|
auto&& types = catalog().types();
|
||||||
|
|
||||||
|
for (auto&& arg_elem : m_args) {
|
||||||
|
|
||||||
|
// All Table arguments lies at the end of the list
|
||||||
|
// Do not include them as the part of the argument list
|
||||||
|
if (arg_elem.mode == Arg::Table)
|
||||||
|
break;
|
||||||
|
|
||||||
|
nArgs++;
|
||||||
|
if (args.length() > 0)
|
||||||
|
args += (multiline) ? ",\n " : ", ";
|
||||||
|
|
||||||
|
QString arg;
|
||||||
|
if (arg_elem.mode != Arg::In)
|
||||||
|
arg += ArgModeToString(arg_elem.mode);
|
||||||
|
|
||||||
|
if (!arg_elem.name.isEmpty()) {
|
||||||
|
if (!arg.isEmpty())
|
||||||
|
arg += " ";
|
||||||
|
arg += quoteIdent(arg_elem.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!arg.isEmpty())
|
||||||
|
arg += " ";
|
||||||
|
arg += types->getByKey(arg_elem.type)->name;
|
||||||
|
|
||||||
|
if (!arg_elem.def.isEmpty())
|
||||||
|
arg += " DEFAULT " + arg_elem.def;
|
||||||
|
|
||||||
|
args += arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multiline && nArgs > 1)
|
||||||
|
args = "\n " + args;
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the signature arguments list. If forScript = true, we format the list
|
||||||
|
// appropriately for use in a SELECT script.
|
||||||
|
QString PgProc::argSigList(const bool forScript) const
|
||||||
|
{
|
||||||
|
QString args;
|
||||||
|
|
||||||
|
auto&& types = catalog().types();
|
||||||
|
|
||||||
|
for (auto&& arg_elem : m_args) {
|
||||||
|
// OUT parameters are not considered part of the signature, except for EDB-SPL,
|
||||||
|
// although this is not true for EDB AS90 onwards..
|
||||||
|
if (arg_elem.mode != Arg::Out && arg_elem.mode != Arg::Table) {
|
||||||
|
if (args.length() > 0) {
|
||||||
|
if (forScript)
|
||||||
|
args += ",\n";
|
||||||
|
else
|
||||||
|
args += ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString typname = types->getByKey(arg_elem.type)->name;
|
||||||
|
if (forScript)
|
||||||
|
args += " <" + typname + ">";
|
||||||
|
else
|
||||||
|
args += typname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString PgProc::createSql() const
|
||||||
|
{
|
||||||
|
if (createSqlCache.isEmpty()) {
|
||||||
|
QString sql;
|
||||||
|
|
||||||
|
//wxString qtName = GetQuotedFullIdentifier() + wxT("(") + GetArgListWithNames(true) + wxT(")");
|
||||||
|
QString quoted_name = QString("%1(%2)").arg(fullyQualifiedQuotedObjectName(), argListWithNames(true));
|
||||||
|
// wxString qtSig = GetQuotedFullIdentifier() + wxT("(") + GetArgSigList() + wxT(")");
|
||||||
|
QString quoted_sig = QString("%1(%2)").arg(fullyQualifiedQuotedObjectName(), argSigList());
|
||||||
|
|
||||||
|
auto&& types = catalog().types();
|
||||||
|
QString return_type = types->getByKey(rettype)->name;
|
||||||
|
|
||||||
|
|
||||||
|
sql = QString("-- Function: %1\n\n"
|
||||||
|
"-- DROP FUNCTION %1;\n\n"
|
||||||
|
"CREATE OR REPLACE FUNCTION %2\n"
|
||||||
|
" RETURNS %3 AS\n"
|
||||||
|
).arg(quoted_sig, quoted_name, return_type);
|
||||||
|
|
||||||
|
// if (GetLanguage().IsSameAs(wxT("C"), false))
|
||||||
|
// {
|
||||||
|
// sql += qtDbString(GetBin()) + wxT(", ") + qtDbString(GetSource());
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// if (GetConnection()->BackendMinimumVersion(7, 5))
|
||||||
|
// sql += qtDbStringDollar(GetSource());
|
||||||
|
sql += dollarQuoteString(src);
|
||||||
|
// else
|
||||||
|
// sql += qtDbString(GetSource());
|
||||||
|
// }
|
||||||
|
// sql += wxT("\n LANGUAGE ") + GetLanguage() + wxT(" ");
|
||||||
|
// if (GetConnection()->BackendMinimumVersion(8, 4) && GetIsWindow())
|
||||||
|
// sql += wxT("WINDOW ");
|
||||||
|
// sql += GetVolatility();
|
||||||
|
|
||||||
|
// if (GetConnection()->BackendMinimumVersion(9, 2) && GetIsLeakProof())
|
||||||
|
// sql += wxT(" LEAKPROOF");
|
||||||
|
// if (GetIsStrict())
|
||||||
|
// sql += wxT(" STRICT");
|
||||||
|
// if (GetSecureDefiner())
|
||||||
|
// sql += wxT(" SECURITY DEFINER");
|
||||||
|
|
||||||
|
// // PostgreSQL 8.3+ cost/row estimations
|
||||||
|
// if (GetConnection()->BackendMinimumVersion(8, 3))
|
||||||
|
// {
|
||||||
|
// sql += wxT("\n COST ") + NumToStr(GetCost());
|
||||||
|
|
||||||
|
// if (GetReturnAsSet())
|
||||||
|
// sql += wxT("\n ROWS ") + NumToStr(GetRows());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (!sql.Strip(wxString::both).EndsWith(wxT(";")))
|
||||||
|
// sql += wxT(";");
|
||||||
|
|
||||||
|
// size_t i;
|
||||||
|
// for (i = 0 ; i < configList.GetCount() ; i++)
|
||||||
|
// {
|
||||||
|
// if (configList.Item(i).BeforeFirst('=') != wxT("search_path") &&
|
||||||
|
// configList.Item(i).BeforeFirst('=') != wxT("temp_tablespaces"))
|
||||||
|
// sql += wxT("\nALTER FUNCTION ") + qtSig
|
||||||
|
// + wxT(" SET ") + configList.Item(i).BeforeFirst('=') + wxT("='") + configList.Item(i).AfterFirst('=') + wxT("';\n");
|
||||||
|
// else
|
||||||
|
// sql += wxT("\nALTER FUNCTION ") + qtSig
|
||||||
|
// + wxT(" SET ") + configList.Item(i).BeforeFirst('=') + wxT("=") + configList.Item(i).AfterFirst('=') + wxT(";\n");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// sql += wxT("\n")
|
||||||
|
// + GetOwnerSql(8, 0, wxT("FUNCTION ") + qtSig)
|
||||||
|
// + GetGrant(wxT("X"), wxT("FUNCTION ") + qtSig);
|
||||||
|
|
||||||
|
// if (!GetComment().IsNull())
|
||||||
|
// {
|
||||||
|
// sql += wxT("COMMENT ON FUNCTION ") + qtSig
|
||||||
|
// + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (GetConnection()->BackendMinimumVersion(9, 1))
|
||||||
|
// sql += GetSeqLabelsSql();
|
||||||
|
|
||||||
|
createSqlCache = std::move(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
return createSqlCache;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,24 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <libpq-fe.h>
|
#include <libpq-fe.h>
|
||||||
#include "Pgsql_Value.h"
|
#include "Pgsql_Value.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class Arg {
|
||||||
|
public:
|
||||||
|
enum Mode {
|
||||||
|
In, Out, InOut, Variadic, Table
|
||||||
|
};
|
||||||
|
|
||||||
|
Oid type;
|
||||||
|
Mode mode;
|
||||||
|
QString name;
|
||||||
|
QString def;
|
||||||
|
|
||||||
|
Arg(Oid t, Mode m, QString n, QString d)
|
||||||
|
: type(t), mode(m), name(n), def(d)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class PgProc: public PgSchemaObject {
|
class PgProc: public PgSchemaObject {
|
||||||
public:
|
public:
|
||||||
|
|
@ -28,18 +46,24 @@ public:
|
||||||
char provolatile = '\0'; // char
|
char provolatile = '\0'; // char
|
||||||
char parallel = '\0'; // char, version >= 9.6
|
char parallel = '\0'; // char, version >= 9.6
|
||||||
int16_t nargs = 0; // int2
|
int16_t nargs = 0; // int2
|
||||||
int16_t nargdefaults = 0; // int2
|
int16_t nargdefaults; // = 0; // int2
|
||||||
Oid rettype = InvalidOid; // oid
|
Oid rettype = InvalidOid; // oid
|
||||||
std::vector<Oid> argtypes; // oid[]
|
|
||||||
std::vector<Oid> allargtypes; // oid[]
|
|
||||||
std::vector<char> argmodes; // char[]
|
|
||||||
std::vector<QString> argnames; // text[]
|
|
||||||
std::optional<QString> argdefaults; // pg_node_tree
|
|
||||||
std::vector<Oid> trftypes; // oid[], version >= 9.5
|
std::vector<Oid> trftypes; // oid[], version >= 9.5
|
||||||
QString src; // text
|
QString src; // text
|
||||||
QString bin; // text
|
QString bin; // text
|
||||||
std::vector<QString> config; // text[]
|
std::vector<QString> config; // text[]
|
||||||
std::vector<QString> acl; // aclitem[]
|
QString acl; // aclitem[]
|
||||||
|
|
||||||
|
/// Converts the collection of arrays about the arguments to a single list of arguments
|
||||||
|
/// making it much easier to work with them correctly
|
||||||
|
void setArgs(
|
||||||
|
std::vector<Oid> argtypes,
|
||||||
|
std::vector<Oid> allargtypes,
|
||||||
|
std::vector<char> argmodes,
|
||||||
|
std::vector<QString> argnames,
|
||||||
|
std::optional<QString> argdefaults
|
||||||
|
);
|
||||||
|
const std::vector<Arg>& args() const;
|
||||||
|
|
||||||
bool operator==(Oid _oid) const { return oid == _oid; }
|
bool operator==(Oid _oid) const { return oid == _oid; }
|
||||||
bool operator==(const QString &n) const { return name == n; }
|
bool operator==(const QString &n) const { return name == n; }
|
||||||
|
|
@ -47,6 +71,19 @@ public:
|
||||||
bool operator<(const PgProc &rhs) const { return oid < rhs.oid; }
|
bool operator<(const PgProc &rhs) const { return oid < rhs.oid; }
|
||||||
|
|
||||||
virtual QString objectName() const override;
|
virtual QString objectName() const override;
|
||||||
|
|
||||||
|
QString createSql() const;
|
||||||
|
QString argListWithNames(bool multiline = false) const;
|
||||||
|
QString argSigList(const bool forScript = false) const;
|
||||||
|
|
||||||
|
// bool isTrigger() const
|
||||||
|
// {
|
||||||
|
// return typname == wxT("\"trigger\"") || typname == wxT("trigger") || typname == wxT("event_trigger") || typname == wxT("\"event_trigger\""))
|
||||||
|
// }
|
||||||
|
private:
|
||||||
|
mutable QString createSqlCache;
|
||||||
|
|
||||||
|
std::vector<Arg> m_args;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PGPROC_H
|
#endif // PGPROC_H
|
||||||
|
|
|
||||||
|
|
@ -28,17 +28,22 @@ PgProc PgProcContainer::loadElem(const Pgsql::Row &row)
|
||||||
Pgsql::Col col(row);
|
Pgsql::Col col(row);
|
||||||
PgProc v(m_catalog);
|
PgProc v(m_catalog);
|
||||||
Oid namespace_oid;
|
Oid namespace_oid;
|
||||||
|
std::vector<Oid> argtypes; // oid[]
|
||||||
|
std::vector<Oid> allargtypes; // oid[]
|
||||||
|
std::vector<char> argmodes; // char[]
|
||||||
|
std::vector<QString> argnames; // text[]
|
||||||
|
std::optional<QString> argdefaults; // pg_node_tree
|
||||||
|
|
||||||
col >> v.oid >> v.name >> namespace_oid >> v.owner >> v.lang >> v.cost >> v.rows
|
col >> v.oid >> v.name >> namespace_oid >> v.owner >> v.lang >> v.cost >> v.rows
|
||||||
>> v.variadic >> v.transform >> v.isagg >> v.iswindow >> v.secdef >> v.leakproof
|
>> v.variadic >> v.transform >> v.isagg >> v.iswindow >> v.secdef >> v.leakproof
|
||||||
>> v.isstrict >> v.retset >> v.provolatile >> v.nargs >> v.nargdefaults
|
>> v.isstrict >> v.retset >> v.provolatile >> v.nargs >> v.nargdefaults
|
||||||
>> v.rettype;
|
>> v.rettype;
|
||||||
col.getAsVector<Oid>(std::back_inserter(v.argtypes));
|
col.getAsVector<Oid>(std::back_inserter(argtypes));
|
||||||
col >> v.allargtypes >> v.argmodes >> v.argnames
|
col >> allargtypes >> argmodes >> argnames >> argdefaults
|
||||||
>> v.argdefaults;
|
>> v.src >> v.bin >> v.config >> v.acl;
|
||||||
col >> v.src;
|
|
||||||
col >> v.bin >> v.config >> v.acl;
|
|
||||||
|
|
||||||
v.setSchemaOid(namespace_oid);
|
v.setSchemaOid(namespace_oid);
|
||||||
|
v.setArgs(argtypes, allargtypes, argmodes, argnames, argdefaults);
|
||||||
|
|
||||||
if (minimumVersion(90500)) {
|
if (minimumVersion(90500)) {
|
||||||
col >> v.trftypes;
|
col >> v.trftypes;
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,8 @@ public:
|
||||||
PgType();
|
PgType();
|
||||||
|
|
||||||
Oid oid = InvalidOid;
|
Oid oid = InvalidOid;
|
||||||
QString name;//"name";"NO"
|
QString name; // formatted name as per database, arrays
|
||||||
|
QString typname; //"name";"NO"
|
||||||
Oid typnamespace = InvalidOid;//"oid";"NO"
|
Oid typnamespace = InvalidOid;//"oid";"NO"
|
||||||
Oid owner = InvalidOid;//"oid";"NO"
|
Oid owner = InvalidOid;//"oid";"NO"
|
||||||
short len = -1;//"smallint";"NO"
|
short len = -1;//"smallint";"NO"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "PgTypeContainer.h"
|
#include "PgTypeContainer.h"
|
||||||
#include "Pgsql_Connection.h"
|
#include "Pgsql_Connection.h"
|
||||||
|
#include "Pgsql_Col.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
//const PgType& PgTypeContainer::getTypeByOid(Oid oid) const
|
//const PgType& PgTypeContainer::getTypeByOid(Oid oid) const
|
||||||
|
|
@ -29,7 +30,7 @@
|
||||||
std::string PgTypeContainer::getLoadQuery() const
|
std::string PgTypeContainer::getLoadQuery() const
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
"SELECT oid, typname, typnamespace, typowner, typlen, typbyval, typtype, typcategory, \n"
|
"SELECT oid, format_type(oid, NULL) AS name, typname, typnamespace, typowner, typlen, typbyval, typtype, typcategory, \n"
|
||||||
" typispreferred, typisdefined, typdelim, typrelid, typelem, typarray, typinput, typoutput, \n"
|
" typispreferred, typisdefined, typdelim, typrelid, typelem, typarray, typinput, typoutput, \n"
|
||||||
" typreceive, typsend, typmodin, typmodout, typanalyze, typalign, typstorage, typnotnull, \n"
|
" typreceive, typsend, typmodin, typmodout, typanalyze, typalign, typstorage, typnotnull, \n"
|
||||||
" typbasetype, typtypmod, typndims, typcollation, typdefaultbin, typdefault, typacl \n"
|
" typbasetype, typtypmod, typndims, typcollation, typdefaultbin, typdefault, typacl \n"
|
||||||
|
|
@ -38,37 +39,11 @@ std::string PgTypeContainer::getLoadQuery() const
|
||||||
|
|
||||||
PgType PgTypeContainer::loadElem(const Pgsql::Row &row)
|
PgType PgTypeContainer::loadElem(const Pgsql::Row &row)
|
||||||
{
|
{
|
||||||
|
Pgsql::Col col(row);
|
||||||
PgType v;
|
PgType v;
|
||||||
v.oid << row.get(0); // InvalidOid;
|
col >> v.oid >> v.name >> v.typname >> v.typnamespace >> v.owner >> v.len >> v.byval >> v.type >> v.category
|
||||||
v.name << row.get(1); //. operator QString(); // "name";"NO"
|
>> v.ispreferred >> v.isdefined >> v.delim >> v.relid >> v.elem >> v.array >> v.input >> v.output
|
||||||
v.typnamespace << row.get(2); // InvalidOid;//"oid";"NO"
|
>> v.receive >> v.send >> v.modin >> v.modout >> v.analyze >> v.align >> v.storage >> v.notnull
|
||||||
v.owner << row.get(3); // InvalidOid;//"oid";"NO"
|
>> v.basetype >> v.typmod >> v.ndims >> v.collation >> v.defaultbin >> v.typdefault >> v.acl;
|
||||||
v.len << row.get(4); // -1;//"smallint";"NO"
|
|
||||||
v.byval << row.get(5); // false;//"boolean";"NO"
|
|
||||||
v.type << row.get(6);//""char"";"NO"
|
|
||||||
v.category << row.get(7);//""char"";"NO"
|
|
||||||
v.ispreferred << row.get(8); //false;//"boolean";"NO"
|
|
||||||
v.isdefined << row.get(9); //false;//"boolean";"NO"
|
|
||||||
v.delim << row.get(10); //""char"";"NO"
|
|
||||||
v.relid << row.get(11); // InvalidOid;//"oid";"NO"
|
|
||||||
v.elem << row.get(12); // InvalidOid;//"oid";"NO"
|
|
||||||
v.array << row.get(13); // InvalidOid;//"oid";"NO"
|
|
||||||
v.input << row.get(14);//regproc";"NO"
|
|
||||||
v.output << row.get(15);//"regproc";"NO"
|
|
||||||
v.receive << row.get(16);//"regproc";"NO"
|
|
||||||
v.send << row.get(17);//"regproc";"NO"
|
|
||||||
v.modin << row.get(18);//"regproc";"NO"
|
|
||||||
v.modout << row.get(19);//"regproc";"NO"
|
|
||||||
v.analyze << row.get(20);//"regproc";"NO"
|
|
||||||
v.align << row.get(21); // //""char"";"NO"
|
|
||||||
v.storage << row.get(22); //""char"";"NO"
|
|
||||||
v.notnull << row.get(23); //"boolean";"NO"
|
|
||||||
v.basetype << row.get(24); //"oid";"NO"
|
|
||||||
v.typmod << row.get(25); //-1;//"integer";"NO"
|
|
||||||
v.ndims << row.get(26); //"integer";"NO"
|
|
||||||
v.collation << row.get(27); //InvalidOid;//"oid";"NO"
|
|
||||||
v.defaultbin << row.get(28);//"pg_node_tree";"YES"
|
|
||||||
v.typdefault << row.get(29);//"text";"YES"
|
|
||||||
v.acl << row.get(30);//"ARRAY";"YES"
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -227,6 +227,23 @@ QString quoteIdent(QString ident)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString dollarQuoteString(const QString &value)
|
||||||
|
{
|
||||||
|
QString def_tag = "BODY";
|
||||||
|
QString tag = QString("$%1$").arg(def_tag);
|
||||||
|
|
||||||
|
int counter = 1;
|
||||||
|
while (value.indexOf(tag) >= 0)
|
||||||
|
tag = QString("$%1%2$").arg(def_tag, counter++);
|
||||||
|
|
||||||
|
|
||||||
|
return tag
|
||||||
|
+ value
|
||||||
|
+ tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QString genSchemaPrefix(const PgNamespace &ns)
|
QString genSchemaPrefix(const PgNamespace &ns)
|
||||||
{
|
{
|
||||||
QString str;
|
QString str;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,10 @@ QString escapeLiteral(const QString &input);
|
||||||
|
|
||||||
bool identNeedsQuotes(QString ident);
|
bool identNeedsQuotes(QString ident);
|
||||||
QString quoteIdent(QString ident);
|
QString quoteIdent(QString ident);
|
||||||
|
/// Puts a string in dollar quote for passing in a query
|
||||||
|
/// the standard quotes are $BODY$ if the tag already exists in the string it will start numbering
|
||||||
|
QString dollarQuoteString(const QString &value);
|
||||||
|
|
||||||
|
|
||||||
QString genFQTableName(const PgDatabaseCatalog &catalog, const PgClass &cls);
|
QString genFQTableName(const PgDatabaseCatalog &catalog, const PgClass &cls);
|
||||||
QString getDropConstraintDefinition(const PgDatabaseCatalog &catalog, const PgConstraint &constraint);
|
QString getDropConstraintDefinition(const PgDatabaseCatalog &catalog, const PgConstraint &constraint);
|
||||||
|
|
|
||||||
|
|
@ -155,3 +155,16 @@ else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pgsq
|
||||||
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pgsql/release/pgsql.lib
|
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pgsql/release/pgsql.lib
|
||||||
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pgsql/debug/pgsql.lib
|
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pgsql/debug/pgsql.lib
|
||||||
else:unix:!macx: PRE_TARGETDEPS += $$OUT_PWD/../pgsql/libpgsql.a
|
else:unix:!macx: PRE_TARGETDEPS += $$OUT_PWD/../pgsql/libpgsql.a
|
||||||
|
|
||||||
|
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../core/release/ -lcore
|
||||||
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../core/debug/ -lcore
|
||||||
|
else:unix: LIBS += -L$$OUT_PWD/../core/ -lcore
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/../core
|
||||||
|
DEPENDPATH += $$PWD/../core
|
||||||
|
|
||||||
|
win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/release/libcore.a
|
||||||
|
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/debug/libcore.a
|
||||||
|
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/release/core.lib
|
||||||
|
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/debug/core.lib
|
||||||
|
else:unix: PRE_TARGETDEPS += $$OUT_PWD/../core/libcore.a
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue