all: updated FSF address in GPL text
[sip-router] / modules / db_berkeley / km_bdb_val.c
1 /*
2  * $Id$
3  *
4  * db_berkeley module, portions of this code were templated using
5  * the dbtext and postgres modules.
6
7  * Copyright (C) 2007 Cisco Systems
8  *
9  * This file is part of SIP-router, a free SIP server.
10  *
11  * SIP-router is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version
15  *
16  * SIP-router is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License 
22  * along with this program; if not, write to the Free Software 
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
24  * 
25  * History:
26  * --------
27  * 2007-09-19  genesis (wiquan)
28  */
29  
30 /*! \file
31  * Berkeley DB : 
32  *
33  * \ingroup database
34  */
35
36
37 #include "../../lib/srdb1/db_val.h"
38 #include "../../lib/srdb1/db_ut.h"
39 #include "km_db_berkeley.h"
40 #include "km_bdb_res.h"
41 #include "km_bdb_val.h"
42 #include <string.h>
43
44 /**
45  * A copy of db_ut::db_time2str EXCEPT does not wrap the date in single-quotes
46  *
47  * Convert a time_t value to string (w.o single-quote)
48  * \param _v source value
49  * \param _s target string
50  * \param _l available length and target length
51  * \return -1 on error, 0 on success
52  * \todo This functions add quotes to the time value. This
53  * should be done in the val2str function, as some databases
54  * like db_berkeley don't need or like this at all.
55  */
56 inline int km_bdb_time2str(time_t _v, char* _s, int* _l)
57 {
58         struct tm* t;
59         int l;
60
61         if ((!_s) || (!_l) || (*_l < 2)) {
62                 LM_ERR("Invalid parameter value\n");
63                 return -1;
64         }
65
66 //      *_s++ = '\'';
67
68         /* Convert time_t structure to format accepted by the database */
69         t = localtime(&_v);
70         l = strftime(_s, *_l -1, "%Y-%m-%d %H:%M:%S", t);
71
72         if (l == 0) {
73                 LM_ERR("Error during time conversion\n");
74                 /* the value of _s is now unspecified */
75                 _s = NULL;
76                 _l = 0;
77                 return -1;
78         }
79         *_l = l;
80
81 //      *(_s + l) = '\'';
82 //      *_l = l + 2;
83         return 0;
84 }
85
86 /**
87  * Does not copy strings
88  */
89 int bdb_str2val(db_type_t _t, db_val_t* _v, char* _s, int _l)
90 {
91
92         static str dummy_string = {"", 0};
93
94         if(!_s)
95         {
96                 memset(_v, 0, sizeof(db_val_t));
97                 /* Initialize the string pointers to a dummy empty
98                  * string so that we do not crash when the NULL flag
99                  * is set but the module does not check it properly
100                  */
101                 VAL_STRING(_v) = dummy_string.s;
102                 VAL_STR(_v) = dummy_string;
103                 VAL_BLOB(_v) = dummy_string;
104                 VAL_TYPE(_v) = _t;
105                 VAL_NULL(_v) = 1;
106                 return 0;
107         }
108         VAL_NULL(_v) = 0;
109
110         switch(_t) {
111         case DB1_INT:
112                 if (db_str2int(_s, &VAL_INT(_v)) < 0) {
113                         LM_ERR("Error while converting INT value from string\n");
114                         return -2;
115                 } else {
116                         VAL_TYPE(_v) = DB1_INT;
117                         return 0;
118                 }
119                 break;
120
121         case DB1_BIGINT:
122                         LM_ERR("BIGINT not supported");
123                         return -1;
124
125         case DB1_BITMAP:
126                 if (db_str2int(_s, &VAL_INT(_v)) < 0) {
127                         LM_ERR("Error while converting BITMAP value from string\n");
128                         return -3;
129                 } else {
130                         VAL_TYPE(_v) = DB1_BITMAP;
131                         return 0;
132                 }
133                 break;
134
135         case DB1_DOUBLE:
136                 if (db_str2double(_s, &VAL_DOUBLE(_v)) < 0) {
137                         LM_ERR("Error while converting DOUBLE value from string\n");
138                         return -4;
139                 } else {
140                         VAL_TYPE(_v) = DB1_DOUBLE;
141                         return 0;
142                 }
143                 break;
144
145         case DB1_STRING:
146                 VAL_STRING(_v) = _s;
147                 VAL_TYPE(_v) = DB1_STRING;
148                 VAL_FREE(_v) = 1;
149                 
150                 if( strlen(_s)==4 && !strncasecmp(_s, "NULL", 4) )
151                         VAL_NULL(_v) = 1;
152                 
153                 return 0;
154
155         case DB1_STR:
156                 VAL_STR(_v).s = (char*)_s;
157                 VAL_STR(_v).len = _l;
158                 VAL_TYPE(_v) = DB1_STR;
159                 VAL_FREE(_v) = 1;
160
161                 if( strlen(_s)==4 && !strncasecmp(_s, "NULL", 4) )
162                         VAL_NULL(_v) = 1;
163
164                 return 0;
165
166         case DB1_DATETIME:
167                 if (db_str2time(_s, &VAL_TIME(_v)) < 0) {
168                         LM_ERR("Error converting datetime\n");
169                         return -5;
170                 } else {
171                         VAL_TYPE(_v) = DB1_DATETIME;
172                         return 0;
173                 }
174                 break;
175
176         case DB1_BLOB:
177                 VAL_BLOB(_v).s = _s;
178                 VAL_TYPE(_v) = DB1_BLOB;
179                 LM_DBG("got blob len %d\n", _l);
180                 return 0;
181         }
182
183         return -6;
184 }
185
186
187 /*
188  * Used when converting result from a query
189  */
190 int km_bdb_val2str(db_val_t* _v, char* _s, int* _len)
191 {
192         int l;
193
194         if (VAL_NULL(_v)) 
195         {
196                 *_len = snprintf(_s, *_len, "NULL");
197                 return 0;
198         }
199         
200         switch(VAL_TYPE(_v)) {
201         case DB1_INT:
202                 if (db_int2str(VAL_INT(_v), _s, _len) < 0) {
203                         LM_ERR("Error while converting int to string\n");
204                         return -2;
205                 } else {
206                         LM_DBG("Converted int to string\n");
207                         return 0;
208                 }
209                 break;
210
211         case DB1_BITMAP:
212                 if (db_int2str(VAL_INT(_v), _s, _len) < 0) {
213                         LM_ERR("Error while converting bitmap to string\n");
214                         return -3;
215                 } else {
216                         LM_DBG("Converted bitmap to string\n");
217                         return 0;
218                 }
219                 break;
220
221         case DB1_DOUBLE:
222                 if (db_double2str(VAL_DOUBLE(_v), _s, _len) < 0) {
223                         LM_ERR("Error while converting double  to string\n");
224                         return -3;
225                 } else {
226                         LM_DBG("Converted double to string\n");
227                         return 0;
228                 }
229                 break;
230
231         case DB1_STRING:
232                 l = strlen(VAL_STRING(_v));
233                 if (*_len < l ) 
234                 {       LM_ERR("Destination buffer too short for string\n");
235                         return -4;
236                 } 
237                 else 
238                 {       LM_DBG("Converted string to string\n");
239                         strncpy(_s, VAL_STRING(_v) , l);
240                         _s[l] = 0;
241                         *_len = l;
242                         return 0;
243                 }
244                 break;
245
246         case DB1_STR:
247                 l = VAL_STR(_v).len;
248                 if (*_len < l) 
249                 {
250                         LM_ERR("Destination buffer too short for str\n");
251                         return -5;
252                 } 
253                 else 
254                 {
255                         LM_DBG("Converted str to string\n");
256                         strncpy(_s, VAL_STR(_v).s , VAL_STR(_v).len);
257                         *_len = VAL_STR(_v).len;
258                         return 0;
259                 }
260                 break;
261
262         case DB1_DATETIME:
263                 if (km_bdb_time2str(VAL_TIME(_v), _s, _len) < 0) {
264                         LM_ERR("Error while converting time_t to string\n");
265                         return -6;
266                 } else {
267                         LM_DBG("Converted time_t to string\n");
268                         return 0;
269                 }
270                 break;
271
272         case DB1_BLOB:
273                 l = VAL_BLOB(_v).len;
274                 if (*_len < l) 
275                 {
276                         LM_ERR("Destination buffer too short for blob\n");
277                         return -7;
278                 } 
279                 else 
280                 {
281                         LM_DBG("Converting BLOB [%s]\n", _s);
282                         _s = VAL_BLOB(_v).s;
283                         *_len = 0;
284                         return -8;
285                 }
286                 break;
287
288         default:
289                 LM_DBG("Unknown data type\n");
290                 return -8;
291         }
292 }