暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

openGauss下使用Libpq驱动开发-想说爱你不容易啊

SmallDB 2025-03-21
180

 

总结

想法1
自己运行代码的机器上不光需要下载官方的驱动,还要依赖数据库自身的动态库文件(意味着还要加载数据库自身的动态库),感觉依赖太多,后来者有太多的包袱前行了,因为它需要从已有的数据库市场抢占份额,需要兼容的东西太多了,把自己弄成了四不像了,搞的开发者太累了,折腾的东西太多了,没有经历的开发者,几乎很难搞定,这是我的感受
想法2
就是因为有太多的兼容性,太复杂,它才有很多集成商们专门来做这个事,从方案设计到落地实施维护一体化的方案,你只管用,其它的事我包了

操作如下

建立项目目录结构(一定要先好自己最贴近的版本,我就吃了这个亏)

[root@vbox ~]# mkdir demoproject
[root@vbox ~]# wget https://opengauss.obs.cn-south-1.myhuaweicloud.com/6.0.1/openEuler22.03/x86/openGauss-Libpq-6.0.1-openEuler22.03-x86_64.tar.gz
[root@vbox ~]# mv openGauss-Libpq-6.0.1-openEuler22.03-x86_64.tar.gz  demoproject/
[root@vbox ~]# cd demoproject/
[root@vbox demoproject]# tar -zxvf openGauss-Libpq-6.0.1-openEuler22.03-x86_64.tar.gz
[root@vbox demoproject]# ll
total 5404
drwxr-x---. 3 root root    4096 Jan 17 18:23 include
drwxr-x---. 2 root root    4096 Jan 17 18:23 lib
-rwxr-x---. 1 root root 5521498 Mar 21 08:37 openGauss-Libpq-6.0.1-openEuler22.03-x86_64.tar.gz

运行测试文件

[root@vbox demoproject]# gcc testlibpq.c -o test -I include   -L lib   -lpq
/usr/bin/ld: warning: libgssapi_krb5_gauss.so.2, needed by lib/libpq.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libgssrpc_gauss.so.4, needed by lib/libpq.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libkrb5_gauss.so.3, needed by lib/libpq.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libkrb5support_gauss.so.0, needed by lib/libpq.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libk5crypto_gauss.so.3, needed by lib/libpq.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libcom_err_gauss.so.3, needed by lib/libpq.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: lib/libpq.so: undefined reference to `gss_display_status@gssapi_krb5_gauss_2_MIT'
/usr/bin/ld: lib/libpq.so: undefined reference to `GSS_KRB5_NT_PRINCIPAL_NAME@gssapi_krb5_gauss_2_MIT'

/usr/bin/ld: lib/libpq.so: undefined reference to `krb5_set_profile_path@krb5_gauss_3_MIT'
/usr/bin/ld: lib/libpq.so: undefined reference to `krb5_clean_cache_profile_path@krb5_gauss_3_MIT'

/usr/bin/ld: lib/libpq.so: undefined reference to `gss_delete_sec_context@gssapi_krb5_gauss_2_MIT'
/usr/bin/ld: lib/libpq.so: undefined reference to `gss_release_name@gssapi_krb5_gauss_2_MIT'

/usr/bin/ld: lib/libpq.so: undefined reference to `gss_import_name@gssapi_krb5_gauss_2_MIT'
/usr/bin/ld: lib/libpq.so: undefined reference to `gss_release_buffer@gssapi_krb5_gauss_2_MIT'

