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