对libpq进行简单的c++封装
2011-07-27 17:04
381 查看
最近项目需要用c++操作PostgreSQL,编译c++的libpqxx遇到太多问题,虽然搞定,但不适合项目开发和维护。且官网似乎对此第三方库并不推荐,所以就查阅了相关资料,封装了一个c++的hpp,用来操作数据库。代码如下:
运行结果如下:
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
#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
相关文章推荐
- 对libpq进行简单的c++封装
- 使用C++进行WMI查询的简单封装
- 用C++封装了一个简单的“按钮”类
- 对系统网络请求进行简单封装
- C++封装一个简单的线程类
- 使用Retrofit和Rxjava对联网进行简单封装
- 用c++封装一个Hash Table,并与STL map 进行操作性能上的比较
- WebBrowser Control的一个简单C++封装
- C++中 栈的简单封装
- 简单的关于C++继承的封装
- 对系统网络请求进行简单封装
- Android Studio下使用JAVA+Appium进行自动化测试及简单封装
- 用C++进行简单的文件I/O操作
- 一个依靠STL vector的接口进行申请和回收管理的内存池类( c++ 封装)
- 使用windbg进行简单的debug c++代码
- C也可以通过精心封装某些函数功能实现重用,那C++的类有什么优点吗(从面向对象的三大属性进行分析)
- 对ZXing进行封装,整合成一个调用简单的Scanner接口
- 对Pthread线程进行简单的类封装
- C++使用try&catch进行异常处理的简单范例
- curl的简单封装(c++版本)