乐趣区

关于sql:PostgreSQL-libpq-客户端接口一

前言

Libpq 是为 C 语言开发这提供的对于 PostgreSQL 的接口。Libpq 由相干库函数组成,能够容许客户端程序通过将查问传递给 PostgreSQL 后盾服务器并接管这些查问返回的后果。同时,libpq 也是其它几个 PostgreSQL 利用程序接口的根底引擎,包含 C++,Perl,Python,Tcl 和 ECPGC 编程的嵌入式 SQL。

连贯字符串

以下函数解决 PostgreSQL 后盾服务器的连贯。一个应用程序同时能够有多个关上的连贯,这也是 PostgreSQL 服务器可能同时拜访多个库的起因。每一个连贯都通过 PGconn 对象示意,该对象能够从函数 PQconnectdb,PQconnectdbParams 中或者 PQsetdbLogin 获取信息。须要留神的是,这些对象通常返回一个非空的对象指针。除非因为内存太小导致无奈调配 PGconn 对象。PQstatus 函数用来查看在执行查问前连贯是否胜利的状态。

函数介绍如下:
PQconnectdbParams 
该参数用来创立连贯到数据库服务器的新的连贯。如下:

PGconn *PQconnectdbParams(const char * const *keywords,
                          const char * const *values,
                          int expand_dbname);

该函数应用传入的两个 NULL 终止的数组中关上一个新的连贯,首先,keywords 用来定义一个字符串数组,每一个都是一个关键字。其次,values,为每个关键字给定一个值。以后可辨认的关键字有 host、hostaddr、port、dbname、user、password、passfile、connect_timeout、client_encoding、options、application_name、fallback_application_name,keepalives 等信息。罕用的通常有 host、hostaddr、port、dbname、user、password 这五个。

当 expand_dbname 是非零时,该 dbname 关键字的值能够容许作为一个连贯字符串。
而对于 PGconn 的定义,PGconn 属于封装到后端的连贯,应用程序不须要关怀该构造的定义,此处给出该构造的定义:

typedef struct pg_conn PGconn;

能够看出 PGconn 的数据类型为 pg_conn,而在 pg_conn 中自定义的数据类型的构造为如下(此处只形容了罕用的几个):

struct pg_conn 
{
        /* Saved values of connection options */
        char       *pghost;                     /* 服务器运行的主机
                                                * 或者是一个 UNIX 套接字, 或者是
                                                * 逗号分隔的主机列表,或者是门路
                                                * 如果为 NULL, 应用 DEFAULT_PGSOCKET_DIR 定义的套接字目录 
                                                */
        char       *pghostaddr;                 /* 服务器运行主机的数值 IP 地址或者主机列表
                                                * 优先于 pghost
                                                */
        char       *pgport;                     /* 服务器通信端口 */

        char       *connect_timeout;            /* 指定连贯超时 */
        char       *pgtcp_user_timeout;         /* tcp 用户超时 */
        char       *client_encoding_initial;    /* 客户端应用的编码 */ 
        char       *dbName;                     /* 数据库名称 */ 
        char       *pguser;                     /* 用户名 */
        char       *pgpass;                     /* 用户明码 */
};
  • PQconnectdb

该函数和 PQconnectdbParams 相似,只不过该函数应用的并非一个 key-value 的值,而是一个字符串数组常量。如下:

PGconn * PQconnectdb(const char * conninfo);

上述中,字符串数组常量为 conninfo,是一个指针常量。传入的字符串能够为空,为空时,应用默认 uninx 套接字进行连贯,或者蕴含一个或者多个用空格分隔的参数设置。或者能够蕴含 URI。应用的 URI 格局如下:

postgresql://
postgresql://localhost
postgresql://localhost:5433
postgresql://localhost/mydb
postgresql://user@localhost
postgresql://user:secret@localhost
postgresql://other@localhost/otherdb?connect_timeout=10&application_name=myapp
postgresql://host1:123,host2:456/somedb?target_session_attrs=any&application_name=myapp
  • PQsetdbLogin

该函数用来应用指定的数据库信息进行连贯,其实 PQconnectdb 执行时省略了这一步而已。该函数与 PQconnectdb 具备雷同的性能,都时用来创立一个新的服务器连贯,只不过 PQsetdbLogin 指定了相干的数据库信息,而 PQconnectdb 应用 URI 来连贯。如果该参数短少参数,也将采纳默认值,即 UNIX 套接字。

