Builds on windows again

This commit is contained in:
eelke 2017-11-26 13:07:21 +01:00
parent 33cf39b799
commit bebb3391c3
160 changed files with 138 additions and 117 deletions

206
pgsql/Pgsql_Connection.cpp Normal file
View file

@ -0,0 +1,206 @@
#include "Pgsql_Connection.h"
#include "Pgsql_declare.h"
#include "Pgsql_Params.h"
#include <stdexcept>
using namespace Pgsql;
Canceller::Canceller(PGcancel *c)
: m_cancel(c)
{}
Canceller::Canceller(Canceller&& rhs)
: m_cancel(rhs.m_cancel)
{
rhs.m_cancel = nullptr;
}
Canceller& Canceller::operator=(Canceller&& rhs)
{
if (m_cancel) {
PQfreeCancel(m_cancel);
}
m_cancel = rhs.m_cancel;
rhs.m_cancel = nullptr;
return *this;
}
Canceller::~Canceller()
{
if (m_cancel) {
PQfreeCancel(m_cancel);
}
}
bool Canceller::cancel(std::string *error)
{
const int errbuf_size = 256;
char errbuf[errbuf_size];
bool res = PQcancel(m_cancel, errbuf, errbuf_size);
if (!res && error) {
*error = errbuf;
}
return res;
}
Connection::Connection() = default;
Connection::~Connection()
{
close();
}
Connection::Connection(Connection &&rhs)
: conn(rhs.conn)
{
rhs.conn = nullptr;
}
Connection& Connection::operator=(Connection &&rhs)
{
close();
conn = rhs.conn;
rhs.conn = nullptr;
return *this;
}
void Connection::close()
{
if (conn) {
PQfinish(conn);
conn = nullptr;
}
}
Canceller Connection::getCancel()
{
Canceller c(PQgetCancel(conn));
return c;
}
bool Connection::connect(const char *params)
{
bool result = false;
conn = PQconnectdb(params);
if (conn) {
ConnStatusType status = PQstatus(conn);
result = (status == CONNECTION_OK);
}
return result;
}
bool Connection::connect(const char *const * keywords, const char* const * values, int expand_dbname)
{
bool result = false;
conn = PQconnectdbParams(keywords, values, expand_dbname);
if (conn) {
ConnStatusType status = PQstatus(conn);
result = (status == CONNECTION_OK);
}
return result;
}
bool Connection::connectStart(const char* params)
{
conn = PQconnectStart(params);
return conn != nullptr;
}
bool Connection::connectStart(const char * const *keywords,
const char * const *values)
{
conn = PQconnectStartParams(keywords, values, 0);
return conn != nullptr;
}
PostgresPollingStatusType Connection::connectPoll()
{
return PQconnectPoll(conn);
}
ConnStatusType Connection::status()
{
return PQstatus(conn);
}
int Connection::socket()
{
return PQsocket(conn);
}
std::string Connection::getErrorMessage() const
{
std::string result;
if (conn) {
result = PQerrorMessage(conn);
}
else {
result = "no connection";
}
return result;
}
Result Connection::query(const char * command)
{
PGresult *result = PQexec(conn, command);
return Result(result);
}
bool Connection::sendQuery(const char *query)
{
int res = PQsendQuery(conn, query);
return res == 1;
}
bool Connection::sendQueryParams(const char * command, const Params &params)
{
int res = PQsendQueryParams(conn, command, params.size(), params.types(),
params.values(), params.lengths(), params.formats(),
0); // text format
return res == 1;
}
std::shared_ptr<Result> Connection::getResult()
{
PGresult *r = PQgetResult(conn);
if (r) {
return std::make_shared<Result>(r);
}
else {
return nullptr;
}
}
bool Connection::consumeInput()
{
int res = PQconsumeInput(conn);
return res == 1;
}
bool Connection::isBusy()
{
int res = PQisBusy(conn);
return res == 1;
}
void Connection::setNoticeReceiver(std::function<void(const PGresult *)> callback)
{
notifyReceiver = callback;
PQsetNoticeReceiver(conn,
Connection::notifyReceiveFunc
, reinterpret_cast<void*>(this));
}
void Connection::notifyReceiveFunc(void *arg, const PGresult *result)
{
Connection *c = reinterpret_cast<Connection *>(arg);
c->notifyReceiver(result);
}

