接口篇 – C连接Greenplum

如果说Java占据应用开发领域、Golang占据中间件开发领域、那么C语言无疑是底层开发的霸主,现在大多数开发人员可能不怎么会用C语言进行开发。但是在2020年1月份发布的2019年度编程语言(https://www.tiobe.com/tiobe-index/ )中,C语言战胜众多对手,王者归来,足见C语言的地位。

也确实如上所说,C语言可能影响到软件开发的方方面面,但并不一定为你我所熟知。在 PostgreSQL/Greenplum 领域中,libpq 是 PostgreSQL/Greenplum 的C应用程序接口,这个C接口同时也是 C++、Perl、Python、Tcl 和 ECPG 应用接口的驱动引擎。今天就来简单看看这个C接口是如何使用的。

示例

可以将如下代码编辑到 gpadmin 用户下的 testlibpq.c 文件中,下面会介绍简单的编译和使用

/*
 * src/test/examples/testlibpq.c
 * testlibpq.c
 *      注意:下面需要引入libpq-fe.h头文件
 */
#include <stdio.h>
#include <stdlib.h>
#include "libpq-fe.h"
 
static void
exit_nicely(PGconn *conn)
{
    PQfinish(conn);
    exit(1);
}
 
int
main(int argc, char **argv)
{
    const char *conninfo;
    PGconn     *conn;
    PGresult   *res;
    int         nFields;
    int         i,
                j;
 
    /* 
     * 如果用户在命令行定义了参数,那么这里解析为conninfo,作为连接参数;
     * 如果没有定义,则会选用环境变量定义的连接参数或采用默认值。
     */
    if (argc > 1)
        conninfo = argv[1];
    else
        conninfo = "dbname = postgres";
 
    /* 创建一个数据库连接 */
    conn = PQconnectdb(conninfo);
 
    /* 检查连接是否成功开启 */
    if (PQstatus(conn) != CONNECTION_OK)
    {
        fprintf(stderr, "Connection to database failed: %s",
                PQerrorMessage(conn));
        exit_nicely(conn);
    }
 
    /* Set always-secure search path, so malicious users can't take control. */
    res = PQexec(conn,
                 "SELECT pg_catalog.set_config('search_path', '', false)");
    if (PQresultStatus(res) != PGRES_TUPLES_OK)
    {
        fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
        PQclear(res);
        exit_nicely(conn);
    }
 
    /*
     * 当完成操作后,执行清理操作,避免内存泄漏。
     */
    PQclear(res);
 
    /*
     * Our test case here involves using a cursor, for which we must be inside
     * a transaction block.  We could do the whole thing with a single
     * PQexec() of "select * from pg_database", but that's too trivial to make
     * a good example.
     */
 
    /* 开始一个事务块 */
    res = PQexec(conn, "BEGIN");
    if (PQresultStatus(res) != PGRES_COMMAND_OK)
    {
        fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn));
        PQclear(res);
        exit_nicely(conn);
    }
    PQclear(res);
 
    /*
     * 从pg_database表中获取数据
     */
    res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database");
    if (PQresultStatus(res) != PGRES_COMMAND_OK)
    {
        fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn));
        PQclear(res);
        exit_nicely(conn);
    }
    PQclear(res);
 
    res = PQexec(conn, "FETCH ALL in myportal");
    if (PQresultStatus(res) != PGRES_TUPLES_OK)
    {
        fprintf(stderr, "FETCH ALL failed: %s", PQerrorMessage(conn));
        PQclear(res);
        exit_nicely(conn);
    }
 
    /* 打印列名 */
    nFields = PQnfields(res);
    for (i = 0; i < nFields; i++)
        printf("%-15s", PQfname(res, i));
    printf("\n\n");
 
    /* 打印数据 */
    for (i = 0; i < PQntuples(res); i++)
    {
        for (j = 0; j < nFields; j++)
            printf("%-15s", PQgetvalue(res, i, j));
        printf("\n");
    }
 
    PQclear(res);
 
    /* 关闭上面定义的cursor */
    res = PQexec(conn, "CLOSE myportal");
    PQclear(res);
 
    /* end the transaction */
    res = PQexec(conn, "END");
    PQclear(res);
 
    /* 关闭数据库连接 */
    PQfinish(conn);
 
    return 0;
}

编译

[gpadmin@gp1 ~]$ gcc -I /usr/local/greenplum-db/include/ -L /usr/local/greenplum-db/lib -lpq testlibpq.c -o testlibpq

这里采用 gcc 编译器,指定头文件(-I)和库文件(-L),编译完成后,会生成二进制可执行文件 testlibpq。

运行

此时可以执行该文件,查看是否能正常访问数据库。

[gpadmin@gp1 ~]$ ./testlibpq
datname datdba encoding datcollate datctype datistemplate datallowconn datconnlimit datlastsysoid datfrozenxid datminmxid dattablespace datacl

template1 10 6 en_US.utf8 en_US.utf8 t t -1 12813 725 1 1663 {=c/gpadmin,gpadmin=CTc/gpadmin}
template0 10 6 en_US.utf8 en_US.utf8 t f -1 12813 725 1 1663 {=c/gpadmin,gpadmin=CTc/gpadmin}
postgres 10 6 en_US.utf8 en_US.utf8 t t -1 12813 725 1 1663

上面代码采用默认的连接信息,如果要特别指定,可以通过定义如下字符串信息来访问数据库。

[gpadmin@gp1 ~]$ ./testlibpq “host=172.16.142.191 port=5432 user=gpadmin dbname=postgres”
datname datdba encoding datcollate datctype datistemplate datallowconn datconnlimit datlastsysoid datfrozenxid datminmxid dattablespace datacl
template1 10 6 en_US.utf8 en_US.utf8 t t -1 12813 725 1 1663 {=c/gpadmin,gpadmin=CTc/gpadmin}
template0 10 6 en_US.utf8 en_US.utf8 t f -1 12813 725 1 1663 {=c/gpadmin,gpadmin=CTc/gpadmin}
postgres 10 6 en_US.utf8 en_US.utf8 t t -1 12813 725 1 1663

在尝试连接过程中,可能会报如下错误,此时需要修改 pg_hba.conf 文件并 gpstop -u 生效即可。

[gpadmin@gp1 ~]$ ./testlibpq
Connection to database failed: FATAL: no pg_hba.conf entry for host “[local]”, user “gpadmin”, database “postgres”, SSL off

参考文章

https://www.postgresql.org/docs/current/libpq-example.html

本文从CSDN(点击查看原文)转载而来。不代表烟海拾贝立场,如若转载,请注明出处:https://somirror.com/3697.html

(0)
上一篇 2023-01-17 11:13
下一篇 2023-01-17 14:38

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注