2
0

db_val.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  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. case DB_BITMAP:
  169. sprintf(dbuf, "got int %s", _s);
  170. DLOG("str2valp", dbuf);
  171. if (str2int(_s, &VAL_INT(_v)) < 0) {
  172. LOG(L_ERR, "str2valp(): Error while converting integer value from string\n");
  173. return -2;
  174. } else {
  175. VAL_TYPE(_v) = DB_INT;
  176. return 0;
  177. }
  178. break;
  179. case DB_DOUBLE:
  180. sprintf(dbuf, "got double %s", _s);
  181. DLOG("str2valp", dbuf);
  182. if (str2double(_s, &VAL_DOUBLE(_v)) < 0) {
  183. LOG(L_ERR, "str2valp(): Error while converting double value from string\n");
  184. return -3;
  185. } else {
  186. VAL_TYPE(_v) = DB_DOUBLE;
  187. return 0;
  188. }
  189. break;
  190. case DB_STRING:
  191. sprintf(dbuf, "got string %s", _s);
  192. DLOG("str2valp", dbuf);
  193. VAL_STRING(_v) = aug_strdup(_s, _p);
  194. VAL_TYPE(_v) = DB_STRING;
  195. return 0;
  196. case DB_STR:
  197. VAL_STR(_v).s = aug_alloc(_l + 1, _p);
  198. memcpy(_s, VAL_STR(_v).s, _l);
  199. VAL_STR(_v).s[_l] = (char) 0;
  200. VAL_STR(_v).len = _l;
  201. VAL_TYPE(_v) = DB_STR;
  202. sprintf(dbuf, "got len string %d %s", _l, _s);
  203. DLOG("str2valp", dbuf);
  204. return 0;
  205. case DB_DATETIME:
  206. sprintf(dbuf, "got time %s", _s);
  207. DLOG("str2valp", dbuf);
  208. if (str2time(_s, &VAL_TIME(_v)) < 0) {
  209. PLOG("str2valp", "error converting datetime");
  210. return -4;
  211. } else {
  212. VAL_TYPE(_v) = DB_DATETIME;
  213. return 0;
  214. }
  215. break;
  216. case DB_BLOB:
  217. VAL_STR(_v).s = aug_alloc(_l + 1, _p);
  218. memcpy(_s, VAL_STR(_v).s, _l);
  219. VAL_STR(_v).s[_l] = (char) 0;
  220. VAL_STR(_v).len = _l;
  221. VAL_TYPE(_v) = DB_BLOB;
  222. sprintf(dbuf, "got blob %d", _l);
  223. DLOG("str2valp", dbuf);
  224. return 0;
  225. }
  226. return -5;
  227. }
  228. /*
  229. * Used when converting result from a query
  230. */
  231. int val2str(db_val_t* _v, char* _s, int* _len)
  232. {
  233. int l;
  234. #ifdef PARANOID
  235. if ((!_v) || (!_s) || (!_len) || (!*_len)) {
  236. LOG(L_ERR, "val2str(): Invalid parameter value\n");
  237. return -1;
  238. }
  239. #endif
  240. if (VAL_NULL(_v)) {
  241. *_len = snprintf(_s, *_len, "NULL");
  242. return 0;
  243. }
  244. switch(VAL_TYPE(_v)) {
  245. case DB_INT:
  246. if (int2str(VAL_INT(_v), _s, _len) < 0) {
  247. LOG(L_ERR, "val2str(): Error while converting string to int\n");
  248. return -2;
  249. } else {
  250. return 0;
  251. }
  252. break;
  253. case DB_DOUBLE:
  254. if (double2str(VAL_DOUBLE(_v), _s, _len) < 0) {
  255. LOG(L_ERR, "val2str(): Error while converting string to double\n");
  256. return -3;
  257. } else {
  258. return 0;
  259. }
  260. break;
  261. case DB_STRING:
  262. l = strlen(VAL_STRING(_v));
  263. LOG(L_ERR, "val2str(): converting %s, %d\n", VAL_STRING(_v), l);
  264. if (*_len < (l + 3)) {
  265. LOG(L_ERR, "val2str(): Destination buffer too short\n");
  266. return -4;
  267. } else {
  268. *_s++ = '\'';
  269. memcpy(_s, VAL_STRING(_v), l);
  270. *(_s + l) = '\'';
  271. *(_s + l + 1) = '\0'; /* FIXME */
  272. *_len = l + 2;
  273. return 0;
  274. }
  275. break;
  276. case DB_STR:
  277. l = VAL_STR(_v).len;
  278. if (*_len < (l + 3)) {
  279. LOG(L_ERR, "val2str(): Destination buffer too short %d\n", *_len);
  280. return -5;
  281. } else {
  282. *_s++ = '\'';
  283. memcpy(_s, VAL_STR(_v).s, l);
  284. *(_s + l) = '\'';
  285. *(_s + l + 1) = '\0';
  286. *_len = l + 2;
  287. return 0;
  288. }
  289. break;
  290. case DB_DATETIME:
  291. if (time2str(VAL_TIME(_v), _s, _len) < 0) {
  292. LOG(L_ERR, "val2str(): Error while converting string to time_t\n");
  293. return -6;
  294. } else {
  295. return 0;
  296. }
  297. break;
  298. case DB_BLOB:
  299. l = VAL_BLOB(_v).len;
  300. if (*_len < (l * 2 + 3)) {
  301. LOG(L_ERR, "val2str(): Destination buffer too short\n");
  302. return -7;
  303. } else {
  304. /* WRITE ME */
  305. return 0;
  306. }
  307. break;
  308. default:
  309. DBG("val2str(): Unknow data type\n");
  310. return -7;
  311. }
  312. return -8;
  313. }