modules/ims_qos: added patch for flow-description bug when request originates from...
[sip-router] / src / lib / srdb1 / db_val.c
1 /*
2  * Copyright (C) 2001-2003 FhG Fokus
3  * Copyright (C) 2008-2009 1&1 Internet AG
4  *
5  * This file is part of Kamailio, a free SIP server.
6  *
7  * Kamailio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version
11  *
12  * Kamailio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License 
18  * along with this program; if not, write to the Free Software 
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #include "db_ut.h"
23
24 #include <stdio.h>
25 #include <time.h>
26
27 /*!
28  * \brief Convert a str to a db value
29  *
30  * Convert a str to a db value, copy strings if _cpy is not zero.
31  * Copying is not necessary if the result from the database client library
32  * is freed after the result inside the server is processed. If the result
33  * is freed earlier, e.g. because its saved inside some temporary storage,
34  * then it must be copied in order to be use it reliable.
35  *
36  * \param _t destination value type
37  * \param _v destination value
38  * \param _s source string
39  * \param _l string length
40  * \param _cpy when set to zero does not copy strings, otherwise copy strings
41  * \return 0 on success, negative on error
42  */
43 int db_str2val(const db_type_t _t, db_val_t* _v, const char* _s, const int _l,
44                 const unsigned int _cpy)
45 {
46         static str dummy_string = {"", 0};
47         static char dummy_string_buf[2];
48         
49         if (!_v) {
50                 LM_ERR("invalid parameter value\n");
51                 return -1;
52         }
53         /* A NULL string is a SQL NULL value, otherwise its an empty value */
54         if (!_s) {
55                 LM_DBG("converting NULL value\n");
56                 memset(_v, 0, sizeof(db_val_t));
57                         /* Initialize the string pointers to a dummy empty
58                          * string so that we do not crash when the NULL flag
59                          * is set but the module does not check it properly
60                          */
61                 dummy_string_buf[0] = '\0';
62                 dummy_string.s = dummy_string_buf;
63                 VAL_STRING(_v) = dummy_string.s;
64                 VAL_STR(_v) = dummy_string;
65                 VAL_BLOB(_v) = dummy_string;
66                 VAL_TYPE(_v) = _t;
67                 VAL_NULL(_v) = 1;
68                 return 0;
69         }
70         VAL_NULL(_v) = 0;
71
72         switch(_t) {
73         case DB1_INT:
74                 LM_DBG("converting INT [%s]\n", _s);
75                 if (db_str2int(_s, &VAL_INT(_v)) < 0) {
76                         LM_ERR("error while converting integer value from string\n");
77                         return -2;
78                 } else {
79                         VAL_TYPE(_v) = DB1_INT;
80                         return 0;
81                 }
82                 break;
83
84         case DB1_BIGINT:
85                 LM_DBG("converting BIGINT [%s]\n", _s);
86                 if (db_str2longlong(_s, &VAL_BIGINT(_v)) < 0) {
87                         LM_ERR("error while converting big integer value from string\n");
88                         return -3;
89                 } else {
90                         VAL_TYPE(_v) = DB1_BIGINT;
91                         return 0;
92                 }
93                 break;
94
95         case DB1_BITMAP:
96                 LM_DBG("converting BITMAP [%s]\n", _s);
97                 if (db_str2int(_s, &VAL_INT(_v)) < 0) {
98                         LM_ERR("error while converting bitmap value from string\n");
99                         return -4;
100                 } else {
101                         VAL_TYPE(_v) = DB1_BITMAP;
102                         return 0;
103                 }
104                 break;
105         
106         case DB1_DOUBLE:
107                 LM_DBG("converting DOUBLE [%s]\n", _s);
108                 if (db_str2double(_s, &VAL_DOUBLE(_v)) < 0) {
109                         LM_ERR("error while converting double value from string\n");
110                         return -5;
111                 } else {
112                         VAL_TYPE(_v) = DB1_DOUBLE;
113                         return 0;
114                 }
115                 break;
116
117         case DB1_STRING:
118                 LM_DBG("converting STRING [%s]\n", _s);
119
120                 if (_cpy == 0) {
121                         VAL_STRING(_v) = _s;
122                 } else {
123                         VAL_STRING(_v) = pkg_malloc(_l + 1);
124                         if (VAL_STRING(_v) == NULL) {
125                                 LM_ERR("no private memory left\n");
126                                 return -6;
127                         }
128                         LM_DBG("allocate %d bytes memory for STRING at %p\n", _l + 1, VAL_STRING(_v));
129                         strncpy((char*)VAL_STRING(_v), _s, _l);
130                         ((char*)VAL_STRING(_v))[_l] = '\0';
131                         VAL_FREE(_v) = 1;
132                 }
133
134                 VAL_TYPE(_v) = DB1_STRING;
135                 return 0;
136
137         case DB1_STR:
138                 LM_DBG("converting STR [%.*s]\n", _l, _s);
139
140                 if (_cpy == 0) {
141                         VAL_STR(_v).s = (char*) _s;
142                 } else {
143                         VAL_STR(_v).s = pkg_malloc(_l);
144                         if (VAL_STR(_v).s == NULL) {
145                                 LM_ERR("no private memory left\n");
146                                 return -7;
147                         }
148                         LM_DBG("allocate %d bytes memory for STR at %p\n", _l, VAL_STR(_v).s);
149                         strncpy(VAL_STR(_v).s, _s, _l);
150                         VAL_FREE(_v) = 1;
151                 }
152
153                 VAL_STR(_v).len = _l;
154                 VAL_TYPE(_v) = DB1_STR;
155                 return 0;
156
157         case DB1_DATETIME:
158                 LM_DBG("converting DATETIME [%s]\n", _s);
159                 if (db_str2time(_s, &VAL_TIME(_v)) < 0) {
160                         LM_ERR("error while converting datetime value from string\n");
161                         return -8;
162                 } else {
163                         VAL_TYPE(_v) = DB1_DATETIME;
164                         return 0;
165                 }
166                 break;
167
168         case DB1_BLOB:
169                 LM_DBG("converting BLOB [%.*s]\n", _l, _s);
170
171                 if (_cpy == 0) {
172                         VAL_BLOB(_v).s = (char*) _s;
173                 } else {
174                         VAL_BLOB(_v).s = pkg_malloc(_l);
175                         if (VAL_BLOB(_v).s == NULL) {
176                                 LM_ERR("no private memory left\n");
177                                 return -9;
178                         }
179                         LM_DBG("allocate %d bytes memory for BLOB at %p\n", _l, VAL_BLOB(_v).s);
180                         strncpy(VAL_BLOB(_v).s, _s, _l);
181                         VAL_FREE(_v) = 1;
182                 }
183
184                 VAL_BLOB(_v).len = _l;
185                 VAL_TYPE(_v) = DB1_BLOB;
186                 return 0;
187
188         default:
189                 return -10;
190         }
191         return -10;
192 }
193
194
195 /*!
196  * \brief Convert a numerical value to a string
197  *
198  * Convert a numerical value to a string, used when converting result from a query.
199  * Implement common functionality needed from the databases, does parameter checking.
200  * \param _c database connection
201  * \param _v source value
202  * \param _s target string
203  * \param _len target string length
204  * \return 0 on success, negative on error, 1 if value must be converted by other means
205  */
206 int db_val2str(const db1_con_t* _c, const db_val_t* _v, char* _s, int* _len)
207 {
208         if (!_c || !_v || !_s || !_len || !*_len) {
209                 LM_ERR("invalid parameter value\n");
210                 return -1;
211         }
212
213         if (VAL_NULL(_v)) {
214                 if (*_len < sizeof("NULL")) {
215                         LM_ERR("buffer too small\n");
216                         return -1;
217                 }
218                 *_len = snprintf(_s, *_len, "NULL");
219                 return 0;
220         }
221         
222         switch(VAL_TYPE(_v)) {
223         case DB1_INT:
224                 if (db_int2str(VAL_INT(_v), _s, _len) < 0) {
225                         LM_ERR("error while converting string to int\n");
226                         return -2;
227                 } else {
228                         return 0;
229                 }
230                 break;
231
232         case DB1_BIGINT:
233                 if (db_longlong2str(VAL_BIGINT(_v), _s, _len) < 0) {
234                         LM_ERR("error while converting string to big int\n");
235                         return -3;
236                 } else {
237                         return 0;
238                 }
239                 break;
240
241         case DB1_BITMAP:
242                 if (db_int2str(VAL_BITMAP(_v), _s, _len) < 0) {
243                         LM_ERR("error while converting string to int\n");
244                         return -4;
245                 } else {
246                         return 0;
247                 }
248                 break;
249
250         case DB1_DOUBLE:
251                 if (db_double2str(VAL_DOUBLE(_v), _s, _len) < 0) {
252                         LM_ERR("error while converting string to double\n");
253                         return -5;
254                 } else {
255                         return 0;
256                 }
257                 break;
258
259         case DB1_DATETIME:
260                 if (db_time2str(VAL_TIME(_v), _s, _len) < 0) {
261                         LM_ERR("failed to convert string to time_t\n");
262                         return -8;
263                 } else {
264                         return 0;
265                 }
266                 break;
267
268         default:
269                 return 1;
270         }
271 }