pginterface.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:5k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*
  2.  * pginterface.c
  3.  *
  4. */
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <stdarg.h>
  8. #include <libpq-fe.h>
  9. #include "halt.h"
  10. #include "pginterface.h"
  11. #define NUL ''
  12. #ifndef TRUE
  13. #define TRUE 1
  14. #endif
  15. #ifndef FALSE
  16. #define FALSE 0
  17. #endif
  18. /* GLOBAL VARIABLES */
  19. static PGconn *conn;
  20. static PGresult *res = NULL;
  21. #define ON_ERROR_STOP 0
  22. #define ON_ERROR_CONTINUE 1
  23. static int on_error_state = ON_ERROR_STOP;
  24. static in_result_block = FALSE;
  25. static was_get_unset_result = FALSE;
  26. /* LOCAL VARIABLES */
  27. static int tuple;
  28. /*
  29. **
  30. ** connectdb - returns PGconn structure
  31. **
  32. */
  33. PGconn *
  34. connectdb(char *dbName,
  35.   char *pghost,
  36.   char *pgport,
  37.   char *pgoptions,
  38.   char *pgtty)
  39. {
  40. /* make a connection to the database */
  41. conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
  42. if (PQstatus(conn) == CONNECTION_BAD)
  43. halt("Connection to database '%s' failed.n%sn", dbName,
  44.  PQerrorMessage(conn));
  45. return conn;
  46. }
  47. /*
  48. **
  49. ** disconnectdb
  50. **
  51. */
  52. void
  53. disconnectdb()
  54. {
  55. PQfinish(conn);
  56. }
  57. /*
  58. **
  59. ** doquery - returns PGresult structure
  60. **
  61. */
  62. PGresult   *
  63. doquery(char *query)
  64. {
  65. if (res != NULL && in_result_block == FALSE && was_get_unset_result == FALSE)
  66. PQclear(res);
  67. was_get_unset_result = FALSE;
  68. res = PQexec(conn, query);
  69. if (on_error_state == ON_ERROR_STOP &&
  70. (res == NULL ||
  71.  PQresultStatus(res) == PGRES_BAD_RESPONSE ||
  72.  PQresultStatus(res) == PGRES_NONFATAL_ERROR ||
  73.  PQresultStatus(res) == PGRES_FATAL_ERROR))
  74. {
  75. if (res != NULL)
  76. fprintf(stderr, "query error:  %sn", PQcmdStatus(res));
  77. else
  78. fprintf(stderr, "connection error:  %sn", PQerrorMessage(conn));
  79. PQfinish(conn);
  80. halt("failed request:  %sn", query);
  81. }
  82. tuple = 0;
  83. return res;
  84. }
  85. /*
  86. **
  87. ** fetch - returns tuple number (starts at 0), or the value END_OF_TUPLES
  88. ** NULL pointers are skipped
  89. **
  90. */
  91. int
  92. fetch(void *param,...)
  93. {
  94. va_list ap;
  95. int arg,
  96. num_fields;
  97. num_fields = PQnfields(res);
  98. if (tuple >= PQntuples(res))
  99. return END_OF_TUPLES;
  100. va_start(ap, param);
  101. for (arg = 0; arg < num_fields; arg++)
  102. {
  103. if (param != NULL)
  104. {
  105. if (PQfsize(res, arg) == -1)
  106. {
  107. memcpy(param, PQgetvalue(res, tuple, arg), PQgetlength(res, tuple, arg));
  108. ((char *) param)[PQgetlength(res, tuple, arg)] = NUL;
  109. }
  110. else
  111. memcpy(param, PQgetvalue(res, tuple, arg), PQfsize(res, arg));
  112. }
  113. param = va_arg(ap, char *);
  114. }
  115. va_end(ap);
  116. return tuple++;
  117. }
  118. /*
  119. **
  120. ** fetchwithnulls - returns tuple number (starts at 0),
  121. ** or the value END_OF_TUPLES
  122. ** Returns TRUE or FALSE into null indicator variables
  123. ** NULL pointers are skipped
  124. */
  125. int
  126. fetchwithnulls(void *param,...)
  127. {
  128. va_list ap;
  129. int arg,
  130. num_fields;
  131. num_fields = PQnfields(res);
  132. if (tuple >= PQntuples(res))
  133. return END_OF_TUPLES;
  134. va_start(ap, param);
  135. for (arg = 0; arg < num_fields; arg++)
  136. {
  137. if (param != NULL)
  138. {
  139. if (PQfsize(res, arg) == -1)
  140. {
  141. memcpy(param, PQgetvalue(res, tuple, arg), PQgetlength(res, tuple, arg));
  142. ((char *) param)[PQgetlength(res, tuple, arg)] = NUL;
  143. }
  144. else
  145. memcpy(param, PQgetvalue(res, tuple, arg), PQfsize(res, arg));
  146. }
  147. param = va_arg(ap, char *);
  148. if (PQgetisnull(res, tuple, arg) != 0)
  149. *(int *) param = 1;
  150. else
  151. *(int *) param = 0;
  152. param = va_arg(ap, char *);
  153. }
  154. va_end(ap);
  155. return tuple++;
  156. }
  157. /*
  158. **
  159. ** on_error_stop
  160. **
  161. */
  162. void
  163. on_error_stop()
  164. {
  165. on_error_state = ON_ERROR_STOP;
  166. }
  167. /*
  168. **
  169. ** on_error_continue
  170. **
  171. */
  172. void
  173. on_error_continue()
  174. {
  175. on_error_state = ON_ERROR_CONTINUE;
  176. }
  177. /*
  178. **
  179. ** get_result
  180. **
  181. */
  182. PGresult   *
  183. get_result()
  184. {
  185. char    *cmdstatus = PQcmdStatus(res);
  186. was_get_unset_result = TRUE;
  187. /* we have to store the fetch location somewhere */
  188. cmdstatus[0] = NUL;
  189. memcpy(&cmdstatus[1], &tuple, sizeof(tuple));
  190. return res;
  191. }
  192. /*
  193. **
  194. ** set_result
  195. **
  196. */
  197. void
  198. set_result(PGresult *newres)
  199. {
  200. char    *cmdstatus = PQcmdStatus(res);
  201. if (newres == NULL)
  202. halt("set_result called with null result pointern");
  203. if (res != NULL && was_get_unset_result == FALSE)
  204. if (in_result_block == FALSE)
  205. PQclear(res);
  206. else
  207. {
  208. cmdstatus[0] = NUL;
  209. memcpy(&cmdstatus[1], &tuple, sizeof(tuple));
  210. }
  211. in_result_block = TRUE;
  212. was_get_unset_result = FALSE;
  213. cmdstatus = PQcmdStatus(newres);
  214. memcpy(&tuple, &cmdstatus[1], sizeof(tuple));
  215. res = newres;
  216. }
  217. /*
  218. **
  219. ** unset_result
  220. **
  221. */
  222. void
  223. unset_result(PGresult *oldres)
  224. {
  225. char    *cmdstatus = PQcmdStatus(oldres);
  226. if (oldres == NULL)
  227. halt("unset_result called with null result pointern");
  228. if (in_result_block == FALSE)
  229. halt("Unset of result without being set.n");
  230. was_get_unset_result = TRUE;
  231. cmdstatus[0] = NUL;
  232. memcpy(&cmdstatus[1], &tuple, sizeof(tuple));
  233. in_result_block = FALSE;
  234. }
  235. /*
  236. **
  237. ** reset_fetch
  238. **
  239. */
  240. void
  241. reset_fetch()
  242. {
  243. tuple = 0;
  244. }