博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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

Posted on 2011-07-27 17:04  开源云  阅读(1556)  评论(1编辑  收藏  举报

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

 1 #ifndef _DBCONN_HPP_
2 #define _DBCONN_HPP_
3
4 #include <iostream>
5 #include <string>
6 #include <libpq-fe.h>
7 #include <map>
8 using namespace std;
9
10 typedef map<int,map<string,string> > map_result;
11
12 class Conn
13 {
14 public:
15 Conn(char *connstring);
16 ~Conn();
17 map_result Fetch(char *SQL);
18 int Exec(char *SQL);
19 private:
20 void FinishConnection(PGconn *conn);
21 void Reset();
22 private:
23 PGconn *_conn;
24 const char *_conninfo;
25 PGresult *_res;
26 };
27
28
29 #endif // _DBCONN_HPP_

  

  1 #include "DBConn.h"
2
3 Conn::Conn(char *connstring)
4 {
5 _conninfo = connstring;
6 _conn = PQconnectdb(_conninfo);
7 if (PQstatus(_conn) != CONNECTION_OK)
8 {
9 fprintf(stderr, "Could not connect to db/n%s", PQerrorMessage(_conn));
10 FinishConnection(_conn);
11 }
12 }
13 Conn::~Conn()
14 {
15 _conninfo = NULL;
16 FinishConnection(_conn);
17 }
18 void Conn::Reset()
19 {
20 PQfinish(_conn);
21 _conn = PQconnectdb(_conninfo);
22 }
23
24 void Conn::FinishConnection(PGconn *conn)
25 {
26 PQfinish(_conn);
27 }
28
29 map_result Conn::Fetch(char *SQL)
30 {
31 int row, col;
32 map_result results;
33 map<string,string> pairs;
34 // 检查连接
35 if (PQstatus(_conn) != CONNECTION_OK)
36 {
37 this->Reset();
38 }
39 // 开始一个事物
40 _res = PQexec(_conn, "BEGIN");
41 if (PQresultStatus(_res) != PGRES_COMMAND_OK)
42 {
43 fprintf(stderr, "Failed to BEGIN transaction /n%s", PQerrorMessage(_conn));
44 PQclear(_res);
45 FinishConnection(_conn);
46 }
47 // 建立游标
48 string FinalSQL = string("DECLARE myportal CURSOR FOR ") +
49 string(SQL);
50 _res = PQexec(_conn,FinalSQL.c_str());
51 if (PQresultStatus(_res) != PGRES_COMMAND_OK)
52 {
53 fprintf(stderr, "QUERY FAILED/n%s/n", PQerrorMessage(_conn));
54 PQclear(_res);
55 FinishConnection(_conn);
56 }
57 PQclear(_res);
58
59 _res = PQexec(_conn, "FETCH ALL in myportal");
60 if (PQresultStatus(_res) != PGRES_TUPLES_OK)
61 {
62 fprintf(stderr, "FETCH ALL failed/n%s/n", PQerrorMessage(_conn));
63 PQclear(_res);
64 FinishConnection(_conn);
65 }
66 else
67 {
68 for (row=0;row<PQntuples(_res);row++)
69 {
70 for(col=0;col<PQnfields(_res);col++)
71 {
72 pairs[PQfname(_res,col)] = PQgetvalue(_res, row, col);
73 }
74 results[row] = pairs;
75 }
76 }
77 // 结束一个事物
78 _res = PQexec(_conn, "END");
79 if (PQresultStatus(_res) != PGRES_COMMAND_OK)
80 {
81 fprintf(stderr, "Failed to END transaction /n%s", PQerrorMessage(_conn));
82 PQclear(_res);
83 FinishConnection(_conn);
84 }
85 return results;
86 }
87 int Conn::Exec(char *sql)
88 {
89 // 检查连接
90 if (PQstatus(_conn) != CONNECTION_OK)
91 {
92 this->Reset();
93 }
94 // 开始一个事物
95 _res = PQexec(_conn, "BEGIN");
96 if (PQresultStatus(_res) != PGRES_COMMAND_OK)
97 {
98 fprintf(stderr, "Failed to BEGIN transaction /n%s/n", PQerrorMessage(_conn));
99 PQclear(_res);
100 FinishConnection(_conn);
101 }
102 // 执行插入
103 _res = PQexec(_conn, sql);
104 if (PQresultStatus(_res) != PGRES_COMMAND_OK)
105 {
106 fprintf(stderr, "Failed to execute INSERT /n%s/n", PQerrorMessage(_conn));
107 PQclear(_res);
108 FinishConnection(_conn);
109 }
110 // 提交事物
111 _res = PQexec(_conn, "COMMIT");
112 if (PQresultStatus(_res) != PGRES_COMMAND_OK)
113 {
114 fprintf(stderr, "Failed to COMMIT transaction/n%s/n", PQerrorMessage(_conn));
115 PQclear(_res);
116 FinishConnection(_conn);
117 }
118 // 结束一个事物
119 _res = PQexec(_conn, "END");
120 if (PQresultStatus(_res) != PGRES_COMMAND_OK)
121 {
122 fprintf(stderr, "Failed to END transaction /n%s", PQerrorMessage(_conn));
123 PQclear(_res);
124 FinishConnection(_conn);
125 }
126 return 0;
127 }

  

 1 #include <iostream>    
2 #include "DBConn.h"
3 using namespace std;
4
5 int main()
6 {
7 map_result res;
8 Conn *postgres = new Conn("host=192.168.150.131 dbname=postgres user=enterprisedb password=mayong port=5432 connect_timeout=5");
9 for( int i=0; i<4; ++i )
10 {
11 postgres->Exec("insert into test (select nextval('s_id'), 'dog', 3)");
12 }
13 res = postgres->Fetch("SELECT * FROM test where name = 'dog'");
14 map_result::iterator it = res.begin();
15 for( ; it!=res.end(); ++it )
16 {
17 cout << "ROW:" << it->first << endl;
18 map<string,string>::iterator itField = it->second.begin();
19 for( ; itField!=it->second.end(); ++itField )
20 {
21 cout << "Field:" << itField->first << " Value:" << itField->second << endl;
22 }
23 }
24
25 postgres->Exec("update test set name = 'cat' where name = 'dog'");
26 cout << "--------------------------------" << endl;
27 res = postgres->Fetch("SELECT * FROM test where name = 'cat'");
28 it = res.begin();
29 for( ; it!=res.end(); ++it )
30 {
31 cout << "ROW:" << it->first << endl;
32 map<string,string>::iterator itField = it->second.begin();
33 for( ; itField!=it->second.end(); ++itField )
34 {
35 cout << "Field:" << itField->first << " Value:" << itField->second << endl;
36 }
37 }
38
39 postgres->Exec("delete from test where name = 'cat'");
40
41 delete postgres;
42 return 0;
43 }

运行结果如下:

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