PostgreSQL libpq client interface (1)

Preface

Libpq is a PostgreSQL interface for C language development. Libpq is composed of related library functions, allowing client programs to pass queries to the PostgreSQL backend server and receive the results returned by these queries. At the same time, libpq is also the basic engine for several other PostgreSQL application programming interfaces, including embedded SQL for C++, Perl, Python, Tcl and ECPGC programming.

Connection string

The following function handles the connection of the PostgreSQL backend server. An application can have multiple open connections at the same time, which is why the PostgreSQL server can access multiple libraries at the same time. Each connection is represented by a PGconn object, which can obtain information from the functions PQconnectdb, PQconnectdbParams or PQsetdbLogin. It should be noted that these objects usually return a non-null object pointer. Unless the memory is too small to allocate PGconn objects. The PQstatus function is used to check whether the connection is successful before executing the query.

The function description is as follows:
PQconnectdbParams
This parameter is used to create a new connection to the database server. as follows:

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

This function uses the two NULL-terminated arrays to open a new connection. First, keywords are used to define an array of strings, each of which is a keyword. Secondly, values, given a value for each keyword. The currently recognized keywords include host, hostaddr, port, dbname, user, password, passfile, connect_timeout, client_encoding, options, application_name, fallback_application_name, keepalives and other information. There are usually five commonly used host, hostaddr, port, dbname, user, and password.

When expand_dbname is non-zero, the value of the dbname keyword can be allowed as a connection string.
Regarding the definition of PGconn, PGconn belongs to the connection encapsulated to the back end, and the application does not need to care about the definition of the structure. Here is the definition of the structure:

typedef struct pg_conn PGconn;

It can be seen that the data type of PGconn is pg_conn, and the structure of the custom data type in pg_conn is as follows (only a few commonly used are described here):

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
    This function is similar to PQconnectdbParams, except that the function does not use a key-value value, but a string array constant. as follows:

PGconn * PQconnectdb(const char * conninfo);

In the above, the string array constant is conninfo, which is a pointer constant. The incoming string can be empty. When it is empty, the default uninx socket is used to connect, or it contains one or more parameter settings separated by spaces. Or it can include a URI. The URI format used is as follows:

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
    This function is used to connect using the specified database information. In fact, this step is omitted when PQconnectdb is executed. This function has the same function as PQconnectdb. It is used to create a new server connection, except that PQsetdbLogin specifies the relevant database information, and PQconnectdb uses URI to connect. If the parameter lacks parameters, the default value will also be used, that is, UNIX socket.
PGconn *PQsetdbLogin(const char *pghost,
                     const char *pgport,
                     const char *pgoptions,
                     const char *pgtty,
                     const char *dbName,
                     const char *login,
                     const char *pwd);
  • PQsetdb
    This function uses the specified database information to connect. Mainly used for compatibility with the previous version of the server, ignore it.

Connection state function

  • PQstatus

ConnStatusType PQstatus(const PGconn *conn);

This function returns the status of a connection. The value of this state may be a number. However, only two states can be seen outside the asynchronous connection process: CONNECTION_OK and CONNECTION_BAD. If the connection to the database is normal, CONNECTION_OK is returned, otherwise CONNECTION_BAD is returned. Usually an OK status will continue until PQfinish is executed.

  • PQerrorMessage
    This function returns the error message that occurred during the most recent connection.

char *PQerrorMessage(const PGconn *conn);

  • PQconnectionNeedsPassword
    This function returns the password that needs to be requested when using password encryption for authentication. If a password is required but the password is wrong, return 1; if not, return 0.

int PQconnectionNeedsPassword(const PGconn *conn);

  • PQparameterStatus
    returns the parameter information of the currently connected server

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

The status of the function may be one of multiple values. However, only two of these values ​​are visible outside of asynchronous connection processing: CONNECTION_OK and CONNECTION_BAD. The status of the normal connection to the database server is CONNECTION_OK. The status of not connected to the database server is CONNECTION_BAD. Normally, the status of successful server connection will be kept until the execution of PQfinish ends, but server connection communication failure may cause the status to be changed to CONNECTION_BAD prematurely. In this case, the application may try to recover by calling PQreset.

  • PQtransactionStatus
    returns the status of the server currently in a transaction.

PGTransactionStatusType PQtransactionStatus(const PGconn *conn);

This state may be PQTRANS_IDLE (currently idle), PQTRANS_ACTIVE (there are commands being executed in the transaction), PQTRANS_INTRANS (indicating that the state is idle in a valid transaction block), or PQTRANS_INERROR (indicating that it is idle in a failed transaction block). If the server connection fails, it will prompt PQTRANS_UNKNOWN status. Only when a query in a transaction is sent to the server and is not completed, the server status in the transaction is PQTRANS_ACTIVE.

  • PQerrorMessage
    This function returns information about the most recent operation error generated on a connected server.

char *PQerrorMessage(const PGconn *conn);

  • PQbackendPID
    This function returns the ID of a background process connected to the server.

int PQbackendPID(const PGconn *conn);

Generally, the background PID is very useful for connections for debugging purposes and for comparing NOTIFY information.

  • PQconnectionNeedsPassword
    If the connection authentication method requests a password, then this function returns 1, if there is no password request, it returns 0.

int PQconnectionNeedsPassword(const PGconn *conn);

This function is used to try to determine whether to prompt the user's password after the connection fails.

  • PQconnectionUsedPassword
    returns 1 if a connection authentication method uses a password, otherwise it returns 0.

int PQconnectionUsedPassword(const PGconn *conn);

Example

#创建源码文件存放目录
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("OK\n");
    }

}

#编写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

Author: Song Shaohua

Member of Training and Certification Committee of PostgreSQL Branch, Chief Technical Expert of Shengshu Technology, Gold Lecturer of Shengshu College, Oracle 11g OCM, PostgreSQL's first batch of PGCE.

Served the State Grid Jibei Electric Power Co., Ltd. to build a big data platform, built IT basic services for the Human Resources and Social Security Bureau and the Beijing Municipal Health and Family Planning Commission, and built web servers, system and database maintenance for many banks and securities companies; IT training experience in government industries such as State Grid, banks and private enterprises; design DW data warehouse models for related security industries, use PostgreSQL, Greenplum, HUAWEIGaussDB, Vertica and Clickhouse as basic data services, develop TB-level data landing programs and 100 TB level Data migration program.

Guess you like

Origin blog.51cto.com/14575413/2542765