libpq
libpq是openGauss C应用程序接口。libpq允许客户程序向openGauss服务器服务进程发送查询并且获得查询返回的库函数。同时也是其他几个openGauss应用接口下面的引擎,如ODBC等依赖的库文件。
libpq使用依赖的头文件
使用libpq的前端程序必须包括头文件libpq-fe.h并且编译时须链接libpq库。
开发流程
编译一个libpq的源程序,需要做下面的一些事情:
- 解压相应的发布包(如openGauss-*.*.0-***-64bit-Libpq.tar.gz)文件,其中include文件夹下的头文件为所需的头文件,lib文件夹中为所需的libpq库文件。
说明: 除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='xxxxxx'";
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='xxxxxx'";
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='xxxxxx'";
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='xxxxxx'";
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='xxxxxx'";
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='xxxxxx'";
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. }
说明: 除libpq-fe.h外,include文件夹下默认还存在头文件postgres_ext.h,gs_thread.h,gs_threadlocal.h,这三个头文件是libpq-fe.h的依赖文件。
2. 包含libpq-fe.h头文件: