libpq

libpq是openGauss C应用程序接口。libpq允许客户程序向openGauss服务器服务进程发送查询并且获得查询返回的库函数。同时也是其他几个openGauss应用接口下面的引擎,如ODBC等依赖的库文件。

libpq使用依赖的头文件

使用libpq的前端程序必须包括头文件libpq-fe.h并且编译时须链接libpq库。

开发流程

编译一个libpq的源程序,需要做下面的一些事情:

  1. 解压相应的发布包(如openGauss-*.*.0-***-64bit-Libpq.tar.gz)文件,其中include文件夹下的头文件为所需的头文件,lib文件夹中为所需的libpq库文件。

    libpq - 图1 说明: 除libpq-fe.h外,include文件夹下默认还存在头文件postgres_ext.h,gs_thread.h,gs_threadlocal.h,这三个头文件是libpq-fe.h的依赖文件。

  2. 包含libpq-fe.h头文件:

    1. #include <libpq-fe.h>
  3. 通过-I_ directory_选项,提供头文件的安装位置(有些时候编译器会查找缺省的目录,因此可以忽略这些选项)。如:

    1. gcc -I (头文件所在目录) -L (libpq库所在目录) testprog.c -lpq
  4. 如果要使用制作文件(makefile),向CPPFLAGS、LDFLAGS、LIBS变量中增加如下选项:

    1. CPPFLAGS += -I (头文件所在目录)
    2. LDFLAGS += -L (libpq库所在目录)
    3. LIBS += -lpq

连接数据库

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <libpq-fe.h>
  4. static void
  5. exit_nicely(PGconn *conn)
  6. {
  7. PQfinish(conn);
  8. exit(1);
  9. }
  10. int
  11. main(int argc, char **argv)
  12. {
  13. const char *conninfo;
  14. PGconn *conn;
  15. /*
  16. * 用户在命令行上提供了conninfo字符串的值时使用该值
  17. * 否则环境变量或者所有其它连接参数
  18. * 都使用缺省值。
  19. */
  20. if (argc > 1)
  21. conninfo = argv[1];
  22. else
  23. conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";
  24. /* 连接数据库 */
  25. conn = PQconnectdb(conninfo);
  26. /* 检查后端连接成功建立 */
  27. if (PQstatus(conn) != CONNECTION_OK)
  28. {
  29. fprintf(stderr, "Connection to database failed: %s",
  30. PQerrorMessage(conn));
  31. exit_nicely(conn);
  32. }
  33. /* 关闭数据库连接并清理 */
  34. PQfinish(conn);
  35. return 0;
  36. }

创建表

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <libpq-fe.h>
  4. static void
  5. exit_nicely(PGconn *conn)
  6. {
  7. PQfinish(conn);
  8. exit(1);
  9. }
  10. int
  11. main(int argc, char **argv)
  12. {
  13. const char *conninfo;
  14. PGconn *conn;
  15. PGresult *res;
  16. int nFields;
  17. int i,j;
  18. if (argc > 1)
  19. conninfo = argv[1];
  20. else
  21. conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";
  22. conn = PQconnectdb(conninfo);
  23. if (PQstatus(conn) != CONNECTION_OK)
  24. {
  25. fprintf(stderr, "Connection to database failed: %s",
  26. PQerrorMessage(conn));
  27. exit_nicely(conn);
  28. }
  29. res = PQexec(conn, "CREATE TABLE customer_t1(c_customer_sk INTEGER, c_customer_name VARCHAR(32))");
  30. if (PQresultStatus(res) != PGRES_COMMAND_OK)
  31. {
  32. fprintf(stderr, "CREATE command failed: %s", PQerrorMessage(conn));
  33. PQclear(res);
  34. exit_nicely(conn);
  35. }
  36. /* 关闭数据库连接并清理 */
  37. PQfinish(conn);
  38. return 0;
  39. }

插入操作

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <libpq-fe.h>
  4. static void
  5. exit_nicely(PGconn *conn)
  6. {
  7. PQfinish(conn);
  8. exit(1);
  9. }
  10. int
  11. main(int argc, char **argv)
  12. {
  13. const char *conninfo;
  14. PGconn *conn;
  15. PGresult *res;
  16. if (argc > 1)
  17. conninfo = argv[1];
  18. else
  19. conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";
  20. conn = PQconnectdb(conninfo);
  21. if (PQstatus(conn) != CONNECTION_OK)
  22. {
  23. fprintf(stderr, "Connection to database failed: %s",
  24. PQerrorMessage(conn));
  25. exit_nicely(conn);
  26. }
  27. res = PQexec(conn, "insert into customer_t1 values(25,'li')");
  28. if (PQresultStatus(res) != PGRES_COMMAND_OK)
  29. {
  30. fprintf(stderr, "INSERT command failed: %s", PQerrorMessage(conn));
  31. PQclear(res);
  32. exit_nicely(conn);
  33. }
  34. /* 关闭数据库连接并清理 */
  35. PQfinish(conn);
  36. return 0;
  37. }