PGconn *PQsetdbLogin(const char *pghost,
                     const char *pgport,
                     const char *pgoptions,
                     const char *pgtty,
                     const char *dbName,
                     const char *login,
                     const char *pwd);
  • PQsetdb

该函数应用指定的数据库信息进行连贯。次要用来和以前版本的服务器进行兼容,疏忽。

连贯状态函数

  • PQstatus
ConnStatusType PQstatus(const PGconn *conn);

该函数返回一个连贯的状态。该状态的值可能是一个数字。然而,在异步连贯过程之外只能看到两个状态:CONNECTION_OK 和 CONNECTION_BAD。若连贯到数据库失常则返回 CONNECTION_OK,否则返回 CONNECTION_BAD。通常一个 OK 的状态将会继续到执行 PQfinish。

  • PQerrorMessage

该函数返回最近连贯时呈现的错误信息。

char *PQerrorMessage(const PGconn *conn);
  • PQconnectionNeedsPassword

该函数返回采纳明码加密形式认证时须要申请的明码。如果须要明码但明码谬误返回 1,如果没有则返回 0。

int PQconnectionNeedsPassword(const PGconn *conn);
  • PQparameterStatus

返回以后已连贯服务器的参数信息

const char *PQparameterStatus(const PGconn *conn, const char *paramName);

该函数的状态可能是多个值中的一个值。然而,这些值中仅有两种状态在异步连贯解决之外可见:CONNECTION_OK 和 CONNECTION_BAD。失常连贯到数据库服务器的状态是 CONNECTION_OK。未连贯到数据库服务器的状态为 CONNECTION_BAD。通常,服务器连贯胜利的状态会在 PQfinish 执行完结前始终保留,但服务器连贯通信失败可能会过早使状态变更为 CONNECTION_BAD。在这种状况下,应用程序可能会通过调用 PQreset 尝试复原。

  • PQtransactionStatus

返回以后处于事务当中服务器状态。

PGTransactionStatusType PQtransactionStatus(const PGconn *conn);

这个状态可能是 PQTRANS_IDLE(以后闲暇),PQTRANS_ACTIVE(事务中有正在执行的命令),PQTRANS_INTRANS(示意在一个无效的事务块中状态闲暇),或者 PQTRANS_INERROR(示意在一个失败的事务块中闲暇)。如果服务器连贯失败,将会提醒 PQTRANS_UNKNOWN 状态。只有当一个在事务中的查问被发送到服务器并且没有实现的时候,事务中的服务器状态为 PQTRANS_ACTIVE。

  • PQerrorMessage

该函数返回在一个已连贯到服务器上生成的最近操作谬误的信息。

char *PQerrorMessage(const PGconn *conn);
  • PQbackendPID

该函数返回一个已连贯到服务器的后盾过程 ID。

int PQbackendPID(const PGconn *conn);

通常,对于出于 debugging 目标和比拟 NOTIFY 信息的连贯来说,后盾 PID 十分有用。

  • PQconnectionNeedsPassword

如果连贯认证形式申请一个明码,那么该函数返回 1,如果没有明码申请,则返回 0。

int PQconnectionNeedsPassword(const PGconn *conn);

该函数被利用于在连贯失败后尝试决定是否须要提醒用户明码。

  • PQconnectionUsedPassword

如果一个连贯认证形式应用明码则返回 1,否则返回 0。

int PQconnectionUsedPassword(const PGconn *conn);

示例

# 创立源码文件寄存目录
mkdir /home/postgres/libpqtest
#编写源码文件 test.c
#include <stdio.h>
#include <stdlib.h>
#include "libpq-fe.h"

int main(int argc,char **argv)
{
    const char          *conninfo; // 定义传入连贯参数常量
    PGconn              *conn;     // 定义连贯字符串 
    if (argc > 1)
    {conninfo = argv[1];
    }else
    {conninfo = "dbname = postgres";}
    // 创立一个新的连贯
    conn = PQconnectdb(conninfo);
    // 查看连贯状态
    if (PQstatus(conn) != CONNECTION_OK)
    {
          // 打印连贯字符串信息
          fprintf(stderr,"谬误的连贯字符串信息: %s",PQerrorMessage(conn));
    }else
    {
         // 打印连贯的字符串信息
      printf("OKn");
    }

}

