首页 > 编程语言 >c/c++访问lightdb

c/c++访问lightdb

时间:2022-11-03 16:45:52浏览次数:45  
标签:binary lightdb zjh res fnum bytes c++ 访问 conn

/*
 * src/test/examples/testlibpq3.c
 *
 *
 * testlibpq3.c
 *      Test out-of-line parameters and binary I/O.
 *
 * Before running this, populate a database with the following commands
 * (provided in src/test/examples/testlibpq3.sql):
 *
 * CREATE SCHEMA testlibpq3;
 * SET search_path = testlibpq3;
 * SET standard_conforming_strings = ON;
 * CREATE TABLE test1 (i int4, t text, b bytea);
 * INSERT INTO test1 values (1, 'joe''s place', '\000\001\002\003\004');
 * INSERT INTO test1 values (2, 'ho there', '\004\003\002\001\000');
 *
 * The expected output is:
 *
 * tuple 0: got
 *  i = (4 bytes) 1
 *  t = (11 bytes) 'joe's place'
 *  b = (5 bytes) \000\001\002\003\004
 *
 * tuple 0: got
 *  i = (4 bytes) 2
 *  t = (8 bytes) 'ho there'
 *  b = (5 bytes) \004\003\002\001\000
 */

#ifdef WIN32
#include <windows.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include "libpq-fe.h"

/* for ntohl/htonl */
#include <netinet/in.h>
#include <arpa/inet.h>


static void
exit_nicely(PGconn *conn)
{
    PQfinish(conn);
    exit(1);
}

/*
 * This function prints a query result that is a binary-format fetch from
 * a table defined as in the comment above.  We split it out because the
 * main() function uses it twice.
 */
static void
show_binary_results(PGresult *res)
{
    int         i,
                j;
    int         i_fnum,
                t_fnum,
                b_fnum;

    /* Use PQfnumber to avoid assumptions about field order in result */
    i_fnum = PQfnumber(res, "i");
    t_fnum = PQfnumber(res, "t");
    b_fnum = PQfnumber(res, "b");

    for (i = 0; i < PQntuples(res); i++)
    {
        char       *iptr;
        char       *tptr;
        char       *bptr;
        int         blen;
        int         ival;

        /* Get the field values (we ignore possibility they are null!) */
        iptr = PQgetvalue(res, i, i_fnum);
        tptr = PQgetvalue(res, i, t_fnum);
        bptr = PQgetvalue(res, i, b_fnum);

        /*
         * The binary representation of INT4 is in network byte order, which
         * we'd better coerce to the local byte order.
         */
        ival = ntohl(*((uint32_t *) iptr));

        /*
         * The binary representation of TEXT is, well, text, and since libpq
         * was nice enough to append a zero byte to it, it'll work just fine
         * as a C string.
         *
         * The binary representation of BYTEA is a bunch of bytes, which could
         * include embedded nulls so we have to pay attention to field length.
         */
        blen = PQgetlength(res, i, b_fnum);

        printf("tuple %d: got\n", i);
        printf(" i = (%d bytes) %d\n",
               PQgetlength(res, i, i_fnum), ival);
        printf(" t = (%d bytes) '%s'\n",
               PQgetlength(res, i, t_fnum), tptr);
        printf(" b = (%d bytes) ", blen);
        for (j = 0; j < blen; j++)
            printf("\\%03o", bptr[j]);
        printf("\n\n");
    }
}

int
main(int argc, char **argv)
{
    const char *conninfo;
    PGconn     *conn;
    PGresult   *res;
    const char *paramValues[1];
    int         paramLengths[1];
    int         paramFormats[1];
    uint32_t    binaryIntVal;

    /*
     * If the user supplies a parameter on the command line, use it as the
     * conninfo string; otherwise default to setting dbname=lt_test and using
     * environment variables or defaults for all other connection parameters.
     */
    if (argc > 1)
        conninfo = argv[1];
    else
        conninfo = "dbname = lt_test";

    /* Make a connection to the database */
    conn = PQconnectdb(conninfo);

    /* Check to see that the backend connection was successfully made */
    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, "SET search_path = testlibpq3");
    if (PQresultStatus(res) != PGRES_COMMAND_OK)
    {
        fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
        PQclear(res);
        exit_nicely(conn);
    }
    PQclear(res);

    /*
     * The point of this program is to illustrate use of PQexecParams() with
     * out-of-line parameters, as well as binary transmission of data.
     *
     * This first example transmits the parameters as text, but receives the
     * results in binary format.  By using out-of-line parameters we can avoid
     * a lot of tedious mucking about with quoting and escaping, even though
     * the data is text.  Notice how we don't have to do anything special with
     * the quote mark in the parameter value.
     */

    /* Here is our out-of-line parameter value */
    paramValues[0] = "joe's place";

    res = PQexecParams(conn,
                       "SELECT * FROM test1 WHERE t = $1",
                       1,       /* one param */
                       NULL,    /* let the backend deduce param type */
                       paramValues,
                       NULL,    /* don't need param lengths since text */
                       NULL,    /* default to all text params */
                       1);      /* ask for binary results */

    if (PQresultStatus(res) != PGRES_TUPLES_OK)
    {
        fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
        PQclear(res);
        exit_nicely(conn);
    }

    show_binary_results(res);

    PQclear(res);

    /*
     * In this second example we transmit an integer parameter in binary form,
     * and again retrieve the results in binary form.
     *
     * Although we tell PQexecParams we are letting the backend deduce
     * parameter type, we really force the decision by casting the parameter
     * symbol in the query text.  This is a good safety measure when sending
     * binary parameters.
     */

    /* Convert integer value "2" to network byte order */
    binaryIntVal = htonl((uint32_t) 2);

    /* Set up parameter arrays for PQexecParams */
    paramValues[0] = (char *) &binaryIntVal;
    paramLengths[0] = sizeof(binaryIntVal);
    paramFormats[0] = 1;        /* binary */

    res = PQexecParams(conn,
                       "SELECT * FROM test1 WHERE i = $1::int4",
                       1,       /* one param */
                       NULL,    /* let the backend deduce param type */
                       paramValues,
                       paramLengths,
                       paramFormats,
                       1);      /* ask for binary results */

    if (PQresultStatus(res) != PGRES_TUPLES_OK)
    {
        fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
        PQclear(res);
        exit_nicely(conn);
    }

    show_binary_results(res);

    PQclear(res);

    /* close the connection to the database and cleanup */
    PQfinish(conn);

    return 0;
}

