您的位置:首页 > 编程语言 > C语言/C++

对libpq进行简单的c++封装

2011-07-27 17:04 381 查看
  最近项目需要用c++操作PostgreSQL,编译c++的libpqxx遇到太多问题,虽然搞定,但不适合项目开发和维护。且官网似乎对此第三方库并不推荐,所以就查阅了相关资料,封装了一个c++的hpp,用来操作数据库。代码如下:

#ifndef _DBCONN_HPP_
#define _DBCONN_HPP_

#include <iostream>
#include <string>
#include <libpq-fe.h>
#include <map>
using namespace std;

typedef map<int,map<string,string> > map_result;

class Conn
{
public:
Conn(char *connstring);
~Conn();
map_result Fetch(char *SQL);
int Exec(char *SQL);
private:
void FinishConnection(PGconn *conn);
void Reset();
private:
PGconn *_conn;
const char *_conninfo;
PGresult *_res;
};

#endif // _DBCONN_HPP_


  

#include "DBConn.h"

Conn::Conn(char *connstring)
{
_conninfo = connstring;
_conn = PQconnectdb(_conninfo);
if (PQstatus(_conn) != CONNECTION_OK)
{
fprintf(stderr, "Could not connect to db/n%s", PQerrorMessage(_conn));
FinishConnection(_conn);
}
}
Conn::~Conn()
{
_conninfo = NULL;
FinishConnection(_conn);
}
void Conn::Reset()
{
PQfinish(_conn);
_conn = PQconnectdb(_conninfo);
}

void Conn::FinishConnection(PGconn *conn)
{
PQfinish(_conn);
}

map_result Conn::Fetch(char *SQL)
{
int row, col;
map_result results;
map<string,string> pairs;
// 检查连接
if (PQstatus(_conn) != CONNECTION_OK)
{
this->Reset();
}
// 开始一个事物
_res = PQexec(_conn, "BEGIN");
if (PQresultStatus(_res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "Failed to BEGIN transaction /n%s", PQerrorMessage(_conn));
PQclear(_res);
FinishConnection(_conn);
}
// 建立游标
string FinalSQL = string("DECLARE myportal CURSOR FOR ") +
string(SQL);
_res = PQexec(_conn,FinalSQL.c_str());
if (PQresultStatus(_res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "QUERY FAILED/n%s/n", PQerrorMessage(_conn));
PQclear(_res);
FinishConnection(_conn);
}
PQclear(_res);

_res = PQexec(_conn, "FETCH ALL in myportal");
if (PQresultStatus(_res) != PGRES_TUPLES_OK)
{
fprintf(stderr, "FETCH ALL failed/n%s/n", PQerrorMessage(_conn));
PQclear(_res);
FinishConnection(_conn);
}
else
{
for (row=0;row<PQntuples(_res);row++)
{
for(col=0;col<PQnfields(_res);col++)
{
pairs[PQfname(_res,col)] = PQgetvalue(_res, row, col);
}
results[row] = pairs;
}
}
// 结束一个事物
_res = PQexec(_conn, "END");
if (PQresultStatus(_res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "Failed to END transaction /n%s", PQerrorMessage(_conn));
PQclear(_res);
FinishConnection(_conn);
}
return results;
}
int Conn::Exec(char *sql)
{
// 检查连接
if (PQstatus(_conn) != CONNECTION_OK)
{
this->Reset();
}
// 开始一个事物
_res = PQexec(_conn, "BEGIN");
if (PQresultStatus(_res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "Failed to BEGIN transaction /n%s/n", PQerrorMessage(_conn));
PQclear(_res);
FinishConnection(_conn);
}
// 执行插入
_res = PQexec(_conn, sql);
if (PQresultStatus(_res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "Failed to execute INSERT /n%s/n", PQerrorMessage(_conn));
PQclear(_res);
FinishConnection(_conn);
}
// 提交事物
_res = PQexec(_conn, "COMMIT");
if (PQresultStatus(_res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "Failed to COMMIT transaction/n%s/n", PQerrorMessage(_conn));
PQclear(_res);
FinishConnection(_conn);
}
// 结束一个事物
_res = PQexec(_conn, "END");
if (PQresultStatus(_res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "Failed to END transaction /n%s", PQerrorMessage(_conn));
PQclear(_res);
FinishConnection(_conn);
}
return 0;
}


  

#include <iostream>
#include "DBConn.h"
using namespace std;

int main()
{
map_result res;
Conn *postgres = new Conn("host=192.168.150.131 dbname=postgres user=enterprisedb password=mayong port=5432 connect_timeout=5");
for( int i=0; i<4; ++i )
{
postgres->Exec("insert into test (select nextval('s_id'), 'dog', 3)");
}
res = postgres->Fetch("SELECT * FROM test where name = 'dog'");
map_result::iterator it = res.begin();
for( ; it!=res.end(); ++it )
{
cout << "ROW:" << it->first << endl;
map<string,string>::iterator itField = it->second.begin();
for( ; itField!=it->second.end(); ++itField )
{
cout << "Field:" << itField->first << "  Value:" << itField->second << endl;
}
}

postgres->Exec("update test set name = 'cat' where name = 'dog'");
cout << "--------------------------------" << endl;
res = postgres->Fetch("SELECT * FROM test where name = 'cat'");
it = res.begin();
for( ; it!=res.end(); ++it )
{
cout << "ROW:" << it->first << endl;
map<string,string>::iterator itField = it->second.begin();
for( ; itField!=it->second.end(); ++itField )
{
cout << "Field:" << itField->first << "  Value:" << itField->second << endl;
}
}

postgres->Exec("delete from test where name = 'cat'");

delete postgres;
return 0;
}


运行结果如下:

ROW:0

Field:age Value:3

Field:id Value:243

Field:name Value:dog

ROW:1

Field:age Value:3

Field:id Value:244

Field:name Value:dog

ROW:2

Field:age Value:3

Field:id Value:245

Field:name Value:dog

ROW:3

Field:age Value:3

Field:id Value:246

Field:name Value:dog

--------------------------------

ROW:0

Field:age Value:3

Field:id Value:243

Field:name Value:cat

ROW:1

Field:age Value:3

Field:id Value:244

Field:name Value:cat

ROW:2

Field:age Value:3

Field:id Value:245

Field:name Value:cat

ROW:3

Field:age Value:3

Field:id Value:246

Field:name Value:cat
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: