class DBConnection
{
public:
class TParams
{
public:
TParams(int size);
virtual ~TParams();
private:
TParams(const TParams& params) {}
TParams& operator = (const TParams& params) { return *this; }
public:
void Add(const char* val, int size);
void Add(int val);
void Add(unsigned int val);
void Add(uint64_t val);
void Add(short val);
void Free();
int Size() const { return _size; }
const char * const * Value() const { return value; }
const int* Length() const { return length; }
const int* Format() const { return format; }
public:
char** value;
int* length;
int* format;
private:
int _size;
int _pos;
};
public:
DBConnection()
: conn(NULL)
{
}
virtual ~DBConnection();
public:
int Connect(const char* info);
void Disconnect();
int ExecCmd(const char* cmd);
PGresult* ExecQuery(const char* sql);
int ExecCmdWithParams(const char* cmd, const TParams& params);
PGresult* ExecQueryWithParams(const char* sql, const TParams& params);
int BeginTranscation();
int EndTranscation();
private:
PGconn* conn;
};
DBConnection::TParams::TParams(int size)
: _size(size), _pos(0)
{
value = new char*[_size];
length = new int[_size];
format = new int[_size];
}
DBConnection::TParams::~TParams()
{
Free();
}
void DBConnection::TParams::Free()
{
if (_size == 0)
{
return;
}
for (int i = 0; i < _size; ++ i)
{
if (format[i] == 0)
{
delete[] value[i];
}
else if (length[i] == sizeof(int) || length[i] == sizeof(unsigned int))
{
delete (int*)value[i];
}
else if (length[i] == sizeof(uint64_t))
{
delete (uint64_t*)value[i];
}
else
{
delete (short*)value[i];
}
}
delete[] value, value = NULL;
delete[] length, length = NULL;
delete[] format, format = NULL;
_size = 0;
DEBUG(DEBUG_ANY, "<DBConnection::TParams::Free()>"<< std::endl);
}
void DBConnection::TParams::Add(const char* val, int size)
{
char* char_val = new char[size + 1];
char_val[size] = '\0';
// char* char_val = new char[size];
memcpy(char_val, val, size);
value[_pos] = char_val;
length[_pos] = size + 1;
format[_pos] = 0;
++ _pos;
}
void DBConnection::TParams::Add(int val)
{
#ifdef __OS_MAC__
int* int_val = new (int)(val);
#else
int* int_val = new (int)(htonl(val));
#endif
value[_pos] = (char*)(int_val);
length[_pos] = sizeof(int);
format[_pos] = 1;
++ _pos;
}
void DBConnection::TParams::Add(unsigned int val)
{
#ifdef __OS_MAC__
unsigned int* int_val = new (unsigned int)(val);
#else
unsigned int* int_val = new (unsigned int)(htonl(val));
#endif
value[_pos] = (char*)(int_val);
length[_pos] = sizeof(int);
format[_pos] = 1;
++ _pos;
}
void DBConnection::TParams::Add(uint64_t val)
{
#ifdef __OS_MAC__
uint64_t* uint64_val = new uint64_t(val);
#else
uint64_t* uint64_val = new uint64_t(htobe64(val));
#endif
value[_pos] = (char*)(uint64_val);
length[_pos] = sizeof(uint64_t);
format[_pos] = 1;
++ _pos;
}
void DBConnection::TParams::Add(short val)
{
#ifdef __OS_MAC__
short* int_val = new (short)(val);
#else
short* int_val = new (short)(htons(val));
#endif
value[_pos] = (char*)(int_val);
length[_pos] = sizeof(short);
format[_pos] = 1;
++ _pos;
}
////
DBConnection::~DBConnection()
{
Disconnect();
}
int DBConnection::Connect(const char* info)
{
conn = PQconnectdb(info);
if (PQstatus(conn) != CONNECTION_OK)
{
DEBUG(DEBUG_ANY, "PQ connection failed.");
PQfinish(conn);
return -1;
}
return 0;
}
void DBConnection::Disconnect()
{
if (conn != NULL)
{
PQfinish(conn);
conn = NULL;
}
}
int DBConnection::ExecCmd(const char* cmd)
{
PGresult* res = PQexec(conn, cmd);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
DEBUG(DEBUG_ANY, "<DBConnection::ExecCmd> failed - " << cmd << std::endl);
DEBUG(DEBUG_ANY, "DBConnection::ExecCmd> error - " << PQerrorMessage(conn) << std::endl);
PQclear(res);
return -1;
}
// int ret = ntohl(*PQcmdTuples(res));
int ret = *PQcmdTuples(res);
PQclear(res);
return ret;
}
PGresult* DBConnection::ExecQuery(const char* sql)
{
PGresult* res = PQexec(conn, sql);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
DEBUG(DEBUG_ANY, "<DBConnection::ExecQuery> failed - " << sql << std::endl);
DEBUG(DEBUG_ANY, "DBConnection::ExecQuery> error - " << PQerrorMessage(conn) << std::endl);
PQclear(res);
return NULL;
}
return res;
}
int DBConnection::ExecCmdWithParams(const char* cmd, const DBConnection::TParams& params)
{
PGresult* res = PQexecParams(conn, cmd, params.Size(), NULL, params.Value(), params.Length(), params.Format(), 0);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
DEBUG(DEBUG_ANY, "<DBConnection::ExecCmdWithParams> failed - " << cmd << std::endl);
DEBUG(DEBUG_ANY, "DBConnection::ExecCmdWithParams> error - " << PQerrorMessage(conn) << std::endl);
PQclear(res);
return -1;
}
// int ret = ntohl(*PQcmdTuples(res));
int ret = *PQcmdTuples(res);
PQclear(res);
DEBUG(DEBUG_ANY, "<DBConnection::ExecCmdWithParams> succ - " << cmd << std::endl);
return ret;
// return 0;
}
PGresult* DBConnection::ExecQueryWithParams(const char* sql, const TParams& params)
{
PGresult* res = PQexecParams(conn, sql, params.Size(), NULL, params.Value(), params.Length(), params.Format(), 0);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
DEBUG(DEBUG_ANY, "<DBConnection::ExecQueryWithParams> failed - " << sql << std::endl);
DEBUG(DEBUG_ANY, "DBConnection::ExecQueryWithParams> error - " << PQerrorMessage(conn) << std::endl);
PQclear(res);
return NULL;
}
return res;
}
int DBConnection::BeginTranscation()
{
return ExecCmd("BEGIN");
}
int DBConnection::EndTranscation()
{
return ExecCmd("END");
}