PostgreSQL作为目前最优秀的跨平台的开源数据库,其介绍及优点这里不再赘述,它能让我以最快的速度忘记my*,ms*。libpq是PostgreSQL的C应用程序接口,它允许客户程序向PostgreSQL服务器进程发送查询并获得查询结果。
我的实验环境是:
操作系统:Linux wheezy 3.2.0-4-amd64 #1 SMP Debian 3.2.41-2 x86_64 GNU/Linux
数据库:EnterpriseDB (PostgreSQL Plus Advanced Server)9.2.1.3
示例语言:c++
工具:cmake2.8.9,g++ (Debian 4.7.2-5) 4.7.2
可能大家只知道PostgreSQL,对EnterpriseDB则比较陌生,这里简单介绍一下EnterpriseDB。EnterpriseDB是在PostgreSQL基础上,针对企业级应用进行了专门的优化,同时增加了一系列如动态性能调优(DynaTune)、EDB Loader、高效批量SQL处理等高级特性;另外EnterpriseDB与Oracle近乎完美的兼容性以及相对Oracle低廉的价格更是一大亮点,这些优异的特点加上IBM与Redhat的巨额注资,我看好它。EnterpriseDB的libpq与PostgreSQL开源版本完全一致,所以这里您也可以使用PostgreSQL。
一、准备项目文件CMakeLists.txt,设置libpq的依赖项
使用 libpq 的前端程序必须包括头文件 libpq-fe.h 并且必须与 libpq 库链接。我们创建一个简单的示例项目,并且用cmake作为项目管理工具,这样可以同时复习之前介绍过的cmake相关的知识。
创建CMakeLists.txt文件,里面的内容如下:
project(edbconn) cmake_minimum_required(VERSION 2.8) aux_source_directory(. SRC_LIST) add_executable(${PROJECT_NAME} ${SRC_LIST}) SET(PG_BASE "/opt/PostgresPlus/9.2AS") INCLUDE_DIRECTORIES("${PG_BASE}/include") LINK_DIRECTORIES("${PG_BASE}/lib") TARGET_LINK_LIBRARIES(${PROJECT_NAME} "${PG_BASE}/lib/libpq.so")
简单解释一下:
INCLUDE_DIRECTORIES("${PG_BASE}/include")
告诉编译器在哪里去找PostgreSQL的头文件,我的EnterpriseDB安装目录是在/opt/PostgresPlus/9.2AS,INCLUDE_DIRECTORIES("/opt/PostgresPlus/9.2AS/include")这样写也是一样的。
LINK_DIRECTORIES("/opt/PostgresPlus/9.2AS/lib")
告诉编译器外部依赖库,也就是libpq的位置
最后不要忘了告诉编译器依赖项
TARGET_LINK_LIBRARIES(${PROJECT_NAME} "/opt/PostgresPlus/9.2AS/lib/libpq.so")
二、用c++通过libpq连接PostgreSQL数据库
类似学习一门新的编程语言从hello world!开始,现在先从连接数据库开始。这次demo是用c++作为开发语言,我陆续会写写 C#与PostgreSQL相关的笔记。
别忘记包含libpq-fe.h头文件 。
使用libpq连接PostgreSQL,首先要创建一个PGconn对象。
PGconn *conn;
1、PQconnectdb
定义:PGconn *PQconnectdb(const char *conninfo);
函数PQconnectdb的参数conninfo定义为:
char *conninfo = "hostaddr=127.0.0.1 port=5444 dbname=mydb user=enterprisedb password=edb";
conninfo字符串指定数据库的连接信息,各参数之间用空格隔开。参数hostaddr指定数据库主机的IP地址,port指定EnterpriseDB的端口,dbname指定连接的数据库,user和password...。
conn = PQconnectdb(conninfo);
2、PQsetlogin
定义:PGconn *PQsetdbLogin(const char *pghost,
const char *pgport,
const char *pgoptions,
const char *pgtty,
const char *dbName,
const char *login,
const char *pwd);
如果没有给固定参数指定默认值,写NULL或一个空字符串就可以了。
conn = PQsetdbLogin("localhost","5444",NULL,NULL,"mydb","enterprisedb","edb");
PQconnectdb和PQsetdbLogin函数区别不大,怎么用方便就怎么用。
三、连接状态函数
1、返回连接建立时的参数,这些值是固定的
返回连接的数据库名
char *PQdb(const PGconn *conn);
返回连接的用户名
char *PQuser(const PGconn *conn);
返回连接的密码
char *PQpass(const PGconn *conn);
返回连接的服务器主机名
char *PQhost(const PGconn *conn);
…
…
返回连接的端口
char *PQport(const PGconn *conn);
2、返回对PGconn对象操作时的状态数据
返回连接的状态。
ConnStatusType PQstatus(const PGconn *conn);
ConnStatusType的值最常用的两个是CONNECTION_OK或 CONNECTION_BAD。
// 判断与PostgreSQL的连接是否成功 if (PQstatus(conn) != CONNECTION_OK) { // do nothing... }
查询服务器当前的参数设置
const char *PQparameterStatus(const PGconn *conn, const char *paramName);
参数paramName可使用的值有:server_version , server_encoding, client_encoding, session_authorization, DateStyle, TimeZone, integer_datetimes 和 standard_conforming_strings
1 // PQparameterStatus 2 // 3 cout << "server_version : " << PQparameterStatus(conn,"server_version") << endl; 4 cout << "server_encoding : " << PQparameterStatus(conn,"server_encoding") << endl; 5 cout << "client_encoding : " << PQparameterStatus(conn,"client_encoding") << endl; 6 cout << "session_authorization : " << PQparameterStatus(conn,"session_authorization") << endl; 7 cout << "DateStyle : " << PQparameterStatus(conn,"DateStyle") << endl; 8 cout << "TimeZone : " << PQparameterStatus(conn,"TimeZone") << endl; 9 cout << "integer_datetimes : " << PQparameterStatus(conn,"integer_datetimes") << endl; 10 cout << "standard_conforming_strings : " << PQparameterStatus(conn,"standard_conforming_strings") << endl;
返回连接中操作产生的最近的错误信息。
char *PQerrorMessage(const PGconn *conn);
返回当前连接的进程ID(PID)
int PQbackendPID(const PGconn *conn);
到这里,已经可以通过libpq连接到PostgreSQL数据库了。
示例代码:
1 #include <iostream> 2 #include "libpq-fe.h" 3 using namespace std; 4 5 static void exit_nicely(PGconn *conn) 6 { 7 PQfinish(conn); 8 } 9 10 int main() 11 { 12 PGconn *conn; 13 14 /* 15 * PGconn *PQconnectdb(const char *conninfo); 16 */ 17 18 //const char *conninfo = "hostaddr=127.0.0.1 port=5444 dbname=mydb user=enterprisedb password=edb"; 19 // conn = PQconnectdb(conninfo); 20 conn = PQconnectdb("hostaddr=127.0.0.1 port=5444 dbname=mydb user=enterprisedb password=edb"); 21 22 /* 23 *PGconn *PQsetdbLogin(const char *pghost, 24 const char *pgport, 25 const char *pgoptions, 26 const char *pgtty, 27 const char *dbName, 28 const char *login, 29 const char *pwd); 30 */ 31 32 /* Make a connection to the database */ 33 //conn = PQsetdbLogin("localhost","5444",NULL,NULL,"mydb","enterprisedb","edb"); 34 35 /* Check to see that the backend connection was successfully made */ 36 if (PQstatus(conn) != CONNECTION_OK) 37 { 38 cout << "connect failed. PQstatus : " << PQstatus(conn) << endl; 39 // char *PQerrorMessage(const PGconn *conn); 40 cout << PQerrorMessage(conn) << endl; 41 exit_nicely(conn); 42 43 return 0; 44 } 45 46 // PQdb 47 cout << "数据库名 : " << PQdb(conn) << endl; 48 49 // PQuser 50 cout << "用户名 : " << PQuser(conn) << endl; 51 52 // PQpass 53 cout << "口令 : " << PQpass(conn) << endl; 54 55 switch(PQstatus(conn)) 56 { 57 case CONNECTION_STARTED: 58 cout << "正在连接..." << endl; 59 break; 60 61 case CONNECTION_MADE: 62 cout << "与服务器连接已建立..." << endl; 63 break; 64 65 case CONNECTION_AUTH_OK: 66 cout << "auth is ok." << endl; 67 break; 68 69 case CONNECTION_OK: 70 cout << "connected." << endl; 71 break; 72 73 default: 74 cout << "正在连接..." << endl; 75 } 76 77 cout << "---------- 连接状态函数 ---------- " << endl; 78 // 79 // PQparameterStatus 80 // server_version , server_encoding, client_encoding, session_authorization, DateStyle, TimeZone, integer_datetimes 和 standard_conforming_strings 81 cout << "server_version : " << PQparameterStatus(conn,"server_version") << endl; 82 cout << "server_encoding : " << PQparameterStatus(conn,"server_encoding") << endl; 83 cout << "client_encoding : " << PQparameterStatus(conn,"client_encoding") << endl; 84 cout << "session_authorization : " << PQparameterStatus(conn,"session_authorization") << endl; 85 cout << "DateStyle : " << PQparameterStatus(conn,"DateStyle") << endl; 86 cout << "TimeZone : " << PQparameterStatus(conn,"TimeZone") << endl; 87 cout << "integer_datetimes : " << PQparameterStatus(conn,"integer_datetimes") << endl; 88 cout << "standard_conforming_strings : " << PQparameterStatus(conn,"standard_conforming_strings") << endl; 89 90 // PQprotocolVersion 91 cout << "PQprotocolVersion : " << PQprotocolVersion(conn) << endl; 92 93 // PQbackendPID 94 cout << "PQbackendPID : " << PQbackendPID(conn) << endl; 95 96 // PQgetssl 97 cout << "PQgetssl : " << PQgetssl(conn) << endl; 98 99 PQfinish(conn); 100 101 return 0; 102 }