[zjh@hs-10-20-30-193 examples]$ cc -c -I/home/zjh/Sources/postgresql-13.3/src/ testlibpq3.c

[zjh@hs-10-20-30-193 examples]$ cc -o testlibpq3 testlibpq3.o -L/home/zjh/stage/lightdb-x/lib -lpq

zjh@postgres=# CREATE SCHEMA testlibpq3;
\003\002\001\000');CREATE SCHEMA
zjh@postgres=# SET search_path = testlibpq3;
SET
zjh@postgres=# SET standard_conforming_strings = ON;
SET
zjh@postgres=# CREATE TABLE test1 (i int4, t text, b bytea);
CREATE TABLE
zjh@postgres=# INSERT INTO test1 values (1, 'joe''s place', '\000\001\002\003\004');
INSERT 0 1
zjh@postgres=# INSERT INTO test1 values (2, 'ho there', '\004\003\002\001\000');
INSERT 0 1
zjh@postgres=# 
zjh@postgres=# 
zjh@postgres=# 
zjh@postgres=# exit
[zjh@hs-10-20-30-193 examples]$ 
[zjh@hs-10-20-30-193 examples]$ 
[zjh@hs-10-20-30-193 examples]$ 
[zjh@hs-10-20-30-193 examples]$ ./testlibpq3
tuple 0: got
 i = (4 bytes) 1
 t = (11 bytes) 'joe's place'
 b = (5 bytes) \000\001\002\003\004

tuple 0: got
 i = (4 bytes) 2
 t = (8 bytes) 'ho there'
 b = (5 bytes) \004\003\002\001\000

注:因为二进制模式的兼容性和跨平台不是很好,一般来说不建议使用二进制模式,除非大数据量涉及到性能问题。

标签:binary,lightdb,zjh,res,fnum,bytes,c++,访问,conn
From: https://www.cnblogs.com/zhjh256/p/16854838.html

相关文章

  • 微信小程序 图片上传功能可能会遇到的跨域访问图片问题
    小程序里遇到图片跨域访问的问题时,需要在uploadFile合法域名这里添加图片的访问域名就可以了 ......
  • python 创建 dll 到 c++ 调用
    1.如果想要在c++中debug模式调试模式运行,windows下的话,需要安装时安装debug库2.安装cython3.编写pyx文件,例如demo.pyx:#cython:language_level=3cdefpub......
  • c++ 之 const 修饰成员变量、成员函数
     const修饰成员变量、成员函数结论:1、非const成员函数可以调用const成员函数,const成员函数不能调用非const成员函数。2、非const成员函数、const成员函数可以任意访问......
  • K8S环境快速部署Kafka(K8S外部可访问)
    《Ubuntu16环境安装和使用NFS》《K8S使用群晖DS218+的NFS》《K8S的StorageClass实战(NFS)》环境信息本次实战的操作系统和软件的版本信息如下:Kubernetes:1.15......
  • C++浅拷贝与深拷贝
    ​目录 前言一、区别二、浅拷贝1.简单描述2.代码实例三.深拷贝1.简单描述2.代码实例 四.完整代码五.运行结果总结  前言C++中有两种拷贝:深拷贝和浅......
  • C++ 反射机制
    前言反射的概念:指程序在运行时,访问、检测和修改它本身状态或行为的一种能力。wikipedia简单的来说,就是一种自描述和自控制的能力。如果联想到镜子,就可以很好的理解,你能通......
  • 解决局域网内无法访问某个主机的问题
    最近我遇到个问题,我用go语言写了一个服务,然后打开了端口,用局域网内的内网ip访问始终显示400。而用本地环回访问却可以正常访问。可能的原因:1、360安全卫士这款安全软件有......
  • C/C++ 常识
    多态分为静态多态和动态多态1.静态多态:静态多态是编译器在编译期间完成的,编译器会根据实参类型来选择调用合适的函数,如果有合适的函数就调用,没有的话就会发出警告或者......
  • 【c&c++】 cjson使用_Keil环境下Jansson解析库的使用——基于STM32F103
    前言之前我曾经写过几个JSON解析库的使用方法:Qt平台下使用QJson解析和构建JSON字符串使用cJSON库解析JSON使用cJSON库构建JSON对于嵌入式开发,比较常用的就是cJSON解析......
  • 转载文章 c++调用yolov4模型进行目标检测-使用yolov4官方接口
    前言yolo系列用c写的,在工程中的部署特别方便。4月份yolov4横空出世,之前试了试效果,精度确实有了很大的提升,AB大神nb。最近需要在C++项目中使用yolov4,尝试了opencv的调用(见......