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>

5. static void
6. exit_nicely(PGconn *conn)
7. {
8. PQfinish(conn);
9. exit(1);
10. }

12. int
13. main(int argc, char **argv)
14. {
15. const char *conninfo;
16. PGconn     *conn;

18. /*
19. * 用户在命令行上提供了conninfo字符串的值时使用该值
20. * 否则环境变量或者所有其它连接参数
21. * 都使用缺省值。
22. */
23. if (argc > 1)
24. conninfo = argv[1];
25. else
26. conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";

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

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

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

42. return 0;
43. }

创建表

1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <libpq-fe.h>

5. static void
6. exit_nicely(PGconn *conn)
7. {
8. PQfinish(conn);
9. exit(1);
10. }

12. int
13. main(int argc, char **argv)
14. {
15. const char *conninfo;
16. PGconn     *conn;
17. PGresult   *res;
18. int         nFields;
19. int         i,j;

21. if (argc > 1)
22. conninfo = argv[1];
23. else
24. conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";

26. conn = PQconnectdb(conninfo);

28. if (PQstatus(conn) != CONNECTION_OK)
29. {
30. fprintf(stderr, "Connection to database failed: %s",
31. PQerrorMessage(conn));
32. exit_nicely(conn);
33. }

35. res = PQexec(conn, "CREATE TABLE customer_t1(c_customer_sk INTEGER, c_customer_name VARCHAR(32))");
36. if (PQresultStatus(res) != PGRES_COMMAND_OK)
37. {
38. fprintf(stderr, "CREATE command failed: %s", PQerrorMessage(conn));
39. PQclear(res);
40. exit_nicely(conn);
41. }

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

46. return 0;
47. }

插入操作

1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <libpq-fe.h>

5. static void
6. exit_nicely(PGconn *conn)
7. {
8. PQfinish(conn);
9. exit(1);
10. }

12. int
13. main(int argc, char **argv)
14. {
15. const char *conninfo;
16. PGconn     *conn;
17. PGresult   *res;

19. if (argc > 1)
20. conninfo = argv[1];
21. else
22. conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";

24. conn = PQconnectdb(conninfo);

26. if (PQstatus(conn) != CONNECTION_OK)
27. {
28. fprintf(stderr, "Connection to database failed: %s",
29. PQerrorMessage(conn));
30. exit_nicely(conn);
31. }

33. res = PQexec(conn, "insert into customer_t1 values(25,'li')");
34. if (PQresultStatus(res) != PGRES_COMMAND_OK)
35. {
36. fprintf(stderr, "INSERT command failed: %s", PQerrorMessage(conn));
37. PQclear(res);
38. exit_nicely(conn);
39. }

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

44. return 0;
45. }

SELECT操作

1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <libpq-fe.h>
4. #include <stdint.h>

6. static void
7. exit_nicely(PGconn *conn)
8. {
9. PQfinish(conn);
10. exit(1);
11. }
12. static void
13. show_binary_results(PGresult *res)
14. {
15. int         i;
16. int         i_fnum,
17. t_fnum;

19. /* 使用 PQfnumber 来避免对结果中的字段顺序进行假设 */
20. i_fnum = PQfnumber(res, "i");
21. t_fnum = PQfnumber(res, "t");

23. for (i = 0; i < PQntuples(res); i++)
24. {
25. char       *iptr;
26. char       *tptr;
27. int         ival;

29. /* 获取字段值(忽略可能为空的可能) */
30. iptr = PQgetvalue(res, i, i_fnum);
31. tptr = PQgetvalue(res, i, t_fnum);

33. /*
34. * INT4 的二进制表现形式是网络字节序
35. * 建议转换成本地字节序
36. */
37. ival = ntohl(*((uint32_t *) iptr));

39. /*
40. * TEXT 的二进制表现形式是文本,因此libpq能够给它附加一个字节零
41. * 把它看做 C 字符串
42. *
43. */

45. printf("tuple %d: got\n", i);
46. printf(" i = (%d bytes) %d\n",
47. PQgetlength(res, i, i_fnum), ival);
48. printf(" t = (%d bytes) '%s'\n",
49. PQgetlength(res, i, t_fnum), tptr);
50. printf("\n\n");
51. }
52. }