#编写 Makefile 文件
[postgres@sungsasong libpqtest]$ cat Makefile 
#
# Makefile for example programs
#

subdir = ~/libpqtest
top_builddir = /home/postgres/pack/postgresql-12.3
include $(top_builddir)/src/Makefile.global

ifeq ($(PORTNAME), win32)
LDFLAGS += -lws2_32
endif

override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS)
LDFLAGS_INTERNAL += $(libpq_pgport)


PROGS = test

all: $(PROGS)

clean distclean maintainer-clean:
    rm -f $(PROGS) *.o


#执行 make 编译
[postgres@sungsasong libpqtest]$ make
make -C /home/postgres/pack/postgresql-12.3/src/backend generated-headers
make[1]: Entering directory `/home/postgres/pack/postgresql-12.3/src/backend'
make -C catalog distprep generated-header-symlinks
make[2]: Entering directory `/home/postgres/pack/postgresql-12.3/src/backend/catalog'make[2]: Nothing to be done for `distprep'.
make[2]: Nothing to be done for `generated-header-symlinks'.
make[2]: Leaving directory `/home/postgres/pack/postgresql-12.3/src/backend/catalog'
make -C utils distprep generated-header-symlinks
make[2]: Entering directory `/home/postgres/pack/postgresql-12.3/src/backend/utils'make[2]: Nothing to be done for `distprep'.
make[2]: Nothing to be done for `generated-header-symlinks'.
make[2]: Leaving directory `/home/postgres/pack/postgresql-12.3/src/backend/utils'make[1]: Leaving directory `/home/postgres/pack/postgresql-12.3/src/backend'
gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -I/home/postgres/pack/postgresql-12.3/src/interfaces/libpq -I/home/postgres/pack/postgresql-12.3/src/include  -D_GNU_SOURCE -I/usr/include/libxml2   -c -o test.o test.c
gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 test.o -L/home/postgres/pack/postgresql-12.3/src/port -L/home/postgres/pack/postgresql-12.3/src/common -L/home/postgres/pack/postgresql-12.3/src/common -lpgcommon -L/home/postgres/pack/postgresql-12.3/src/port -lpgport -L/home/postgres/pack/postgresql-12.3/src/interfaces/libpq -lpq   -Wl,--as-needed -Wl,-rpath,'/data/pg12/lib',--enable-new-dtags  -lpgcommon -lpgport -lpthread -lxslt -lxml2 -lpam -lssl -lcrypto -lz -lreadline -lrt -lcrypt -ldl -lm  -o test


#执行程序 
[postgres@sungsasong libpqtest]$ ./test
OK
[postgres@sungsasong libpqtest]$ ./test "postgresql://localhost"
OK
[postgres@sungsasong libpqtest]$ ./test "postgresql://10.10.20.50:5404"
谬误的连贯字符串信息: could not connect to server: Connection refused
    Is the server running on host "10.10.20.50" and accepting
    TCP/IP connections on port 5404?
[postgres@sungsasong libpqtest]$ vi $PGDATA/postgresql.conf 
[postgres@sungsasong libpqtest]$ vi $PGDATA/pg_hba.conf 
[postgres@sungsasong libpqtest]$ pg_ctl  restart -D $PGDATA -l /tmp/logfile
waiting for server to shut down.... done
server stopped
waiting for server to start.... done
server started
[postgres@sungsasong libpqtest]$ ./test "postgresql://10.10.20.50:5404"
OK

作者:宋少华

PostgreSQL 分会培训认证委员会委员、晟数科技首席技术专家、晟数学院金牌讲师、oracle 11g OCM、PostgreSQL 首批 PGCE。

曾服务于国家电网冀北电力有限公司建设大数据平台,为人社局和北京市卫计委构建 IT 根底服务,为多家银行和证券公司构建 web 服务器,零碎及数据库保护;具备对税务局、国家电网、银行等政府行业和民营企业的 IT 培训教训;为相干平安行业设计 DW 数据仓库模型,应用 PostgreSQL,Greenplum,HUAWEIGaussDB,Vertica 和 Clickhouse 做数据根底服务,开发 TB 级数据落地程序及百 TB 级别数据迁徙程序。

退出移动版