217
pgsql/Pgsql_Connection.h Normal file
View file

@ -0,0 +1,217 @@
#pragma once
#include <functional>
#include <string>
#include <libpq-fe.h>
#include <cassert>
#include <QString>
#include <vector>
#include <codecvt>
#include <memory>
#include <fmt/format.h>
#include "Pgsql_Result.h"
namespace Pgsql {
class Connection;
/*
This library has multiple layers.
Layer 1 delivers lowlevel C++ wrappers for the basic libpq functionality. Adding
automatic resource management.
*/
// class ConnectionParams {
// public:
// std::string host;
// std::string hostaddr;
// unsigned short port = 5432;
// std::string dbname;
// std::string user;
// std::string password;
// int connect_timeout = -1; ///< -1 omit (ie uses default)
// std::string application_name;
// };
class Result;
class Params;
/** \brief Wrapper for a cancel object from libpq.
*/
class Canceller {
public:
Canceller() = default;
Canceller(PGcancel *c);
Canceller(const Canceller&) = delete;
Canceller& operator=(const Canceller&) = delete;
Canceller(Canceller&& rhs);
Canceller& operator=(Canceller&& rhs);
~Canceller();
bool cancel(std::string *error);
private:
PGcancel *m_cancel = nullptr;
};
/** \brief Class for connecting to the database.
*
* The class isolates the programmer from the worst C style parts
* of the libpq API but is mostly a very thin wrapper.
*/
class Connection {
public:
Connection();
~Connection();
Connection(const Connection &rhs) = delete;
Connection& operator=(const Connection &rhs) = delete;
Connection(Connection &&rhs);
Connection& operator=(Connection &&rhs);
// void connect(const ConnectionParams &params);
bool connect(const char *params);
bool connect(const QString &params)
{
return connect(params.toUtf8().data());
}
bool connect(const char *const * keywords, const char* const * values, int expand_dbname);
bool connectStart(const char *params);
bool connectStart(const std::string &params)
{
return connectStart(params.c_str());
}
bool connectStart(const QString &params)
{
return connectStart(params.toUtf8().data());
}
bool connectStart(const char * const *keywords,
const char * const *values);
PostgresPollingStatusType connectPoll();
ConnStatusType status();
int socket();
void close();
Canceller getCancel();
std::string getErrorMessage() const;
Result query(const char * command);
Result query(const QString &command)
{
return query(command.toUtf8().data());
}
bool sendQuery(const char * query);
bool sendQuery(const std::string &command)
{
return sendQuery(command.c_str());
}
bool sendQuery(const QString &command)
{
return sendQuery(command.toUtf8().data());
}
bool sendQueryParams(const char * command, const Params &params);
std::shared_ptr<Result> getResult();
bool consumeInput();
bool isBusy();
void setNoticeReceiver(std::function<void(const PGresult *)> callback);
private:
PGconn *conn = nullptr;
std::function<void(const PGresult *)> notifyReceiver;
static void notifyReceiveFunc(void *arg, const PGresult *result);
};
// class Field {
// public:
// std::string getName() const;
// private:
// //Tuples tuples;
// int field;
// //
// };
// class Tuples {
// public:
// int getRowCount() const;
// int getColCount() const;
// Field getField(const std::string &fname);
// Field getField(const int idx);
// class const_iterator {
// public:
// const_iterator& operator++();
// };
// void rewind();
// };
// class OkResult: public Result {
// public:
// /** If the result is a data result then returns an interface for processing this data.
// The returned interface remains valid as long as this OkResult exists.
// */
// Tuples* hasTuples();
// };
// class ErrorResult: public Result {
//
// };
// class ITransaction {
// public:
//
// Canceller Query(std::string query,
// std::function<void(OkResult)> on_success,
// std::function<void()> on_cancelled,
// std::function<void(ErrorResult)> on_error);
//
// Canceller Query(std::string query,
// std::function<void(OkResult)> on_success,
// std::function<void()> on_cancelled,
// std::function<void(ErrorResult)> on_error);
//
//
// void Rollback(
// std::function<void(OkResult)> on_success,
// std::function<void(ErrorResult)> on_error);
// void Commit(
// std::function<void(OkResult)> on_success,
// std::function<void()> on_cancelled,
// std::function<void(ErrorResult)> on_error);
//
// };
}

