libpq_test.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. // libpq_test.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include "libpq_test.h"
  5. #ifdef _DEBUG
  6. #define new DEBUG_NEW
  7. #endif
  8. // 唯一的应用程序对象
  9. CWinApp theApp;
  10. using namespace std;
  11. static void exit_nicely(PGconn *conn)
  12. {
  13. PQfinish(conn);
  14. exit(EXIT_SUCCESS);
  15. }
  16. /************************************************************************/
  17. /* 函数:[1/10/2018 Jeff];
  18. /* 描述:;
  19. /* 参数:;
  20. /* [IN] pHost:数据库主机地址;
  21. /* [IN] pPort:数据库端口号;
  22. /* [IN] pUser:数据库用户名;
  23. /* [IN] pPsw:数据库密码;
  24. /* [IN] pDbName:数据库名;
  25. /* [OUT] :;
  26. /* [IN/OUT] :;
  27. /* 返回:void;
  28. /* 注意:;
  29. /* 示例:;
  30. /*
  31. /* 修改:;
  32. /* 日期:;
  33. /* 内容:;
  34. /************************************************************************/
  35. static PGconn* connection_psql(const char *pHost, const char *pPort, const char* pUser, const char* pPsw, const char* pDbName)
  36. {
  37. if ( pHost == NULL || pPort == NULL || pUser == NULL || pPsw == NULL ||pDbName == NULL )
  38. return NULL;
  39. //PGconn *conn = NULL;
  40. char conninfo[1024] = {0};
  41. // postgresql://[user[:password]@][netlocation][:port][/dbname][?param1=value1&...] // 如果密码包含@则连接不通;
  42. // _stprintf(conninfo, _T("postgresql://postgres:%s@%s:%s/%s"),pUser, pPsw, pHost, pPort, pDbName);
  43. sprintf_s(conninfo, "dbname=%s user=%s password=%s host=%s port=%s", pDbName, pUser, pPsw, pHost, pPort);
  44. return PQconnectdb(conninfo);
  45. }
  46. static PGconn* connection_psql2(const char *pHost, const char *pPort, const char* pUser, const char* pPsw, const char* pDbName)
  47. {
  48. if ( pHost == NULL || pPort == NULL || pUser == NULL || pPsw == NULL ||pDbName == NULL )
  49. return NULL;
  50. // 必须以NULL结束;
  51. const char *keywords[] = {"dbname","user","password","host","port", NULL};
  52. const char *values[] = {pDbName,pUser,pPsw,pHost,pPort,NULL};
  53. return PQconnectdbParams(keywords, values, 0);
  54. }
  55. static PGconn* connection_psql3(const char *pHost, const char *pPort, const char* pUser, const char* pPsw, const char* pDbName)
  56. {
  57. if ( pHost == NULL || pPort == NULL || pUser == NULL || pPsw == NULL ||pDbName == NULL )
  58. return NULL;
  59. // 可以连接;
  60. return PQsetdbLogin(pHost,pPort,"","",pDbName,pUser,pPsw);
  61. }
  62. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  63. {
  64. int nRetCode = 0;
  65. // 初始化 MFC 并在失败时显示错误
  66. if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
  67. {
  68. // TODO: 更改错误代码以符合您的需要
  69. _tprintf(_T("错误: MFC 初始化失败\n"));
  70. nRetCode = 1;
  71. }
  72. else
  73. {
  74. // TODO: 在此处为应用程序的行为编写代码。
  75. char *pghost = NULL, *pgport = NULL, *pgoptions = NULL, *pgtty = NULL;
  76. char *dbName = NULL;
  77. PGconn *conn = NULL;
  78. PGresult *res = NULL;
  79. int nFields;
  80. int i = 0,j = 0;
  81. #ifdef DEBUG
  82. FILE *debug;
  83. #endif /* DEBUG */
  84. /*
  85. * Begin by setting the parameters for a backend connection.
  86. * If the parameters are NULL, the system tries to use
  87. * reasonable defaults by looking up environment variables
  88. * or, failing that, using hardwired constants.
  89. */
  90. conn = connection_psql2("itcivilian.vicp.io", "5432", "postgres", "postgres@851208", "test");
  91. // ## 连接数据,有三个函数可以使用:PQconnectdb,PQconnectdbParams,PQsetdbLogin
  92. #if 0 // 密码带@字符的问题未解决;
  93. // URI 的一般形式是:
  94. // postgresql://[user[:password]@][netlocation][:port][/dbname][?param1=value1&...]
  95. //const char *conninfo="postgresql://postgres:postgres@851208@itcivilian.vicp.io:5432/test";
  96. const char *conninfo="postgresql://dbname=test&host=itcivilian.vicp.io&port=5432&user=postgres&password='postgres@851208'";
  97. /* make a connection to the database */
  98. //conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
  99. conn = PQconnectdb(conninfo);
  100. #endif
  101. #if 0
  102. // 可以连接;
  103. const char *conninfo="dbname=test user=postgres password=postgres@851208 host=itcivilian.vicp.io port=5432";
  104. /* make a connection to the database */
  105. //conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
  106. conn = PQconnectdb(conninfo);
  107. #endif
  108. #if 0
  109. // 可以连接;
  110. const char *keywords[] = {"dbname","user","password","host","port", NULL};
  111. const char *values[] = {"test","postgres","postgres@851208","itcivilian.vicp.io","5432",NULL};
  112. conn = PQconnectdbParams(keywords, values, 0);
  113. #endif
  114. #if 0
  115. // 可以连接;
  116. conn = PQsetdbLogin("itcivilian.vicp.io",
  117. "5432",
  118. "",
  119. "",
  120. "test",
  121. "postgres",
  122. "postgres@851208");
  123. // 设置客户端的编码格式 ;
  124. PQsetClientEncoding(conn,"GBK");
  125. #endif
  126. // 返回数据库名称;
  127. char *pDbName = PQdb(conn);
  128. printf("数据库名:%s\n", pDbName);
  129. // 返回的用户名;
  130. char *pUser = PQuser(conn);
  131. printf("用户名:%s\n", pUser);
  132. // 返回的密码;
  133. char *pPsw = PQpass(conn);
  134. printf("密码:%s\n", pPsw);
  135. // 服务器主机名;
  136. char *pHost = PQhost(conn);
  137. printf("服务器主机名:%s\n", pHost);
  138. // 端口号;
  139. char *pPort = PQport(conn);
  140. printf("端口号:%s\n", pPort);
  141. // 查看当前服务器的参数设置;
  142. printf("服务端版本号=%s,\n服务端编码格式=%s,\n客户端编码格式=%s,\n%s,\n%s,\n%s,\n%s,\n%s",
  143. PQparameterStatus(conn,"server_version"),
  144. PQparameterStatus(conn,"server_encoding"),
  145. PQparameterStatus(conn,"client_encoding"),
  146. PQparameterStatus(conn,"session_authorization"),
  147. PQparameterStatus(conn,"DateStyle"),
  148. PQparameterStatus(conn,"TimeZone"),
  149. PQparameterStatus(conn,"integer_datetimes"),
  150. PQparameterStatus(conn,"standard_conforming_strings")
  151. );
  152. // 判断conn的连接状态是否有效;
  153. /* check to see that the backend connection was successfully made */
  154. if (PQstatus(conn) == CONNECTION_BAD)
  155. {
  156. fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
  157. fprintf(stderr, "%s", PQerrorMessage(conn));
  158. system("pause");
  159. exit_nicely(conn);
  160. }
  161. #ifdef DEBUG
  162. debug = fopen("/tmp/trace.out", "w");
  163. PQtrace(conn, debug);
  164. #endif /* DEBUG */
  165. // ###开启事件;
  166. /* start a transaction block */
  167. res = PQexec(conn, "BEGIN");
  168. if (PQresultStatus(res) != PGRES_COMMAND_OK)
  169. {
  170. fprintf(stderr, "BEGIN command failed\n");
  171. PQclear(res);
  172. system("pause");
  173. exit_nicely(conn);
  174. }
  175. /*
  176. * should PQclear PGresult whenever it is no longer needed
  177. * so as to avoid memory leaks
  178. */
  179. PQclear(res);
  180. /*
  181. * fetch instances from the pg_database, the system catalog of
  182. * databases
  183. */
  184. res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database");
  185. if (PQresultStatus(res) != PGRES_COMMAND_OK)
  186. {
  187. fprintf(stderr, "DECLARE CURSOR command failed\n");
  188. PQclear(res);
  189. system("pause");
  190. exit_nicely(conn);
  191. }
  192. PQclear(res);
  193. res = PQexec(conn, "FETCH ALL in myportal");
  194. if (PQresultStatus(res) != PGRES_TUPLES_OK)
  195. {
  196. fprintf(stderr, "FETCH ALL command didn't return tuples properly\n");
  197. PQclear(res);
  198. system("pause");
  199. exit_nicely(conn);
  200. }
  201. /* first, print out the attribute names */
  202. nFields = PQnfields(res);
  203. for (i = 0; i < nFields; i++)
  204. printf("%-15s", PQfname(res, i));
  205. printf("\n\n");
  206. /* next, print out the instances */
  207. for (i = 0; i < PQntuples(res); i++)
  208. {
  209. for (j = 0; j < nFields; j++)
  210. printf("%-15s", PQgetvalue(res, i, j));
  211. printf("\n");
  212. }
  213. PQclear(res);
  214. /* close the portal */
  215. res = PQexec(conn, "CLOSE myportal");
  216. PQclear(res);
  217. // ###结束事务;
  218. /* end the transaction */
  219. res = PQexec(conn, "END");
  220. PQclear(res);
  221. /* close the connection to the database and cleanup */
  222. PQfinish(conn);
  223. #ifdef DEBUG
  224. if (debug)
  225. fclose(debug);
  226. #endif /* DEBUG */
  227. system("pause");
  228. }
  229. return nRetCode;
  230. }