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

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

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

DBConn.h

#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_

DBConn.cpp

#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;

}

main.cpp

#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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: