db_val.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  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. *
  37. */
  38. #include <stdlib.h>
  39. #include <stdio.h>
  40. #include <string.h>
  41. #include "../../db/db_val.h"
  42. #include "../../dprint.h"
  43. #include "defs.h"
  44. #include "db_utils.h"
  45. #include "con_postgres.h"
  46. #include "aug_std.h"
  47. char *strptime(const char *s, const char *format, struct tm *tm);
  48. /*
  49. * Convert a string to integer
  50. */
  51. static inline int str2int(const char* _s, int* _v)
  52. {
  53. #ifdef PARANOID
  54. if ((!_s) || (!_v)) {
  55. LOG(L_ERR, "str2int(): Invalid parameter value\n");
  56. return -1;
  57. }
  58. #endif
  59. *_v = atoi(_s);
  60. return 0;
  61. }
  62. /*
  63. * Convert a string to double
  64. */
  65. static inline int str2double(const char* _s, double* _v)
  66. {
  67. #ifdef PARANOID
  68. if ((!_s) || (!_v)) {
  69. LOG(L_ERR, "str2double(): Invalid parameter value\n");
  70. return -1;
  71. }
  72. #endif
  73. *_v = atof(_s);
  74. return 0;
  75. }
  76. /*
  77. * Convert a string to time_t
  78. */
  79. static inline int str2time(const char* _s, time_t* _v)
  80. {
  81. struct tm t;
  82. #ifdef PARANOID
  83. if ((!_s) || (!_v)) {
  84. LOG(L_ERR, "str2time(): Invalid parameter value\n");
  85. return -1;
  86. }
  87. #endif
  88. strptime(_s,"%Y-%m-%d %H:%M:%S %z",&t);
  89. *_v = mktime(&t);
  90. return 0;
  91. }
  92. /*
  93. * Convert an integer to string
  94. */
  95. static inline int int2str(int _v, char* _s, int* _l)
  96. {
  97. #ifdef PARANOID
  98. if ((!_s) || (!_l) || (!*_l)) {
  99. LOG(L_ERR, "int2str(): Invalid parameter value\n");
  100. return -1;
  101. }
  102. #endif
  103. *_l = snprintf(_s, *_l, "%-d", _v);
  104. return 0;
  105. }
  106. /*
  107. * Convert a double to string
  108. */
  109. static inline int double2str(double _v, char* _s, int* _l)
  110. {
  111. #ifdef PARANOID
  112. if ((!_s) || (!_l) || (!*_l)) {
  113. LOG(L_ERR, "double2str(): Invalid parameter value\n");
  114. return -1;
  115. }
  116. #endif
  117. *_l = snprintf(_s, *_l, "%-10.2f", _v);
  118. return 0;
  119. }
  120. /*
  121. * Convert time_t to string
  122. */
  123. static inline int time2str(time_t _v, char* _s, int* _l)
  124. {
  125. struct tm *t;
  126. int bl;
  127. #ifdef PARANOID
  128. if ((!_s) || (!_l) || (*_l < 2)) {
  129. LOG(L_ERR, "Invalid parameter value\n");
  130. return -1;
  131. }
  132. #endif
  133. t = gmtime(&_v);
  134. if((bl=strftime(_s,(size_t)(*_l)-1,"'%Y-%m-%d %H:%M:%S %z'",t))>0)
  135. *_l = bl;
  136. return 0;
  137. }
  138. /*
  139. * Does not copy strings
  140. */
  141. int str2valp(db_type_t _t, db_val_t* _v, const char* _s, int _l, void *_p)
  142. {
  143. char dbuf[256];
  144. #ifdef PARANOID
  145. if (!_v) {
  146. LOG(L_ERR, "str2valp(): Invalid parameter value\n");
  147. return -1;
  148. }
  149. #endif
  150. if (!_s) {
  151. DLOG("str2valp", "got a null value");
  152. VAL_TYPE(_v) = _t;
  153. VAL_NULL(_v) = 1;
  154. return 0;
  155. }
  156. switch(_t) {
  157. case DB_INT:
  158. sprintf(dbuf, "got int %s", _s);
  159. DLOG("str2valp", dbuf);
  160. if (str2int(_s, &VAL_INT(_v)) < 0) {
  161. LOG(L_ERR, "str2valp(): Error while converting integer value from string\n");
  162. return -2;
  163. } else {
  164. VAL_TYPE(_v) = DB_INT;
  165. return 0;
  166. }
  167. break;
  168. case DB_DOUBLE:
  169. sprintf(dbuf, "got double %s", _s);
  170. DLOG("str2valp", dbuf);
  171. if (str2double(_s, &VAL_DOUBLE(_v)) < 0) {
  172. LOG(L_ERR, "str2valp(): Error while converting double value from string\n");
  173. return -3;
  174. } else {
  175. VAL_TYPE(_v) = DB_DOUBLE;
  176. return 0;
  177. }
  178. break;
  179. case DB_STRING:
  180. sprintf(dbuf, "got string %s", _s);
  181. DLOG("str2valp", dbuf);
  182. VAL_STRING(_v) = aug_strdup(_s, _p);
  183. VAL_TYPE(_v) = DB_STRING;
  184. return 0;
  185. case DB_STR:
  186. VAL_STR(_v).s = aug_alloc(_l + 1, _p);
  187. memcpy(_s, VAL_STR(_v).s, _l);
  188. VAL_STR(_v).s[_l] = (char) 0;
  189. VAL_STR(_v).len = _l;
  190. VAL_TYPE(_v) = DB_STR;
  191. sprintf(dbuf, "got len string %d %s", _l, _s);
  192. DLOG("str2valp", dbuf);
  193. return 0;
  194. case DB_DATETIME:
  195. sprintf(dbuf, "got time %s", _s);
  196. DLOG("str2valp", dbuf);
  197. if (str2time(_s, &VAL_TIME(_v)) < 0) {
  198. PLOG("str2valp", "error converting datetime");
  199. return -4;
  200. } else {
  201. VAL_TYPE(_v) = DB_DATETIME;
  202. return 0;
  203. }
  204. break;
  205. case DB_BLOB:
  206. VAL_STR(_v).s = aug_alloc(_l + 1, _p);
  207. memcpy(_s, VAL_STR(_v).s, _l);
  208. VAL_STR(_v).s[_l] = (char) 0;
  209. VAL_STR(_v).len = _l;
  210. VAL_TYPE(_v) = DB_BLOB;
  211. sprintf(dbuf, "got blob %d", _l);
  212. DLOG("str2valp", dbuf);
  213. return 0;
  214. }
  215. return -5;
  216. }
  217. /*
  218. * Used when converting result from a query
  219. */
  220. int val2str(db_val_t* _v, char* _s, int* _len)
  221. {
  222. int l;
  223. #ifdef PARANOID
  224. if ((!_v) || (!_s) || (!_len) || (!*_len)) {
  225. LOG(L_ERR, "val2str(): Invalid parameter value\n");
  226. return -1;
  227. }
  228. #endif
  229. if (VAL_NULL(_v)) {
  230. *_len = snprintf(_s, *_len, "NULL");
  231. return 0;
  232. }
  233. switch(VAL_TYPE(_v)) {
  234. case DB_INT:
  235. if (int2str(VAL_INT(_v), _s, _len) < 0) {
  236. LOG(L_ERR, "val2str(): Error while converting string to int\n");
  237. return -2;
  238. } else {
  239. return 0;
  240. }
  241. break;
  242. case DB_DOUBLE:
  243. if (double2str(VAL_DOUBLE(_v), _s, _len) < 0) {
  244. LOG(L_ERR, "val2str(): Error while converting string to double\n");
  245. return -3;
  246. } else {
  247. return 0;
  248. }
  249. break;
  250. case DB_STRING:
  251. l = strlen(VAL_STRING(_v));
  252. LOG(L_ERR, "val2str(): converting %s, %d\n", VAL_STRING(_v), l);
  253. if (*_len < (l + 3)) {
  254. LOG(L_ERR, "val2str(): Destination buffer too short\n");
  255. return -4;
  256. } else {
  257. *_s++ = '\'';
  258. memcpy(_s, VAL_STRING(_v), l);
  259. *(_s + l) = '\'';
  260. *(_s + l + 1) = '\0'; /* FIXME */
  261. *_len = l + 2;
  262. return 0;
  263. }
  264. break;
  265. case DB_STR:
  266. l = VAL_STR(_v).len;
  267. if (*_len < (l + 3)) {
  268. LOG(L_ERR, "val2str(): Destination buffer too short %d\n", *_len);
  269. return -5;
  270. } else {
  271. *_s++ = '\'';
  272. memcpy(_s, VAL_STR(_v).s, l);
  273. *(_s + l) = '\'';
  274. *(_s + l + 1) = '\0';
  275. *_len = l + 2;
  276. return 0;
  277. }
  278. break;
  279. case DB_DATETIME:
  280. if (time2str(VAL_TIME(_v), _s, _len) < 0) {
  281. LOG(L_ERR, "val2str(): Error while converting string to time_t\n");
  282. return -6;
  283. } else {
  284. return 0;
  285. }
  286. break;
  287. case DB_BLOB:
  288. l = VAL_BLOB(_v).len;
  289. if (*_len < (l * 2 + 3)) {
  290. LOG(L_ERR, "val2str(): Destination buffer too short\n");
  291. return -7;
  292. } else {
  293. /* WRITE ME */
  294. return 0;
  295. }
  296. break;
  297. default:
  298. DBG("val2str(): Unknow data type\n");
  299. return -7;
  300. }
  301. return -8;
  302. }