/usr/bin/ld: lib/libpq.so: undefined reference to `gss_init_sec_context@gssapi_krb5_gauss_2_MIT'
collect2: error: ld returned 1 exit status
[root@vbox demoproject]#

安装缺失包

挂载镜像

[root@vbox mnt]# mount -o loop  openEuler-24.03-LTS-SP1-x86_64-dvd.iso  /media/cdrom/
mount: media/cdrom: WARNING: source write-protected, mounted read-only.
[root@vbox mnt]# df -Th
Filesystem                 Type      Size  Used Avail Use% Mounted on
/dev/mapper/openeuler-root ext4       17G  7.7G  8.1G  49% /
devtmpfs                   devtmpfs  4.0M     0  4.0M   0% /dev
tmpfs                      tmpfs     729M   12K  729M   1% /dev/shm
tmpfs                      tmpfs     4.0M     0  4.0M   0% /sys/fs/cgroup
tmpfs                      tmpfs     292M  4.3M  288M   2% /run
tmpfs                      tmpfs     729M  8.0K  729M   1% /tmp
/dev/sda2                  ext4      974M  210M  697M  24% /boot
D_DRIVE                    vboxsf    257G  101G  156G  40% /mnt
/dev/loop0                 iso9660   4.1G  4.1G     0 100% /media/cdrom
[root@vbox mnt]#

为镜像设置YUM源

cd /etc/yum.repos.d/
mv openEuler.repo openEuler.repo.bak
vi openEuler.repo

下载密钥

[root@vbox demoproject]# wget http://repo.openeuler.org/openEuler-24.03-LTS-SP1/OS/x86_64/RPM-GPG-KEY-openEuler

配置镜像

[cdrom]
baseurl=file:///media/cdrom
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-openEuler

运行

[root@vbox demoproject]# ll
total 5428
drwxr-x---. 3 root root    4096 Jan 17 18:23 include
drwxr-x---. 2 root root    4096 Jan 17 18:23 lib
-rwxr-x---. 1 root root 5521498 Mar 21 08:37 openGauss-Libpq-6.0.1-openEuler22.03-x86_64.tar.gz
-rwxr-xr-x. 1 root root   16976 Mar 21 09:27 test
-rw-r--r--. 1 root root    2768 Mar 21 08:39 testlibpq.c
[root@vbox demoproject]#
[root@vbox demoproject]# sudo find / -name "libgssapi_krb5_gauss.so.2"
/usr/local/opengauss/lib/libgssapi_krb5_gauss.so.2
[root@vbox demoproject]# export LD_LIBRARY_PATH=/usr/local/opengauss/lib:$LD_LIBRARY_PATH
[root@vbox demoproject]# echo $LD_LIBRARY_PATH
/usr/local/opengauss/lib:://var/lib/opengauss/c/lib:/var/lib/opengauss/c/demoproject/lib
[root@vbox demoproject]# gcc testlibpq.c -o test -I include   -L lib   -lpq

建立数据库权限

[opengauss@vbox ~]$ gsql -p7654 -r
openGauss=# create user test password 'test_1234';
CREATE ROLE
openGauss=# \q
[opengauss@vbox ~]$ gsql -p7654 -U test -W 'test_1234' -h 127.0.0.1
gsql ((openGauss 6.0.0 build ) compiled at 2024-12-19 00:17:38 commit 0 last mr  release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.

openGauss=>

运行代码

[root@vbox demoproject]# vim testlibpq.c
[root@vbox demoproject]# gcc testlibpq.c -o test -I include   -L lib   -lpq
[root@vbox demoproject]# ./test
datname        datdba         encoding       datcollate     datctype       datistemplate  datallowconn   datconnlimit   datlastsysoid  datfrozenxid   dattablespace  datcompatibilitydatacl         datfrozenxid64 datminmxid

template1      10             7              en_US.UTF-8    en_US.UTF-8    t              t              -1             14893          0              1663           A              {=c/opengauss,opengauss=CTc/opengauss}11565          2
hu             10             7              en_US.UTF-8    en_US.UTF-8    f              t              -1             14893          11210          1663           A                             11210          2
template0      10             7              en_US.UTF-8    en_US.UTF-8    t              f              -1             14893          0              1663           A              {=c/opengauss,opengauss=CTc/opengauss}11210          2
postgres       10             7              en_US.UTF-8    en_US.UTF-8    f              t              -1             14893          0              1663           A                             11920          2
[root@vbox demoproject]#
 

测试代码

/*
 * testlibpq.c
 */

#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 port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";

    /* 连接数据库 */
    conn = PQconnectdb(conninfo);

    /* 检查后端连接成功建立 */
    if (PQstatus(conn) != CONNECTION_OK)
    {
        fprintf(stderr"Connection to database failed: %s",
                PQerrorMessage(conn));
        exit_nicely(conn);
    }

    /*
     * 测试实例涉及游标的使用时候必须使用事务块
     *把全部放在一个  "select * from pg_database"
     * PQexec() 里,过于简单,不推荐使用
     */


    /* 开始一个事务块 */
    res = PQexec(conn, "BEGIN");
    if (PQresultStatus(res) != PGRES_COMMAND_OK)
    {
        fprintf(stderr"BEGIN command failed: %s", PQerrorMessage(conn));
        PQclear(res);
        exit_nicely(conn);
    }

    /*
     * 在结果不需要的时候PQclear PGresult,以避免内存泄漏
     */

    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);

    /* 关闭入口 ... 不用检查错误 ... */
    res = PQexec(conn, "CLOSE myportal");
    PQclear(res);

    /* 结束事务 */
    res = PQexec(conn, "END");
    PQclear(res);

    /* 关闭数据库连接并清理 */
    PQfinish(conn);

    return 0;
}

参考

示例 Libpq | openGauss文档 | openGauss社区

 


文章转载自SmallDB,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论