97
pgsql/Pgsql_Params.cpp Normal file
View file

@ -0,0 +1,97 @@
#include "Pgsql_Params.h"
#include <cstring>
using namespace Pgsql;
Params::Params()
{}
Params::Params(const Params& rhs)
: m_paramTypes(rhs.m_paramTypes)
, m_paramLengths(rhs.m_paramLengths)
, m_paramFormats(rhs.m_paramFormats)
{
//std::vector<const char *> m_paramValues;
copyValues(rhs.m_paramValues);
}
Params& Params::operator=(const Params& rhs)
{
if (&rhs != this) {
m_paramTypes = rhs.m_paramTypes;
m_paramLengths = rhs.m_paramLengths;
m_paramFormats = rhs.m_paramFormats;
copyValues(rhs.m_paramValues);
}
return *this;
}
Params::Params(Params&& rhs)
: m_paramTypes(std::move(rhs.m_paramTypes))
, m_paramValues(std::move(rhs.m_paramValues))
, m_paramLengths(std::move(rhs.m_paramLengths))
, m_paramFormats(std::move(rhs.m_paramFormats))
{}
Params& Params::operator=(Params&& rhs)
{
if (&rhs != this) {
m_paramTypes = std::move(rhs.m_paramTypes);
m_paramValues = std::move(rhs.m_paramValues);
m_paramLengths = std::move(rhs.m_paramLengths);
m_paramFormats = std::move(rhs.m_paramFormats);
}
return *this;
}
Params::~Params()
{
deleteValues();
}
void Params::addText(const char *data, Oid oid)
{
m_paramTypes.push_back(oid);
m_paramValues.push_back(data);
m_paramLengths.push_back(data ? strlen(data) + 1 : 0);
m_paramFormats.push_back(0);
}
void Params::add(const QString &s, Oid oid)
{
auto ba = s.toUtf8();
const int len = ba.size();
char * p = new char[len+1];
std::memcpy(p, ba.data(), len);
p[len] = 0;
addText(p, oid);
}
void Params::addBinary(const char *data, int length, Oid oid)
{
m_paramTypes.push_back(oid);
m_paramValues.push_back(data);
m_paramLengths.push_back(length);
m_paramFormats.push_back(1);
}
void Params::clear()
{
m_paramTypes.clear();
deleteValues();
m_paramValues.clear();
m_paramLengths.clear();
m_paramFormats.clear();
}
void Params::copyValues(const t_paramValues &r)
{
const int n = m_paramTypes.size();
m_paramValues.reserve(n);
for (int i = 0; i < n; ++i) {
const int len = m_paramLengths[i];
char * p = new char[len];
std::memcpy(p, r[i], len);
m_paramValues.push_back(p);
}
}

58
pgsql/Pgsql_Params.h Normal file
View file

@ -0,0 +1,58 @@
#ifndef PGSQL_PARAMS_H
#define PGSQL_PARAMS_H
#include <vector>
#include <QString>
#include <libpq-fe.h>
#include "Pgsql_declare.h"
namespace Pgsql {
class Params {
public:
Params();
Params(const Params& rhs);
Params& operator=(const Params& rhs);
Params(Params&& rhs);
Params& operator=(Params&& rhs);
~Params();
/** \brief Add a parameter to the list.
*
* The class takes ownership of data and will try to delete[] it.
*/
void addText(const char *data, Oid oid=oid_varchar);
void add(const QString &s, Oid oid=oid_varchar);
void addBinary(const char *data, int length, Oid oid);
void clear();
bool empty() const { return m_paramTypes.empty(); }
int size() const { return m_paramTypes.size(); }
const Oid* types() const { return m_paramTypes.data(); }
const char* const* values() const { return m_paramValues.data(); }
const int* lengths() const { return m_paramLengths.data(); }
const int* formats() const { return m_paramFormats.data(); }
private:
using t_paramValues = std::vector<const char *>;
void deleteValues()
{
for (auto e : m_paramValues)
delete[] e;
}
/* Assumes other lists already have been copied */
void copyValues(const t_paramValues &r);
std::vector<Oid> m_paramTypes;
t_paramValues m_paramValues;
std::vector<int> m_paramLengths; ///< postgresql ignores lengths for text parameters but we will it anyway for efficient copying
std::vector<int> m_paramFormats;
};
} // end namespace Pgsql
#endif // PGSQL_PARAMS_H

