zoukankan      html  css  js  c++  java
  • [原创]libpqPostgreSQL客户端编程接口(一)libpq中的数据库连接函数

    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 }
  • 相关阅读:
    Spring boot unable to determine jdbc url from datasouce
    Unable to create initial connections of pool. spring boot mysql
    spring boot MySQL Public Key Retrieval is not allowed
    spring boot no identifier specified for entity
    Establishing SSL connection without server's identity verification is not recommended
    eclipse unable to start within 45 seconds
    Oracle 数据库,远程访问 ora-12541:TNS:无监听程序
    macOS 下安装tomcat
    在macOS 上添加 JAVA_HOME 环境变量
    Maven2: Missing artifact but jars are in place
  • 原文地址:https://www.cnblogs.com/ode/p/3066565.html
Copyright © 2011-2022 走看看