没办法,有些c系场合不适宜用.Net/Java之类,尽管有胶水python,但其c/c++的扩展方式确有许多蛋疼之处,所以不如直接上马。相对与mysql哪怕sqlite之辈,postgresql在c接口上维护地非常好,但是却极其低调。尽管之后由libpqxx,但其trac站点似乎总是有问题,版本也没有一直在维护。因此使用自带的libpq是相对明智的选择。
由于在OSX下,本地一直用的postgresapp,而非官方安装包,因此lib或include的安装路径当然与官方文档上不一致,而是都在Postgres.app的包里边:
Default data directory: ~/Library/Application Support/Postgres/var-9.3
Binaries: /Applications/Postgres.app/Contents/Versions/9.3/bin
Headers: /Applications/Postgres.app/Contents/Versions/9.3/include
Libraries: /Applications/Postgres.app/Contents/Versions/9.3/lib
Man pages: /Applications/Postgres.app/Contents/Versions/9.3/share
不是很勤快,所以用的还是9.3。显而易见地,我们需要告诉编译器如何include头文件和link必须的lib,因此g++需要知道这些参数:
-I /Applications/Postgres.app/Contents/Versions/9.3/include -L /Applications/Postgres.app/Contents/Versions/9.3/lib -lpq
然后就是代码了,必须承认,写惯了python的人真的受不了如此繁琐的写法,但严谨些至少让人萌生敬意。下面用个简单官方sample简单改了一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
int handleSomething(){ const char* conninfo="dbname='***' user='***' host='****' password='**'"; PGconn *conn; PGresult *res; conn = PQconnectdb(conninfo); if(PQstatus(conn)!=CONNECTION_OK){ fprintf(stderr,"Connection to database failed: %s",PQerrorMessage(conn)); PQfinish(conn); exit(1); } res = PQexec(conn,"select * from table ..."); int nFields; nFields = PQnfields(res); for (int i = 0; i < nFields; i++) printf("%-15s", PQfname(res, i)); printf("nn"); for (int i = 0; i < PQntuples(res); i++) { printf("%s", PQgetvalue(res, i, 1)); printf("n"); } PQclear(res); PQfinish(conn); return 0; } |
稍显怪异,习惯了就好。