Interfaz de cliente libpq de PostgreSQL (1)

Prefacio

Libpq es una interfaz PostgreSQL para el desarrollo del lenguaje C. Libpq se compone de funciones de biblioteca relacionadas, lo que permite a los programas cliente pasar consultas al servidor backend de PostgreSQL y recibir los resultados devueltos por estas consultas. Al mismo tiempo, libpq también es el motor básico para varias otras interfaces de programación de aplicaciones de PostgreSQL, incluido el SQL incorporado para la programación C ++, Perl, Python, Tcl y ECPGC.

Cadena de conexión

La siguiente función maneja la conexión del servidor backend de PostgreSQL. Una aplicación puede tener múltiples conexiones abiertas al mismo tiempo, razón por la cual el servidor PostgreSQL puede acceder a múltiples bibliotecas al mismo tiempo. Cada conexión está representada por un objeto PGconn, que puede obtener información de las funciones PQconnectdb, PQconnectdbParams o PQsetdbLogin. Cabe señalar que estos objetos generalmente devuelven un puntero de objeto no nulo. A menos que la memoria sea demasiado pequeña para asignar objetos PGconn. La función PQstatus se usa para verificar si la conexión es exitosa antes de ejecutar la consulta.

La descripción de la función es la siguiente:
PQconnectdbParams
Este parámetro se utiliza para crear una nueva conexión al servidor de la base de datos. como sigue:

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

Esta función usa las dos matrices terminadas en NULL para abrir una nueva conexión Primero, las palabras clave se usan para definir una matriz de cadenas, cada una de las cuales es una palabra clave. En segundo lugar, valores, dado un valor para cada palabra clave. Las palabras clave actualmente reconocidas incluyen host, hostaddr, puerto, dbname, usuario, contraseña, passfile, connect_timeout, client_encoding, opciones, application_name, fallback_application_name, keepalives y otra información. Por lo general, hay cinco host, hostaddr, puerto, dbname, usuario y contraseña de uso común.

Cuando expand_dbname es distinto de cero, el valor de la palabra clave dbname se puede permitir como una cadena de conexión.
En cuanto a la definición de PGconn, PGconn pertenece a la conexión encapsulada al backend, y la aplicación no necesita preocuparse por la definición de la estructura. Aquí está la definición de la estructura:

typedef struct pg_conn PGconn;

Se puede ver que el tipo de datos de PGconn es pg_conn, y la estructura del tipo de datos personalizados en pg_conn es la siguiente (aquí solo se describen algunos de los que se usan comúnmente):

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
    Esta función es similar a PQconnectdbParams, excepto que la función no usa un valor clave-valor, sino una constante de matriz de cadena. como sigue:

PGconn * PQconnectdb(const char * conninfo);

En lo anterior, la constante de matriz de cadenas es conninfo, que es una constante de puntero. La cadena entrante puede estar vacía. Cuando está vacía, se usa el conector uninx predeterminado para conectarse, o contiene una o más configuraciones de parámetros separados por espacios. O puede incluir un URI. El formato de URI utilizado es el siguiente:

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
    Esta función se utiliza para conectarse utilizando la información de la base de datos especificada, de hecho, este paso se omite cuando se ejecuta PQconnectdb. Esta función tiene la misma función que PQconnectdb y se usa para crear una nueva conexión de servidor, excepto que PQsetdbLogin especifica la información relevante de la base de datos y PQconnectdb usa URI para conectarse. Si el parámetro carece de parámetros, también se utilizará el valor predeterminado, que es el socket 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
    Esta función utiliza la información de la base de datos especificada para conectarse. Se utiliza principalmente para la compatibilidad con la versión anterior del servidor, ignórelo.

Función de estado de conexión

  • PQstatus

ConnStatusType PQstatus(const PGconn *conn);

Esta función devuelve el estado de una conexión. El valor de este estado puede ser un número. Sin embargo, solo se pueden ver dos estados fuera del proceso de conexión asíncrona: CONNECTION_OK y CONNECTION_BAD. Si la conexión a la base de datos es normal, se devuelve CONNECTION_OK, de lo contrario se devuelve CONNECTION_BAD. Normalmente, un estado OK continuará hasta que se ejecute PQfinish.

  • PQerrorMessage
    Esta función devuelve el mensaje de error que ocurrió durante la conexión más reciente.

char *PQerrorMessage(const PGconn *conn);

  • PQconnectionNeedsPassword
    Esta función devuelve la contraseña que debe solicitarse cuando se utiliza el cifrado de contraseña para la autenticación. Si se requiere una contraseña pero la contraseña es incorrecta, devuelva 1; si no, devuelva 0.

int PQconnectionNeedsPassword(const PGconn *conn);

  • PQparameterStatus
    devuelve la información de los parámetros del servidor conectado actualmente

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

El estado de la función puede ser uno de varios valores. Sin embargo, solo dos de estos valores son visibles fuera del procesamiento de conexión asincrónica: CONNECTION_OK y CONNECTION_BAD. El estado de la conexión normal al servidor de la base de datos es CONNECTION_OK. El estado de no conectado al servidor de la base de datos es CONNECTION_BAD. Normalmente, el estado de la conexión con el servidor exitosa se mantendrá hasta que finalice la ejecución de PQfinish, pero una falla en la comunicación de la conexión con el servidor puede hacer que el estado cambie a CONNECTION_BAD antes de tiempo. En este caso, la aplicación puede intentar recuperarse llamando a PQreset.

  • PQtransactionStatus
    devuelve el estado del servidor actualmente en una transacción.

PGTransactionStatusType PQtransactionStatus(const PGconn *conn);

Este estado puede ser PQTRANS_IDLE (actualmente inactivo), PQTRANS_ACTIVE (hay comandos que se ejecutan en la transacción), PQTRANS_INTRANS (que indica que el estado está inactivo en un bloque de transacción válido) o PQTRANS_INERROR (que indica que está inactivo en un bloque de transacción fallido). Si la conexión del servidor falla, se le pedirá el estado PQTRANS_UNKNOWN. Solo cuando una consulta en una transacción se envía al servidor y no se completa, el estado del servidor en la transacción es PQTRANS_ACTIVE.

  • PQerrorMessage
    Esta función devuelve información sobre el error de operación más reciente generado en un servidor conectado.

char *PQerrorMessage(const PGconn *conn);

  • PQbackendPID
    Esta función devuelve el ID de un proceso en segundo plano conectado al servidor.

int PQbackendPID(const PGconn *conn);

Por lo general, el PID de fondo es muy útil para conexiones con fines de depuración y para comparar información NOTIFICAR.

  • PQconnectionNeedsPassword
    Si el método de autenticación de la conexión solicita una contraseña, esta función devuelve 1, si no hay una solicitud de contraseña, devuelve 0.

int PQconnectionNeedsPassword(const PGconn *conn);

Esta función se utiliza para intentar determinar si solicitar la contraseña del usuario después de que falle la conexión.

  • PQconnectionUsedPassword
    devuelve 1 si un método de autenticación de conexión utiliza una contraseña; de lo contrario, devuelve 0.

int PQconnectionUsedPassword(const PGconn *conn);

Ejemplo

#创建源码文件存放目录
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

Autor: Song Shaohua

Miembro del Comité de Capacitación y Certificación de la Rama PostgreSQL, Experto Técnico Jefe de Tecnología Shengshu, Profesor de Oro de Shengshu College, Oracle 11g OCM, primer lote de PGCE de PostgreSQL

Sirvió a State Grid Jibei Electric Power Co., Ltd. para construir una plataforma de big data, desarrolló servicios básicos de TI para la Oficina de Recursos Humanos y Seguridad Social y la Comisión Municipal de Salud y Planificación Familiar de Beijing, y creó servidores web, mantenimiento de sistemas y bases de datos para muchos bancos y compañías de valores; Experiencia en capacitación de TI en industrias gubernamentales como State Grid, bancos y empresas privadas; diseñar modelos de almacenamiento de datos DW para industrias de seguridad relacionadas, usar PostgreSQL, Greenplum, HUAWEIGaussDB, Vertica y Clickhouse para servicios de datos básicos, desarrollar programas de descarga de datos a nivel de TB y nivel de 100 TB Programa de migración de datos.

Supongo que te gusta

Origin blog.51cto.com/14575413/2542765
Recomendado
Clasificación