182
pgsql/Pgsql_Result.cpp Normal file
View file

@ -0,0 +1,182 @@
#include "Pgsql_Result.h"
using namespace Pgsql;
namespace {
void set_stdstring_with_charptr(std::string &s, const char *p)
{
if (p) {
s = p;
}
else {
s.clear();
}
}
} // einde unnamed namespace
ErrorDetails ErrorDetails::createErrorDetailsFromPGresult(const PGresult *result)
{
ErrorDetails r;
set_stdstring_with_charptr(r.errorMessage, PQresultErrorMessage(result));
set_stdstring_with_charptr(r.state, PQresultErrorField(result, PG_DIAG_SQLSTATE)); ///< PG_DIAG_SQLSTATE Error code as listed in https://www.postgresql.org/docs/9.5/static/errcodes-appendix.html
set_stdstring_with_charptr(r.severity, PQresultErrorField(result, PG_DIAG_SEVERITY));
set_stdstring_with_charptr(r.messagePrimary, PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY));
set_stdstring_with_charptr(r.messageDetail, PQresultErrorField(result, PG_DIAG_MESSAGE_DETAIL));
set_stdstring_with_charptr(r.messageHint, PQresultErrorField(result, PG_DIAG_MESSAGE_HINT));
const char * p = PQresultErrorField(result, PG_DIAG_STATEMENT_POSITION);
r.statementPosition = p != nullptr ? atoi(p) : -1; ///< First character is one, measured in characters not bytes!
p = PQresultErrorField(result, PG_DIAG_INTERNAL_POSITION);
r.internalPosition = p != nullptr ? atoi(p) : -1;
set_stdstring_with_charptr(r.internalQuery, PQresultErrorField(result, PG_DIAG_INTERNAL_QUERY));
set_stdstring_with_charptr(r.context, PQresultErrorField(result, PG_DIAG_CONTEXT));
set_stdstring_with_charptr(r.schemaName, PQresultErrorField(result, PG_DIAG_SCHEMA_NAME));
set_stdstring_with_charptr(r.tableName, PQresultErrorField(result, PG_DIAG_TABLE_NAME));
set_stdstring_with_charptr(r.columnName, PQresultErrorField(result, PG_DIAG_COLUMN_NAME));
set_stdstring_with_charptr(r.datatypeName, PQresultErrorField(result, PG_DIAG_DATATYPE_NAME));
set_stdstring_with_charptr(r.constraintName, PQresultErrorField(result, PG_DIAG_CONSTRAINT_NAME));
set_stdstring_with_charptr(r.sourceFile, PQresultErrorField(result, PG_DIAG_SOURCE_FILE));
set_stdstring_with_charptr(r.sourceLine, PQresultErrorField(result, PG_DIAG_SOURCE_LINE));
set_stdstring_with_charptr(r.sourceFunction, PQresultErrorField(result, PG_DIAG_SOURCE_FUNCTION));
return r;
}
Result::Result(PGresult *res)
: result(res)
{
if (res == nullptr) {
throw std::runtime_error("Passing nullptr to Result::Result is not allowed");
}
}
Result::~Result()
{
PQclear(result);
}
Result::Result(Result &&rhs)
: result(rhs.result)
{
rhs.result = nullptr;
}
Result& Result::operator=(Result &&rhs)
{
if (result) {
PQclear(result);
}
result = rhs.result;
rhs.result = nullptr;
return *this;
}
Result::operator bool() const
{
return result != nullptr;
}
ExecStatusType Result::resultStatus()
{
return PQresultStatus(result);
}
std::string Result::getResStatus()
{
// return PQresStatus(result);
return "";
}
std::string Result::diagSqlState()
{
std::string s(PQresultErrorField(result, PG_DIAG_SQLSTATE));
return s;
}
ErrorDetails Result::diagDetails()
{
// ErrorDetails r;
// r.state = PQresultErrorField(result, PG_DIAG_SQLSTATE); ///< PG_DIAG_SQLSTATE Error code as listed in https://www.postgresql.org/docs/9.5/static/errcodes-appendix.html
// r.severity = PQresultErrorField(result, PG_DIAG_SEVERITY);
// r.messagePrimary = PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY);
// r.messageDetail = PQresultErrorField(result, PG_DIAG_MESSAGE_DETAIL);
// r.messageHint = PQresultErrorField(result, PG_DIAG_MESSAGE_HINT);
// r.statementPosition = atoi(PQresultErrorField(result, PG_DIAG_STATEMENT_POSITION)); ///< First character is one, measured in characters not bytes!
// r.internalPosition = atoi(PQresultErrorField(result, PG_DIAG_INTERNAL_POSITION));
// r.internalQuery = PQresultErrorField(result, PG_DIAG_INTERNAL_QUERY);
// r.context = PQresultErrorField(result, PG_DIAG_CONTEXT);
// r.schemaName = PQresultErrorField(result, PG_DIAG_SCHEMA_NAME);
// r.tableName = PQresultErrorField(result, PG_DIAG_TABLE_NAME);
// r.columnName = PQresultErrorField(result, PG_DIAG_COLUMN_NAME);
// r.datatypeName = PQresultErrorField(result, PG_DIAG_DATATYPE_NAME);
// r.constraintName = PQresultErrorField(result, PG_DIAG_CONSTRAINT_NAME);
// r.sourceFile = PQresultErrorField(result, PG_DIAG_SOURCE_FILE);
// r.sourceLine = PQresultErrorField(result, PG_DIAG_SOURCE_LINE);
// r.sourceFunction = PQresultErrorField(result, PG_DIAG_SOURCE_FUNCTION);
// return r;
return ErrorDetails::createErrorDetailsFromPGresult(result);
}
int Result::tuplesAffected() const
{
int i;
char * res = PQcmdTuples(result);
if (res && res[0] != '\0') {
try {
i = std::stoi(res);
}
catch (std::invalid_argument& ) {
i = -1;
}
catch (std::out_of_range& ) {
i = -1;
}
}
else {
i = -1;
}
return i;
}
int Result::rows() const
{
return PQntuples(result);
}
int Result::cols() const
{
return PQnfields(result);
}
const char * Result::getColName(int idx) const
{
return PQfname(result, idx);
}
const char * Result::val(int col, int row) const
{
return PQgetvalue(result, row, col);
}
Value Result::get(int col, int row) const
{
return Value(
PQgetvalue(result, row, col),
PQftype(result, col)
);
}
Oid Result::type(int col) const
{
return PQftype(result, col);
}
bool Result::null(int col, int row) const
{
return PQgetisnull(result, row, col);
}

