db_val.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /*
  2. * $Id$
  3. *
  4. * POSTGRES module, portions of this code were templated using
  5. * the mysql module, thus it's similarity.
  6. *
  7. *
  8. * Copyright (C) 2003 August.Net Services, LLC
  9. *
  10. * This file is part of ser, a free SIP server.
  11. *
  12. * ser is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation; either version 2 of the License, or
  15. * (at your option) any later version
  16. *
  17. * For a license to use the ser software under conditions
  18. * other than those described here, or to purchase support for this
  19. * software, please contact iptel.org by e-mail at the following addresses:
  20. * [email protected]
  21. *
  22. * ser is distributed in the hope that it will be useful,
  23. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25. * GNU General Public License for more details.
  26. *
  27. * You should have received a copy of the GNU General Public License
  28. * along with this program; if not, write to the Free Software
  29. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  30. *
  31. * ---
  32. *
  33. * History
  34. * -------
  35. * 2003-04-06 initial code written (Greg Fausak/Andy Fullford)
  36. * 2003-04-14 gmtime changed to localtime because mktime later
  37. * expects localtime, changed daylight saving bug
  38. * previously found in mysql module (janakj)
  39. *
  40. */
  41. #include <stdlib.h>
  42. #include <stdio.h>
  43. #include <string.h>
  44. #include "../../db/db_val.h"
  45. #include "../../dprint.h"
  46. #include "defs.h"
  47. #include "db_utils.h"
  48. #include "con_postgres.h"
  49. #include "aug_std.h"
  50. char *strptime(const char *s, const char *format, struct tm *tm);
  51. /*
  52. * Convert a string to integer
  53. */
  54. static inline int str2int(const char* _s, int* _v)
  55. {
  56. #ifdef PARANOID
  57. if ((!_s) || (!_v)) {
  58. LOG(L_ERR, "str2int(): Invalid parameter value\n");
  59. return -1;
  60. }
  61. #endif
  62. *_v = atoi(_s);
  63. return 0;
  64. }
  65. /*
  66. * Convert a string to double
  67. */
  68. static inline int str2double(const char* _s, double* _v)
  69. {
  70. #ifdef PARANOID
  71. if ((!_s) || (!_v)) {
  72. LOG(L_ERR, "str2double(): Invalid parameter value\n");
  73. return -1;
  74. }
  75. #endif
  76. *_v = atof(_s);
  77. return 0;
  78. }
  79. /*
  80. * Convert a string to time_t
  81. */
  82. static inline int str2time(const char* _s, time_t* _v)
  83. {
  84. struct tm t;
  85. #ifdef PARANOID
  86. if ((!_s) || (!_v)) {
  87. LOG(L_ERR, "str2time(): Invalid parameter value\n");
  88. return -1;
  89. }
  90. #endif
  91. memset(&t, '\0', sizeof(struct tm));
  92. strptime(_s,"%Y-%m-%d %H:%M:%S %z",&t);
  93. /* Daylight saving information got lost in the database
  94. * so let mktime to guess it. This eliminates the bug when
  95. * contacts reloaded from the database have different time
  96. * of expiration by one hour when daylight saving is used
  97. */
  98. t.tm_isdst = -1;
  99. *_v = mktime(&t);
  100. return 0;
  101. }
  102. /*
  103. * Convert an integer to string
  104. */
  105. static inline int int2str(int _v, char* _s, int* _l)
  106. {
  107. #ifdef PARANOID
  108. if ((!_s) || (!_l) || (!*_l)) {
  109. LOG(L_ERR, "int2str(): Invalid parameter value\n");
  110. return -1;
  111. }
  112. #endif
  113. *_l = snprintf(_s, *_l, "%-d", _v);
  114. return 0;
  115. }
  116. /*
  117. * Convert a double to string
  118. */
  119. static inline int double2str(double _v, char* _s, int* _l)
  120. {
  121. #ifdef PARANOID
  122. if ((!_s) || (!_l) || (!*_l)) {
  123. LOG(L_ERR, "double2str(): Invalid parameter value\n");
  124. return -1;
  125. }
  126. #endif
  127. *_l = snprintf(_s, *_l, "%-10.2f", _v);
  128. return 0;
  129. }
  130. /*
  131. * Convert time_t to string
  132. */
  133. static inline int time2str(time_t _v, char* _s, int* _l)
  134. {
  135. struct tm *t;
  136. int bl;
  137. #ifdef PARANOID
  138. if ((!_s) || (!_l) || (*_l < 2)) {
  139. LOG(L_ERR, "Invalid parameter value\n");
  140. return -1;
  141. }
  142. #endif
  143. t = localtime(&_v);
  144. if((bl=strftime(_s,(size_t)(*_l)-1,"'%Y-%m-%d %H:%M:%S %z'",t))>0)
  145. *_l = bl;
  146. return 0;
  147. }
  148. /*
  149. * Does not copy strings
  150. */
  151. int str2valp(db_type_t _t, db_val_t* _v, const char* _s, int _l, void *_p)
  152. {
  153. char dbuf[256];
  154. #ifdef PARANOID
  155. if (!_v) {
  156. LOG(L_ERR, "str2valp(): Invalid parameter value\n");
  157. return -1;
  158. }
  159. #endif
  160. if (!_s) {
  161. DLOG("str2valp", "got a null value");
  162. VAL_TYPE(_v) = _t;
  163. VAL_NULL(_v) = 1;
  164. return 0;
  165. }
  166. switch(_t) {
  167. case DB_INT:
  168. sprintf(dbuf, "got int %s", _s);
  169. DLOG("str2valp", dbuf);
  170. if (str2int(_s, &VAL_INT(_v)) < 0) {
  171. LOG(L_ERR, "str2valp(): Error while converting integer value from string\n");
  172. return -2;
  173. } else {
  174. VAL_TYPE(_v) = DB_INT;
  175. return 0;
  176. }
  177. break;
  178. case DB_DOUBLE:
  179. sprintf(dbuf, "got double %s", _s);
  180. DLOG("str2valp", dbuf);
  181. if (str2double(_s, &VAL_DOUBLE(_v)) < 0) {
  182. LOG(L_ERR, "str2valp(): Error while converting double value from string\n");
  183. return -3;
  184. } else {
  185. VAL_TYPE(_v) = DB_DOUBLE;
  186. return 0;
  187. }
  188. break;
  189. case DB_STRING:
  190. sprintf(dbuf, "got string %s", _s);
  191. DLOG("str2valp", dbuf);
  192. VAL_STRING(_v) = aug_strdup(_s, _p);
  193. VAL_TYPE(_v) = DB_STRING;
  194. return 0;
  195. case DB_STR:
  196. VAL_STR(_v).s = aug_alloc(_l + 1, _p);
  197. memcpy(_s, VAL_STR(_v).s, _l);
  198. VAL_STR(_v).s[_l] = (char) 0;
  199. VAL_STR(_v).len = _l;
  200. VAL_TYPE(_v) = DB_STR;
  201. sprintf(dbuf, "got len string %d %s", _l, _s);
  202. DLOG("str2valp", dbuf);
  203. return 0;
  204. case DB_DATETIME:
  205. sprintf(dbuf, "got time %s", _s);
  206. DLOG("str2valp", dbuf);
  207. if (str2time(_s, &VAL_TIME(_v)) < 0) {
  208. PLOG("str2valp", "error converting datetime");
  209. return -4;
  210. } else {
  211. VAL_TYPE(_v) = DB_DATETIME;
  212. return 0;
  213. }
  214. break;
  215. case DB_BLOB:
  216. VAL_STR(_v).s = aug_alloc(_l + 1, _p);
  217. memcpy(_s, VAL_STR(_v).s, _l);
  218. VAL_STR(_v).s[_l] = (char) 0;
  219. VAL_STR(_v).len = _l;
  220. VAL_TYPE(_v) = DB_BLOB;
  221. sprintf(dbuf, "got blob %d", _l);
  222. DLOG("str2valp", dbuf);
  223. return 0;
  224. }
  225. return -5;
  226. }
  227. /*
  228. * Used when converting result from a query
  229. */
  230. int val2str(db_val_t* _v, char* _s, int* _len)
  231. {
  232. int l;
  233. #ifdef PARANOID
  234. if ((!_v) || (!_s) || (!_len) || (!*_len)) {
  235. LOG(L_ERR, "val2str(): Invalid parameter value\n");
  236. return -1;
  237. }
  238. #endif
  239. if (VAL_NULL(_v)) {
  240. *_len = snprintf(_s, *_len, "NULL");
  241. return 0;
  242. }
  243. switch(VAL_TYPE(_v)) {
  244. case DB_INT:
  245. if (int2str(VAL_INT(_v), _s, _len) < 0) {
  246. LOG(L_ERR, "val2str(): Error while converting string to int\n");
  247. return -2;
  248. } else {
  249. return 0;
  250. }
  251. break;
  252. case DB_DOUBLE:
  253. if (double2str(VAL_DOUBLE(_v), _s, _len) < 0) {
  254. LOG(L_ERR, "val2str(): Error while converting string to double\n");
  255. return -3;
  256. } else {
  257. return 0;
  258. }
  259. break;
  260. case DB_STRING:
  261. l = strlen(VAL_STRING(_v));
  262. LOG(L_ERR, "val2str(): converting %s, %d\n", VAL_STRING(_v), l);
  263. if (*_len < (l + 3)) {
  264. LOG(L_ERR, "val2str(): Destination buffer too short\n");
  265. return -4;
  266. } else {
  267. *_s++ = '\'';
  268. memcpy(_s, VAL_STRING(_v), l);
  269. *(_s + l) = '\'';
  270. *(_s + l + 1) = '\0'; /* FIXME */
  271. *_len = l + 2;
  272. return 0;
  273. }
  274. break;
  275. case DB_STR:
  276. l = VAL_STR(_v).len;
  277. if (*_len < (l + 3)) {
  278. LOG(L_ERR, "val2str(): Destination buffer too short %d\n", *_len);
  279. return -5;
  280. } else {
  281. *_s++ = '\'';
  282. memcpy(_s, VAL_STR(_v).s, l);
  283. *(_s + l) = '\'';
  284. *(_s + l + 1) = '\0';
  285. *_len = l + 2;
  286. return 0;
  287. }
  288. break;
  289. case DB_DATETIME:
  290. if (time2str(VAL_TIME(_v), _s, _len) < 0) {
  291. LOG(L_ERR, "val2str(): Error while converting string to time_t\n");
  292. return -6;
  293. } else {
  294. return 0;
  295. }
  296. break;
  297. case DB_BLOB:
  298. l = VAL_BLOB(_v).len;
  299. if (*_len < (l * 2 + 3)) {
  300. LOG(L_ERR, "val2str(): Destination buffer too short\n");
  301. return -7;
  302. } else {
  303. /* WRITE ME */
  304. return 0;
  305. }
  306. break;
  307. default:
  308. DBG("val2str(): Unknow data type\n");
  309. return -7;
  310. }
  311. return -8;
  312. }