54. int
55. main(int argc, char **argv)
56. {
57. const char *conninfo;
58. PGconn     *conn;
59. PGresult   *res;
60. const char *paramValues[1];
61. int        paramLengths[1];
62. int        paramFormats[1];
63. uint32_t   binaryIntVal;

65. if (argc > 1)
66. conninfo = argv[1];
67. else
68. conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";

70. conn = PQconnectdb(conninfo);

72. if (PQstatus(conn) != CONNECTION_OK)
73. {
74. fprintf(stderr, "Connection to database failed: %s",
75. PQerrorMessage(conn));
76. exit_nicely(conn);
77. }

79. /* 把整数值 "2" 转换成网络字节序 */
80. binaryIntVal = htonl((uint32_t) 25);

82. /* 为 PQexecParams 设置参数数组 */
83. paramValues[0] = (char *) &binaryIntVal;
84. paramLengths[0] = sizeof(binaryIntVal);
85. paramFormats[0] = 1;        /* 二进制 */

87. res = PQexecParams(conn,
88. "SELECT * FROM customer_t1 WHERE c_customer_sk = $1::int4",
89. 1,       /* 一个参数 */
90. NULL,    /* 让后端推导参数类型 */
91. paramValues,
92. paramLengths,
93. paramFormats,
94. 1);      /* 要求二进制结果 */

96. if (PQresultStatus(res) != PGRES_TUPLES_OK)
97. {
98. fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
99. PQclear(res);
100. exit_nicely(conn);
101. }

103. show_binary_results(res);

105. PQclear(res);

107. /* 关闭与数据库的连接并清理 */
108. PQfinish(conn);

110. return 0;
111. }

更新操作

1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <libpq-fe.h>

5. static void
6. exit_nicely(PGconn *conn)
7. {
8. PQfinish(conn);
9. exit(1);
10. }

12. int
13. main(int argc, char **argv)
14. {
15. const char *conninfo;
16. PGconn     *conn;
17. PGresult   *res;
18. int         nFields;
19. int         i,j;

21. if (argc > 1)
22. conninfo = argv[1];
23. else
24. conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";

26. conn = PQconnectdb(conninfo);

28. if (PQstatus(conn) != CONNECTION_OK)
29. {
30. fprintf(stderr, "Connection to database failed: %s",
31. PQerrorMessage(conn));
32. exit_nicely(conn);
33. }

35. res = PQexec(conn, "update customer_t1 set c_customer_sk = 1000 where c_customer_name = 'li'");
36. if (PQresultStatus(res) != PGRES_COMMAND_OK)
37. {
38. fprintf(stderr, "UPDATE command failed: %s", PQerrorMessage(conn));
39. PQclear(res);
40. exit_nicely(conn);
41. }

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

46. return 0;
47. }

删除操作

1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <libpq-fe.h>

5. static void
6. exit_nicely(PGconn *conn)
7. {
8. PQfinish(conn);
9. exit(1);
10. }

12. int
13. main(int argc, char **argv)
14. {
15. const char *conninfo;
16. PGconn     *conn;
17. PGresult   *res;
18. int         nFields;
19. int         i,j;

21. if (argc > 1)
22. conninfo = argv[1];
23. else
24. conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";

26. conn = PQconnectdb(conninfo);

28. if (PQstatus(conn) != CONNECTION_OK)
29. {
30. fprintf(stderr, "Connection to database failed: %s",
31. PQerrorMessage(conn));
32. exit_nicely(conn);
33. }

35. res = PQexec(conn, "delete from customer_t1 where c_customer_name = 'li");
36. if (PQresultStatus(res) != PGRES_COMMAND_OK)
37. {
38. fprintf(stderr, "DELETE command failed: %s", PQerrorMessage(conn));
39. PQclear(res);
40. exit_nicely(conn);
41. }

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

46. return 0;
47. }