136
pgsql/Pgsql_Result.h Normal file
View file

@ -0,0 +1,136 @@
#ifndef PGSQL_RESULT_H
#define PGSQL_RESULT_H
#include "Pgsql_Row.h"
namespace Pgsql {
class ErrorDetails {
public:
static ErrorDetails createErrorDetailsFromPGresult(const PGresult *res);
std::string errorMessage;
std::string state; ///< PG_DIAG_SQLSTATE Error code as listed in https://www.postgresql.org/docs/9.5/static/errcodes-appendix.html
std::string severity;
std::string messagePrimary;
std::string messageDetail;
std::string messageHint;
int statementPosition; ///< First character is one, measured in characters not bytes!
int internalPosition;
std::string internalQuery;
std::string context;
std::string schemaName;
std::string tableName;
std::string columnName;
std::string datatypeName;
std::string constraintName;
std::string sourceFile;
std::string sourceLine;
std::string sourceFunction;
};
/** \brief Non-copyable but movable wrapper for a postgresql result.
*
* This class makes sure the result is removed from memory. It also supplies an iterator for the
* rows from the result facilitating also the use of the cpp for each.
*/
class Result {
public:
class const_iterator {
public:
const_iterator(const Result &r, int rw)
: m_row(r, rw)
{}
const_iterator operator++()
{
const_iterator t(*this);
m_row.next();
return t;
}
const_iterator& operator++(int)
{
m_row.next();
return *this;
}
bool operator==(const const_iterator &rhs)
{
return m_row == rhs.m_row;
}
bool operator!=(const const_iterator &rhs)
{
return !operator==(rhs);
}
const Row& operator*()
{
return m_row;
}
const Row& operator->()
{
return m_row;
}
private:
Row m_row;
};
Result() = default;
Result(PGresult *result);
~Result();
Result(const Result &rhs) = delete;
Result& operator=(const Result &rhs) = delete;
Result(Result &&rhs);
Result& operator=(Result &&rhs);
operator bool() const;
ExecStatusType resultStatus();
std::string getResStatus();
/** Use this to retrieve an error code when this is an error result
*
* The possible code are listed in https://www.postgresql.org/docs/9.5/static/errcodes-appendix.html
*/
std::string diagSqlState();
/** Retrieves all the error fields. */
ErrorDetails diagDetails();
const_iterator begin() const
{
return const_iterator(*this, 0);
}
const_iterator end() const
{
return const_iterator(*this, rows());
}
int tuplesAffected() const;
int rows() const;
int cols() const;
const char* getColName(int idx) const;
const char* val(int col, int row) const;
Value get(int col, int row) const;
Oid type(int col) const;
bool null(int col, int row) const;
// iterator begin();
private:
PGresult *result = nullptr;
};
} // end namespace Pgsql
#endif // PGSQL_RESULT_H

36
pgsql/Pgsql_Row.cpp Normal file
View file

@ -0,0 +1,36 @@
#include "Pgsql_Row.h"
#include "Pgsql_Result.h"
using namespace Pgsql;
Row::Row(const Result &result, int row)
: m_result(result)
, m_row(row)
{}
bool Row::next()
{
if (m_row < m_result.rows()) {
++m_row;
return true;
}
return false;
}
bool Row::operator==(const Row& rhs) const
{
return &m_result == &rhs.m_result
&& m_row == rhs.m_row;
}
Value Row::get(int col) const
{
return m_result.get(col, m_row);
}
//Value Row::get(const char *colname) const
//{
//}

31
pgsql/Pgsql_Row.h Normal file
View file

@ -0,0 +1,31 @@
#ifndef PGSQL_ROW_H
#define PGSQL_ROW_H
#include "Pgsql_Value.h"
namespace Pgsql {
class Result;
/** \brief A reference to a specific row from a result.
*
* As it is a reference its contents won't be valid after its associated result has
* been destroyed.
*/
class Row {
public:
Row(const Result &result, int row);
bool next();
bool operator==(const Row& rhs) const;
Value get(int col) const;
//Value get(const char *colname) const;
//bool get(int col, QString &s);
private:
const Result& m_result;
int m_row;
};
} // end namespace Pgsql
#endif // PGSQL_ROW_H

98
pgsql/Pgsql_Value.cpp Normal file
View file

@ -0,0 +1,98 @@
#include "Pgsql_Value.h"
#include <cstdlib>
#include <cstring>
using namespace Pgsql;
Value::Value(const char *val, Oid typ)
: m_val(val), m_typ(typ)
{}
QString Value::asQString() const
{
return QString::fromUtf8(m_val);
}
Value::operator QString() const
{
return QString::fromUtf8(m_val);
}
Value::operator QDateTime() const
{
return QDateTime::fromString(asQString(),
"yyyy-MM-dd hh:mm:ss");
}
Value::operator std::string() const
{
return m_val;
}
Value::operator short() const
{
return (short)std::atoi(m_val);
}
Value::operator int() const
{
return std::atoi(m_val);
}
Value::operator Oid() const
{
return operator int();
}
Value::operator long long() const
{
return std::strtoull(m_val, nullptr, 10);
}
Value::operator bool() const
{
return std::strcmp(m_val, "t") == 0;
}
//void operator<<(QString &s, const Value &v)
//{
// s = v.asQString();
//}
//void operator<<(QDateTime &l, const Value &v)
//{
// l = QDateTime::fromString(asQString(),
// "yyyy-MM-dd hh:mm:ss");
//}
//void operator<<(std::string &l, const Value &v)
//{
// l = v;
//}
//void operator<<(short &l, const Value &v)
//{
// l = (short)std::atoi(v.c_str());
//}
//void operator<<(int &l, const Value &v)
//{
// l = std::atoi(v.c_str());
//}
//void Pgsql::operator<<(Oid &l, const Value &v)
//{
// l = std::atoi(v.c_str());
//}
//void operator<<(__int64 &l, const Value &v)
//{
// l = std::strtoull(v.c_str(), nullptr, 10);
//}
//void operator<<(bool &l, const Value &v)
//{
// l = std::strcmp(v.c_str(), "t") == 0;
//}

