对于 PostgreSQL 的 C 语言编程,可以直接使用 libpq 库,这里简单介绍其使用方法。
libpq
在 CentOS 中,处理通过源码编译安装之外,还可以安装 postgresqlXX-devel
包,然后可以通过如下的方式进行编译。
$ pg_config --includedir
$ pg_config --libdir
$ gcc -I/usr/pgsql-9.2/include/ -L/usr/pgsql-9.2/lib/ -lpq -o version version.c
如下是一个常见操作的示例集合。
#include <stdio.h>
#include <stdlib.h>
#include <libpq-fe.h>
int main()
{
int ver, i;
PGconn *conn;
PGresult *res;
/* Get the libpq library version. */
ver = PQlibVersion();
printf("Libpq version: %d\n", ver);
/* Connect to PostgreSQL with default user and database. */
conn = PQconnectdb("user=postgres dbname=postgres");
if (PQstatus(conn) == CONNECTION_BAD) {
fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(conn));
PQfinish(conn);
exit(EXIT_FAILURE);
}
/* Get the connection infomation */
printf("User: %s\n", PQuser(conn));
printf("Database name: %s\n", PQdb(conn));
printf("Password: %s\n", PQpass(conn));
/* Get the server version */
ver = PQserverVersion(conn);
printf("Server version: %d\n", ver);
/* Retrieve the server version again with different method */
res = PQexec(conn, "SELECT VERSION()");
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
fprintf(stderr, "No data retrieved\n");
PQclear(res);
PQfinish(conn);
exit(EXIT_FAILURE);
}
printf("Current version: %s\n", PQgetvalue(res, 0, 0));
PQclear(res);
/* Create a table, and insert some data */
res = PQexec(conn, "DROP TABLE IF EXISTS foobar");
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
fprintf(stderr, "Drop table failed: %s\n", PQerrorMessage(conn));
PQclear(res);
PQfinish(conn);
exit(EXIT_FAILURE);
}
PQclear(res); /* Free the result */
res = PQexec(conn, "CREATE TABLE foobar(id INTEGER PRIMARY KEY, name VARCHAR(32))");
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
fprintf(stderr, "Create table failed: %s\n", PQerrorMessage(conn));
PQclear(res);
PQfinish(conn);
exit(EXIT_FAILURE);
}
PQclear(res);
res = PQexec(conn, "INSERT INTO foobar VALUES(1, 'Audi'),(2, 'Volvo')");
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
fprintf(stderr, "Insert into table failed: %s\n", PQerrorMessage(conn));
PQclear(res);
PQfinish(conn);
exit(EXIT_FAILURE);
}
PQclear(res);
/* Retrieve multiple rows of data and also it's metadata */
res = PQexec(conn, "SELECT * FROM foobar LIMIT 5");
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
fprintf(stderr, "No data retrieved\n");
PQclear(res);
PQfinish(conn);
exit(EXIT_FAILURE);
}
int ncols = PQnfields(res);
printf("There are %d columns:\n", ncols);
for (i = 0; i < ncols; i++)
printf("col #%d: %s\n", i, PQfname(res, i));
for(i = 0; i < PQntuples(res); i++) /* another way */
printf("line #%d: %s %s\n", i, PQgetvalue(res, i, 0), PQgetvalue(res, i, 1));
PQclear(res);
/* Prepared statements */
const char *params[1] = { "1" };
char *stm = "SELECT * FROM foobar WHERE Id=$1";
res = PQexecParams(conn, stm, 1, NULL, params, NULL, NULL, 0);
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
fprintf(stderr, "No data retrieved\n");
PQclear(res);
PQfinish(conn);
exit(EXIT_FAILURE);
}
printf("Data: %s %s\n", PQgetvalue(res, 0, 0), PQgetvalue(res, 0, 1));
PQclear(res);
/* Transaction */
res = PQexec(conn, "BEGIN");
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
fprintf(stderr, "BEGIN command failed\n");
PQclear(res);
PQfinish(conn);
exit(EXIT_FAILURE);
}
PQclear(res);
res = PQexec(conn, "UPDATE foobar SET name='Mercedes' WHERE id=1");
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
fprintf(stderr, "UPDATE command failed\n");
PQclear(res);
PQfinish(conn);
exit(EXIT_FAILURE);
}
/* Maybe more statements */
res = PQexec(conn, "COMMIT");
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
fprintf(stderr, "COMMIT command failed\n");
PQclear(res);
PQfinish(conn);
exit(EXIT_FAILURE);
}
PQclear(res);
PQfinish(conn);
return 0;
}
pgcenter
pgcenter 是一个 PG 终端的监控工具,但又不仅仅是监控工具,还提供了一些快速访问功能,例如编辑配置文件、重载配置、查看日志文件等。
可以直接查看 github.com/lesovsky/pgcenter,实际上很多的查询 SQL 是在 pg-utils 。
----- 安装依赖库
# yum install ncurses-devel postgresql-devel
----- 直接编译、安装
# make && make install
----- 登陆查看当前的状态
$ pgcenter -h <host> -p <port> -U <user> -d <dbname>
$ pgcenter -h 127.1 -p 5432 -U postgres -d postgres
参考
另外常用的 C 语言组件还有 libzdb、pgpool (提供连接池+负载均衡)、pgbouncer (只有连接池)。
关于 C 语言编程,可以参考 libpq 、libpq-example 。