SELECT操作

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <libpq-fe.h>
  4. #include <stdint.h>
  5. static void
  6. exit_nicely(PGconn *conn)
  7. {
  8. PQfinish(conn);
  9. exit(1);
  10. }
  11. static void
  12. show_binary_results(PGresult *res)
  13. {
  14. int i;
  15. int i_fnum,
  16. t_fnum;
  17. /* 使用 PQfnumber 来避免对结果中的字段顺序进行假设 */
  18. i_fnum = PQfnumber(res, "i");
  19. t_fnum = PQfnumber(res, "t");
  20. for (i = 0; i < PQntuples(res); i++)
  21. {
  22. char *iptr;
  23. char *tptr;
  24. int ival;
  25. /* 获取字段值(忽略可能为空的可能) */
  26. iptr = PQgetvalue(res, i, i_fnum);
  27. tptr = PQgetvalue(res, i, t_fnum);
  28. /*
  29. * INT4 的二进制表现形式是网络字节序
  30. * 建议转换成本地字节序
  31. */
  32. ival = ntohl(*((uint32_t *) iptr));
  33. /*
  34. * TEXT 的二进制表现形式是文本,因此libpq能够给它附加一个字节零
  35. * 把它看做 C 字符串
  36. *
  37. */
  38. printf("tuple %d: got\n", i);
  39. printf(" i = (%d bytes) %d\n",
  40. PQgetlength(res, i, i_fnum), ival);
  41. printf(" t = (%d bytes) '%s'\n",
  42. PQgetlength(res, i, t_fnum), tptr);
  43. printf("\n\n");
  44. }
  45. }
  46. int
  47. main(int argc, char **argv)
  48. {
  49. const char *conninfo;
  50. PGconn *conn;
  51. PGresult *res;
  52. const char *paramValues[1];
  53. int paramLengths[1];
  54. int paramFormats[1];
  55. uint32_t binaryIntVal;
  56. if (argc > 1)
  57. conninfo = argv[1];
  58. else
  59. conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";
  60. conn = PQconnectdb(conninfo);
  61. if (PQstatus(conn) != CONNECTION_OK)
  62. {
  63. fprintf(stderr, "Connection to database failed: %s",
  64. PQerrorMessage(conn));
  65. exit_nicely(conn);
  66. }
  67. /* 把整数值 "2" 转换成网络字节序 */
  68. binaryIntVal = htonl((uint32_t) 25);
  69. /* 为 PQexecParams 设置参数数组 */
  70. paramValues[0] = (char *) &binaryIntVal;
  71. paramLengths[0] = sizeof(binaryIntVal);
  72. paramFormats[0] = 1; /* 二进制 */
  73. res = PQexecParams(conn,
  74. "SELECT * FROM customer_t1 WHERE c_customer_sk = $1::int4",
  75. 1, /* 一个参数 */
  76. NULL, /* 让后端推导参数类型 */
  77. paramValues,
  78. paramLengths,
  79. paramFormats,
  80. 1); /* 要求二进制结果 */
  81. if (PQresultStatus(res) != PGRES_TUPLES_OK)
  82. {
  83. fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
  84. PQclear(res);
  85. exit_nicely(conn);
  86. }
  87. show_binary_results(res);
  88. PQclear(res);
  89. /* 关闭与数据库的连接并清理 */
  90. PQfinish(conn);
  91. return 0;
  92. }

更新操作

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <libpq-fe.h>
  4. static void
  5. exit_nicely(PGconn *conn)
  6. {
  7. PQfinish(conn);
  8. exit(1);
  9. }
  10. int
  11. main(int argc, char **argv)
  12. {
  13. const char *conninfo;
  14. PGconn *conn;
  15. PGresult *res;
  16. int nFields;
  17. int i,j;
  18. if (argc > 1)
  19. conninfo = argv[1];
  20. else
  21. conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";
  22. conn = PQconnectdb(conninfo);
  23. if (PQstatus(conn) != CONNECTION_OK)
  24. {
  25. fprintf(stderr, "Connection to database failed: %s",
  26. PQerrorMessage(conn));
  27. exit_nicely(conn);
  28. }
  29. res = PQexec(conn, "update customer_t1 set c_customer_sk = 1000 where c_customer_name = 'li'");
  30. if (PQresultStatus(res) != PGRES_COMMAND_OK)
  31. {
  32. fprintf(stderr, "UPDATE command failed: %s", PQerrorMessage(conn));
  33. PQclear(res);
  34. exit_nicely(conn);
  35. }
  36. /* 关闭数据库连接并清理 */
  37. PQfinish(conn);
  38. return 0;
  39. }

删除操作

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <libpq-fe.h>
  4. static void
  5. exit_nicely(PGconn *conn)
  6. {
  7. PQfinish(conn);
  8. exit(1);
  9. }
  10. int
  11. main(int argc, char **argv)
  12. {
  13. const char *conninfo;
  14. PGconn *conn;
  15. PGresult *res;
  16. int nFields;
  17. int i,j;
  18. if (argc > 1)
  19. conninfo = argv[1];
  20. else
  21. conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";
  22. conn = PQconnectdb(conninfo);
  23. if (PQstatus(conn) != CONNECTION_OK)
  24. {
  25. fprintf(stderr, "Connection to database failed: %s",
  26. PQerrorMessage(conn));
  27. exit_nicely(conn);
  28. }
  29. res = PQexec(conn, "delete from customer_t1 where c_customer_name = 'li");
  30. if (PQresultStatus(res) != PGRES_COMMAND_OK)
  31. {
  32. fprintf(stderr, "DELETE command failed: %s", PQerrorMessage(conn));
  33. PQclear(res);
  34. exit_nicely(conn);
  35. }
  36. /* 关闭数据库连接并清理 */
  37. PQfinish(conn);
  38. return 0;
  39. }