48
pgsql/Pgsql_Value.h Normal file
View file

@ -0,0 +1,48 @@
#ifndef PGSQL_VALUE_H
#define PGSQL_VALUE_H
#include "Pgsql_declare.h"
#include <QString>
#include <QDateTime>
namespace Pgsql {
/** \brief Class that is returned as value of a cell to facilitate auto conversion.
*/
class Value {
public:
Value(const char *val, Oid typ);
QString asQString() const;
const char* c_str() const { return m_val; }
operator QString() const;
operator QDateTime() const;
operator std::string() const;
operator short() const;
operator int() const;
operator Oid() const;
operator long long() const;
operator bool() const;
private:
const char *m_val;
Oid m_typ;
};
// void operator<<(QString &s, const Value &v);
// void operator<<(QDateTime &l, const Value &v);
// void operator<<(std::string &l, const Value &v);
// void operator<<(short &l, const Value &v);
// void operator<<(int &l, const Value &v);
// void operator<<(Oid &l, const Value &v);
// void operator<<(__int64 &l, const Value &v);
// void operator<<(bool &l, const Value &v);
template <typename T>
void operator<<(T &s, const Value &v)
{
s = static_cast<T>(v);
}
} // end namespace Pgsql
#endif // PGSQL_VALUE_H

27
pgsql/Pgsql_declare.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef PGSQL_DECLARE_H
#define PGSQL_DECLARE_H
#include <libpq-fe.h>
namespace Pgsql {
const Oid oid_bool = 16;
const Oid oid_int2 = 21;
const Oid oid_int4 = 23;
const Oid oid_int8 = 20;
const Oid oid_float4 = 700;
const Oid oid_float8 = 701;
const Oid oid_numeric = 1700;
const Oid oid_oid = 26;
const Oid oid_varchar = 1043;
class Params;
class Connection;
class Result;
class Value;
class Row;
} // END namespace Pgsql
#endif // PGSQL_DECLARE_H

59
pgsql/pgsql.pro Normal file
View file

@ -0,0 +1,59 @@
#-------------------------------------------------
#
# Project created by QtCreator 2016-11-11T09:17:13
#
#-------------------------------------------------
CONFIG += staticlib c++14
QT += core
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets sql
TARGET = pgsql
TEMPLATE = lib
INCLUDEPATH += C:\prog\include C:\Prog\include\pgsql C:\VSproj\boost32\include\boost-1_65_1
DEFINES += WIN32_LEAN_AND_MEAN NOMINMAX
#LIBS += -LC:/prog/boost/lib -Lc:/prog/lib libpq.lib fmt.lib User32.lib ws2_32.lib
LIBS += -LC:/PROG/LIB -lws2_32 -llibpq
debug {
#LIBS += c:/prog/lib/botand_imp.lib
}
release {
# LIBS += c:\prog\lib\botan.lib
}
#win32:RC_ICONS += pglab.ico
SOURCES += Pgsql_Connection.cpp \
Pgsql_Params.cpp \
Pgsql_Result.cpp \
Pgsql_Row.cpp \
Pgsql_Value.cpp
HEADERS += Pgsql_Connection.h \
Pgsql_Params.h \
Pgsql_Result.h \
Pgsql_Row.h \
Pgsql_Value.h \
Pgsql_declare.h
#FORMS +=
#RESOURCES += \
# resources.qrc
#QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS,5.01
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
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