Browse code

lib/srdb1: cast pv value to long

Daniel-Constantin Mierla authored on 20/11/2022 20:02:18
Showing 1 changed files
... ...
@@ -581,15 +581,15 @@ int db_val2pv_spec(struct sip_msg* msg, db_val_t *dbval, pv_spec_t *pvs)
581 581
 			break;
582 582
 			case DB1_INT:
583 583
 				pv.flags = PV_VAL_INT | PV_TYPE_INT;
584
-				pv.ri = (int)dbval->val.int_val;
584
+				pv.ri = (long)dbval->val.int_val;
585 585
 			break;
586 586
 			case DB1_DATETIME:
587 587
 				pv.flags = PV_VAL_INT | PV_TYPE_INT;
588
-				pv.ri = (int)dbval->val.time_val;
588
+				pv.ri = (long)dbval->val.time_val;
589 589
 			break;
590 590
 			case DB1_BITMAP:
591 591
 				pv.flags = PV_VAL_INT | PV_TYPE_INT;
592
-				pv.ri = (int)dbval->val.bitmap_val;
592
+				pv.ri = (long)dbval->val.bitmap_val;
593 593
 			break;
594 594
 			case DB1_BIGINT:
595 595
 				/* BIGINT is stored as string */
Browse code

libs/srdb1: use thread safe localtime_r()

Daniel-Constantin Mierla authored on 04/05/2020 16:26:47
Showing 1 changed files
... ...
@@ -350,7 +350,7 @@ int db_str2time(const char* _s, time_t* _v)
350 350
  */
351 351
 int db_time2str_ex(time_t _v, char* _s, int* _l, int _qmode)
352 352
 {
353
-	struct tm* t;
353
+	struct tm t;
354 354
 	int l;
355 355
 
356 356
 	if ((!_s) || (!_l) || (*_l < 2)) {
... ...
@@ -361,8 +361,8 @@ int db_time2str_ex(time_t _v, char* _s, int* _l, int _qmode)
361 361
 	if(_qmode) *_s++ = '\'';
362 362
 
363 363
 	/* Convert time_t structure to format accepted by the database */
364
-	t = localtime(&_v);
365
-	l = strftime(_s, *_l -1, "%Y-%m-%d %H:%M:%S", t);
364
+	localtime_r(&_v, &t);
365
+	l = strftime(_s, *_l -1, "%Y-%m-%d %H:%M:%S", &t);
366 366
 
367 367
 	if (l == 0) {
368 368
 		LM_ERR("Error during time conversion\n");
Browse code

lib/srdb1: cast for signed comparison

Daniel-Constantin Mierla authored on 15/08/2018 14:45:38
Showing 1 changed files
... ...
@@ -113,7 +113,7 @@ int db_str2uint(const char* _s, unsigned int* _v)
113 113
 
114 114
 	tmp = strtoul(_s, &p, 10);
115 115
 	if ((tmp == ULONG_MAX && errno == ERANGE) ||
116
-				(tmp < INT_MIN) || (tmp > UINT_MAX)) {
116
+				((long)tmp < INT_MIN) || (tmp > UINT_MAX)) {
117 117
 		LM_ERR("Value out of range\n");
118 118
 		return -1;
119 119
 	}
Browse code

lib/srdb1: support types for unsigned int and unsigned long long

- defined db types DB1_UINT and DB1_UBIGINT

Daniel-Constantin Mierla authored on 05/07/2018 11:19:25
Showing 1 changed files
... ...
@@ -69,7 +69,10 @@
69 69
 #include "db_ut.h"
70 70
 
71 71
 
72
-inline int db_str2int(const char* _s, int* _v)
72
+/**
73
+ *
74
+ */
75
+int db_str2int(const char* _s, int* _v)
73 76
 {
74 77
 	long tmp;
75 78
 	char* p = NULL;
... ...
@@ -95,7 +98,39 @@ inline int db_str2int(const char* _s, int* _v)
95 98
 }
96 99
 
97 100
 
98
-inline int db_str2longlong(const char* _s, long long * _v)
101
+/**
102
+ *
103
+ */
104
+int db_str2uint(const char* _s, unsigned int* _v)
105
+{
106
+	unsigned long tmp;
107
+	char* p = NULL;
108
+
109
+	if (!_s || !_v) {
110
+		LM_ERR("Invalid parameter value\n");
111
+		return -1;
112
+	}
113
+
114
+	tmp = strtoul(_s, &p, 10);
115
+	if ((tmp == ULONG_MAX && errno == ERANGE) ||
116
+				(tmp < INT_MIN) || (tmp > UINT_MAX)) {
117
+		LM_ERR("Value out of range\n");
118
+		return -1;
119
+	}
120
+	if (p && *p != '\0') {
121
+		LM_ERR("Unexpected characters: [%s]\n", p);
122
+		return -2;
123
+	}
124
+
125
+	*_v = (unsigned int)tmp;
126
+	return 0;
127
+}
128
+
129
+
130
+/**
131
+ *
132
+ */
133
+int db_str2longlong(const char* _s, long long * _v)
99 134
 {
100 135
 	long long tmp;
101 136
 	char* p = NULL;
... ...
@@ -120,10 +155,38 @@ inline int db_str2longlong(const char* _s, long long * _v)
120 155
 }
121 156
 
122 157
 
158
+/**
159
+ *
160
+ */
161
+int db_str2ulonglong(const char* _s, unsigned long long * _v)
162
+{
163
+	unsigned long long tmp;
164
+	char* p = NULL;
165
+
166
+	if (!_s || !_v) {
167
+		LM_ERR("Invalid parameter value\n");
168
+		return -1;
169
+	}
170
+
171
+	tmp = strtoull(_s, &p, 10);
172
+	if (errno == ERANGE) {
173
+		LM_ERR("Value out of range\n");
174
+		return -1;
175
+	}
176
+	if (p && *p != '\0') {
177
+		LM_ERR("Unexpected characters: [%s]\n", p);
178
+		return -2;
179
+	}
180
+
181
+	*_v = tmp;
182
+	return 0;
183
+}
184
+
185
+
123 186
 /*
124 187
  * Convert a string to double
125 188
  */
126
-inline int db_str2double(const char* _s, double* _v)
189
+int db_str2double(const char* _s, double* _v)
127 190
 {
128 191
 	if ((!_s) || (!_v)) {
129 192
 		LM_ERR("Invalid parameter value\n");
... ...
@@ -135,11 +198,10 @@ inline int db_str2double(const char* _s, double* _v)
135 198
 }
136 199
 
137 200
 
138
-
139 201
 /*
140 202
  * Convert an integer to string
141 203
  */
142
-inline int db_int2str(int _v, char* _s, int* _l)
204
+int db_int2str(int _v, char* _s, int* _l)
143 205
 {
144 206
 	int ret;
145 207
 
... ...
@@ -160,9 +222,32 @@ inline int db_int2str(int _v, char* _s, int* _l)
160 222
 
161 223
 
162 224
 /*
163
- * Convert an long long to string
225
+ * Convert an unsigned integer to string
164 226
  */
165
-inline int db_longlong2str(long long _v, char* _s, int* _l)
227
+int db_uint2str(unsigned int _v, char* _s, int* _l)
228
+{
229
+	int ret;
230
+
231
+	if ((!_s) || (!_l) || (!*_l)) {
232
+		LM_ERR("Invalid parameter value\n");
233
+		return -1;
234
+	}
235
+
236
+	ret = snprintf(_s, *_l, "%u", _v);
237
+	if (ret < 0 || ret >= *_l) {
238
+		LM_ERR("Error in snprintf\n");
239
+		return -1;
240
+	}
241
+	*_l = ret;
242
+
243
+	return 0;
244
+}
245
+
246
+
247
+/*
248
+ * Convert a long long to string
249
+ */
250
+int db_longlong2str(long long _v, char* _s, int* _l)
166 251
 {
167 252
 	int ret;
168 253
 
... ...
@@ -182,10 +267,33 @@ inline int db_longlong2str(long long _v, char* _s, int* _l)
182 267
 }
183 268
 
184 269
 
270
+/*
271
+ * Convert an unsigned long long to string
272
+ */
273
+int db_ulonglong2str(unsigned long long _v, char* _s, int* _l)
274
+{
275
+	int ret;
276
+
277
+	if ((!_s) || (!_l) || (!*_l)) {
278
+		LM_ERR("Invalid parameter value\n");
279
+		return -1;
280
+	}
281
+
282
+	ret = snprintf(_s, *_l, "%llu", _v);
283
+	if (ret < 0 || ret >= *_l) {
284
+		LM_ERR("Error in snprintf\n");
285
+		return -1;
286
+	}
287
+	*_l = ret;
288
+
289
+	return 0;
290
+}
291
+
292
+
185 293
 /*
186 294
  * Convert a double to string
187 295
  */
188
-inline int db_double2str(double _v, char* _s, int* _l)
296
+int db_double2str(double _v, char* _s, int* _l)
189 297
 {
190 298
 	int ret;
191 299
 
... ...
@@ -208,7 +316,7 @@ inline int db_double2str(double _v, char* _s, int* _l)
208 316
 /*
209 317
  * Convert a string to time_t
210 318
  */
211
-inline int db_str2time(const char* _s, time_t* _v)
319
+int db_str2time(const char* _s, time_t* _v)
212 320
 {
213 321
 	struct tm time;
214 322
 
... ...
@@ -240,7 +348,7 @@ inline int db_str2time(const char* _s, time_t* _v)
240 348
 /**
241 349
  *
242 350
  */
243
-inline int db_time2str_ex(time_t _v, char* _s, int* _l, int _qmode)
351
+int db_time2str_ex(time_t _v, char* _s, int* _l, int _qmode)
244 352
 {
245 353
 	struct tm* t;
246 354
 	int l;
... ...
@@ -275,7 +383,7 @@ inline int db_time2str_ex(time_t _v, char* _s, int* _l, int _qmode)
275 383
 /**
276 384
  *
277 385
  */
278
-inline int db_time2str(time_t _v, char* _s, int* _l)
386
+int db_time2str(time_t _v, char* _s, int* _l)
279 387
 {
280 388
 	return db_time2str_ex(_v, _s, _l, 1);
281 389
 }
Browse code

core, lib, modules: updated include paths for header files

Daniel-Constantin Mierla authored on 07/12/2016 11:07:22
Showing 1 changed files
... ...
@@ -30,7 +30,7 @@
30 30
 
31 31
 
32 32
 #if defined (__OS_darwin) || defined (__OS_freebsd)
33
-#include "../../pvar.h"
33
+#include "../../core/pvar.h"
34 34
 #endif
35 35
 
36 36
 /**
... ...
@@ -63,8 +63,8 @@
63 63
 #include <stdlib.h>
64 64
 #include <string.h>
65 65
 
66
-#include "../../mem/mem.h"
67
-#include "../../dprint.h"
66
+#include "../../core/mem/mem.h"
67
+#include "../../core/dprint.h"
68 68
 
69 69
 #include "db_ut.h"
70 70
 
Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,517 @@
1
+/*
2
+ * Copyright (C) 2001-2003 FhG Fokus
3
+ * Copyright (C) 2007-2008 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
+/**
23
+ * \file lib/srdb1/db_ut.c
24
+ * \brief Utility functions for database drivers.
25
+ *
26
+ * This utility methods are used from the database SQL driver to convert
27
+ * values and print SQL queries from the internal API representation.
28
+ * \ingroup db1
29
+ */
30
+
31
+
32
+#if defined (__OS_darwin) || defined (__OS_freebsd)
33
+#include "../../pvar.h"
34
+#endif
35
+
36
+/**
37
+ * make strptime available
38
+ * use 600 for 'Single UNIX Specification, Version 3'
39
+ * _XOPEN_SOURCE creates conflict in swab definition in Solaris
40
+ */
41
+#ifndef __OS_solaris
42
+	#define _XOPEN_SOURCE 600          /* glibc2 on linux, bsd */
43
+	#define _BSD_SOURCE 1              /* needed on linux to "fix" the effect
44
+										* of the above define on
45
+										* features.h/unistd.h syscall() */
46
+	#define _DEFAULT_SOURCE 1         /* _BSD_SOURCE is deprecated */
47
+#else
48
+	#define _XOPEN_SOURCE_EXTENDED 1   /* solaris */
49
+#endif
50
+
51
+#include <time.h>
52
+
53
+#ifndef __OS_solaris
54
+	#undef _XOPEN_SOURCE
55
+	#undef _XOPEN_SOURCE_EXTENDED
56
+#else  /* solaris */
57
+	#undef _XOPEN_SOURCE_EXTENDED
58
+#endif
59
+
60
+#include <limits.h>
61
+#include <errno.h>
62
+#include <stdio.h>
63
+#include <stdlib.h>
64
+#include <string.h>
65
+
66
+#include "../../mem/mem.h"
67
+#include "../../dprint.h"
68
+
69
+#include "db_ut.h"
70
+
71
+
72
+inline int db_str2int(const char* _s, int* _v)
73
+{
74
+	long tmp;
75
+	char* p = NULL;
76
+
77
+	if (!_s || !_v) {
78
+		LM_ERR("Invalid parameter value\n");
79
+		return -1;
80
+	}
81
+
82
+	tmp = strtoul(_s, &p, 10);
83
+	if ((tmp == ULONG_MAX && errno == ERANGE) ||
84
+				(tmp < INT_MIN) || (tmp > UINT_MAX)) {
85
+		LM_ERR("Value out of range\n");
86
+		return -1;
87
+	}
88
+	if (p && *p != '\0') {
89
+		LM_ERR("Unexpected characters: [%s]\n", p);
90
+		return -2;
91
+	}
92
+
93
+	*_v = (int)tmp;
94
+	return 0;
95
+}
96
+
97
+
98
+inline int db_str2longlong(const char* _s, long long * _v)
99
+{
100
+	long long tmp;
101
+	char* p = NULL;
102
+
103
+	if (!_s || !_v) {
104
+		LM_ERR("Invalid parameter value\n");
105
+		return -1;
106
+	}
107
+
108
+	tmp = strtoll(_s, &p, 10);
109
+	if (errno == ERANGE) {
110
+		LM_ERR("Value out of range\n");
111
+		return -1;
112
+	}
113
+	if (p && *p != '\0') {
114
+		LM_ERR("Unexpected characters: [%s]\n", p);
115
+		return -2;
116
+	}
117
+
118
+	*_v = tmp;
119
+	return 0;
120
+}
121
+
122
+
123
+/*
124
+ * Convert a string to double
125
+ */
126
+inline int db_str2double(const char* _s, double* _v)
127
+{
128
+	if ((!_s) || (!_v)) {
129
+		LM_ERR("Invalid parameter value\n");
130
+		return -1;
131
+	}
132
+
133
+	*_v = atof(_s);
134
+	return 0;
135
+}
136
+
137
+
138
+
139
+/*
140
+ * Convert an integer to string
141
+ */
142
+inline int db_int2str(int _v, char* _s, int* _l)
143
+{
144
+	int ret;
145
+
146
+	if ((!_s) || (!_l) || (!*_l)) {
147
+		LM_ERR("Invalid parameter value\n");
148
+		return -1;
149
+	}
150
+
151
+	ret = snprintf(_s, *_l, "%-d", _v);
152
+	if (ret < 0 || ret >= *_l) {
153
+		LM_ERR("Error in snprintf\n");
154
+		return -1;
155
+	}
156
+	*_l = ret;
157
+
158
+	return 0;
159
+}
160
+
161
+
162
+/*
163
+ * Convert an long long to string
164
+ */
165
+inline int db_longlong2str(long long _v, char* _s, int* _l)
166
+{
167
+	int ret;
168
+
169
+	if ((!_s) || (!_l) || (!*_l)) {
170
+		LM_ERR("Invalid parameter value\n");
171
+		return -1;
172
+	}
173
+
174
+	ret = snprintf(_s, *_l, "%-lld", _v);
175
+	if (ret < 0 || ret >= *_l) {
176
+		LM_ERR("Error in snprintf\n");
177
+		return -1;
178
+	}
179
+	*_l = ret;
180
+
181
+	return 0;
182
+}
183
+
184
+
185
+/*
186
+ * Convert a double to string
187
+ */
188
+inline int db_double2str(double _v, char* _s, int* _l)
189
+{
190
+	int ret;
191
+
192
+	if ((!_s) || (!_l) || (!*_l)) {
193
+		LM_ERR("Invalid parameter value\n");
194
+		return -1;
195
+	}
196
+
197
+	ret = snprintf(_s, *_l, "%-10.6f", _v);
198
+	if (ret < 0 || ret >= *_l) {
199
+		LM_ERR("Error in snprintf\n");
200
+		return -1;
201
+	}
202
+	*_l = ret;
203
+
204
+	return 0;
205
+}
206
+
207
+
208
+/*
209
+ * Convert a string to time_t
210
+ */
211
+inline int db_str2time(const char* _s, time_t* _v)
212
+{
213
+	struct tm time;
214
+
215
+	if ((!_s) || (!_v)) {
216
+		LM_ERR("Invalid parameter value\n");
217
+		return -1;
218
+	}
219
+
220
+	/* Convert database time representation to time_t structure
221
+	 * It is necessary to zero tm structure first */
222
+	memset(&time, '\0', sizeof(struct tm));
223
+	if (strptime(_s, "%Y-%m-%d %H:%M:%S", &time) == NULL) {
224
+		LM_ERR("Error during time conversion\n");
225
+		return -1;
226
+	}
227
+
228
+	/* Daylight saving information got lost in the database
229
+	* so let mktime to guess it. This eliminates the bug when
230
+	* contacts reloaded from the database have different time
231
+	* of expiration by one hour when daylight saving is used
232
+	*/
233
+	time.tm_isdst = -1;
234
+	*_v = mktime(&time);
235
+
236
+	return 0;
237
+}
238
+
239
+
240
+/**
241
+ *
242
+ */
243
+inline int db_time2str_ex(time_t _v, char* _s, int* _l, int _qmode)
244
+{
245
+	struct tm* t;
246
+	int l;
247
+
248
+	if ((!_s) || (!_l) || (*_l < 2)) {
249
+		LM_ERR("Invalid parameter value\n");
250
+		return -1;
251
+	}
252
+
253
+	if(_qmode) *_s++ = '\'';
254
+
255
+	/* Convert time_t structure to format accepted by the database */
256
+	t = localtime(&_v);
257
+	l = strftime(_s, *_l -1, "%Y-%m-%d %H:%M:%S", t);
258
+
259
+	if (l == 0) {
260
+		LM_ERR("Error during time conversion\n");
261
+		/* the value of _s is now unspecified */
262
+		_s = NULL;
263
+		_l = 0;
264
+		return -1;
265
+	}
266
+	*_l = l;
267
+
268
+	if(_qmode) {
269
+		*(_s + l) = '\'';
270
+		*_l = l + 2;
271
+	}
272
+	return 0;
273
+}
274
+
275
+/**
276
+ *
277
+ */
278
+inline int db_time2str(time_t _v, char* _s, int* _l)
279
+{
280
+	return db_time2str_ex(_v, _s, _l, 1);
281
+}
282
+
283
+/*
284
+ * Print list of columns separated by comma
285
+ */
286
+int db_print_columns(char* _b, const int _l, const db_key_t* _c, const int _n, const char *_tq)
287
+{
288
+	int i, ret, len = 0;
289
+
290
+	if ((!_c) || (!_n) || (!_b) || (!_l)) {
291
+		LM_ERR("Invalid parameter value\n");
292
+		return -1;
293
+	}
294
+
295
+	for(i = 0; i < _n; i++)	{
296
+		if (i == (_n - 1)) {
297
+			ret = snprintf(_b + len, _l - len, "%s%.*s%s ", _tq, _c[i]->len, _c[i]->s, _tq);
298
+			if (ret < 0 || ret >= (_l - len)) goto error;
299
+			len += ret;
300
+		} else {
301
+			ret = snprintf(_b + len, _l - len, "%s%.*s%s,", _tq, _c[i]->len, _c[i]->s, _tq);
302
+			if (ret < 0 || ret >= (_l - len)) goto error;
303
+			len += ret;
304
+		}
305
+	}
306
+	return len;
307
+
308
+	error:
309
+	LM_ERR("Error in snprintf\n");
310
+	return -1;
311
+}
312
+
313
+
314
+/*
315
+ * Print values of SQL statement
316
+ */
317
+int db_print_values(const db1_con_t* _c, char* _b, const int _l, const db_val_t* _v,
318
+	const int _n, int (*val2str)(const db1_con_t*, const db_val_t*, char*, int*))
319
+{
320
+	int i, l, len = 0;
321
+
322
+	if (!_c || !_b || !_l || !_v || !_n) {
323
+		LM_ERR("Invalid parameter value\n");
324
+		return -1;
325
+	}
326
+
327
+	for(i = 0; i < _n; i++) {
328
+		l = _l - len;
329
+		if ( (*val2str)(_c, _v + i, _b + len, &l) < 0) {
330
+			LM_ERR("Error while converting value to string\n");
331
+			return -1;
332
+		}
333
+		len += l;
334
+		if (i != (_n - 1)) {
335
+			*(_b + len) = ',';
336
+			len++;
337
+		}
338
+	}
339
+	return len;
340
+}
341
+
342
+
343
+/*
344
+ * Print where clause of SQL statement
345
+ */
346
+int db_print_where(const db1_con_t* _c, char* _b, const int _l, const db_key_t* _k,
347
+	const db_op_t* _o, const db_val_t* _v, const int _n, int (*val2str)
348
+	(const 	db1_con_t*, const db_val_t*, char*, int*))
349
+{
350
+	int i, l, ret, len = 0;
351
+
352
+	if (!_c || !_b || !_l || !_k || !_v || !_n) {
353
+		LM_ERR("Invalid parameter value\n");
354
+		return -1;
355
+	}
356
+
357
+	for(i = 0; i < _n; i++) {
358
+		if (_o && strncmp(_o[i], OP_BITWISE_AND, 1) == 0) {
359
+			char tmp_buf[16];
360
+			int tmp_len = 15;
361
+			memset(tmp_buf, 0, 16);
362
+			if ((*val2str)(_c, &(_v[i]), tmp_buf, &tmp_len) < 0) {
363
+				LM_ERR("Error while converting value to string\n");
364
+				return -1;
365
+			}
366
+			ret = snprintf(_b + len, _l - len, "%s%.*s%s&%.*s=%.*s", CON_TQUOTESZ(_c),
367
+					_k[i]->len, _k[i]->s, CON_TQUOTESZ(_c), tmp_len, tmp_buf, tmp_len, tmp_buf);
368
+			if (ret < 0 || ret >= (_l - len)) goto error;
369
+			len += ret;
370
+		} else {
371
+			if (_o) {
372
+				ret = snprintf(_b + len, _l - len, "%s%.*s%s%s", CON_TQUOTESZ(_c),
373
+						_k[i]->len, _k[i]->s, CON_TQUOTESZ(_c), _o[i]);
374
+				if (ret < 0 || ret >= (_l - len)) goto error;
375
+				len += ret;
376
+			} else {
377
+				ret = snprintf(_b + len, _l - len, "%s%.*s%s=", CON_TQUOTESZ(_c),
378
+						_k[i]->len, _k[i]->s, CON_TQUOTESZ(_c));
379
+				if (ret < 0 || ret >= (_l - len)) goto error;
380
+				len += ret;
381
+			}
382
+			l = _l - len;
383
+			if ( (*val2str)(_c, &(_v[i]), _b + len, &l) < 0) {
384
+				LM_ERR("Error while converting value to string\n");
385
+				return -1;
386
+			}
387
+			len += l;
388
+		}
389
+
390
+		if (i != (_n - 1)) {
391
+			ret = snprintf(_b + len, _l - len, " AND ");
392
+			if (ret < 0 || ret >= (_l - len)) goto error;
393
+			len += ret;
394
+		}
395
+	}
396
+	return len;
397
+
398
+error:
399
+	LM_ERR("Error in snprintf\n");
400
+	return -1;
401
+}
402
+
403
+
404
+/*
405
+ * Print set clause of update SQL statement
406
+ */
407
+int db_print_set(const db1_con_t* _c, char* _b, const int _l, const db_key_t* _k,
408
+	const db_val_t* _v, const int _n, int (*val2str)(const db1_con_t*,
409
+	const db_val_t*,char*, int*))
410
+{
411
+	int i, l, ret, len = 0;
412
+
413
+	if (!_c || !_b || !_l || !_k || !_v || !_n) {
414
+		LM_ERR("Invalid parameter value\n");
415
+		return -1;
416
+	}
417
+
418
+	for(i = 0; i < _n; i++) {
419
+		ret = snprintf(_b + len, _l - len, "%s%.*s%s=",
420
+				CON_TQUOTESZ(_c), _k[i]->len, _k[i]->s, CON_TQUOTESZ(_c));
421
+		if (ret < 0 || ret >= (_l - len)) goto error;
422
+		len += ret;
423
+
424
+		l = _l - len;
425
+		if ( (*val2str)(_c, &(_v[i]), _b + len, &l) < 0) {
426
+			LM_ERR("Error while converting value to string\n");
427
+			return -1;
428
+		}
429
+		len += l;
430
+		if (i != (_n - 1)) {
431
+			if ((_l - len) >= 1) {
432
+				*(_b + len++) = ',';
433
+			}
434
+		}
435
+	}
436
+	return len;
437
+
438
+error:
439
+	LM_ERR("Error in snprintf\n");
440
+	return -1;
441
+}
442
+
443
+/*
444
+ * Convert db_val to pv_spec
445
+ */
446
+int db_val2pv_spec(struct sip_msg* msg, db_val_t *dbval, pv_spec_t *pvs)
447
+{
448
+	pv_value_t pv;
449
+#define LL_LEN 21   /* sign, 19 digits and \0 */
450
+	static char ll_buf[LL_LEN];
451
+
452
+	if(dbval->nul)
453
+	{
454
+		pv.flags = PV_VAL_NULL;
455
+	} else
456
+	{
457
+		switch(dbval->type)
458
+		{
459
+			case DB1_STRING:
460
+				pv.flags = PV_VAL_STR;
461
+				pv.rs.s = (char*)dbval->val.string_val;
462
+				pv.rs.len = strlen(pv.rs.s);
463
+			break;
464
+			case DB1_STR:
465
+				pv.flags = PV_VAL_STR;
466
+				pv.rs.s = (char*)dbval->val.str_val.s;
467
+				pv.rs.len = dbval->val.str_val.len;
468
+			break;
469
+			case DB1_BLOB:
470
+				pv.flags = PV_VAL_STR;
471
+				pv.rs.s = (char*)dbval->val.blob_val.s;
472
+				pv.rs.len = dbval->val.blob_val.len;
473
+			break;
474
+			case DB1_INT:
475
+				pv.flags = PV_VAL_INT | PV_TYPE_INT;
476
+				pv.ri = (int)dbval->val.int_val;
477
+			break;
478
+			case DB1_DATETIME:
479
+				pv.flags = PV_VAL_INT | PV_TYPE_INT;
480
+				pv.ri = (int)dbval->val.time_val;
481
+			break;
482
+			case DB1_BITMAP:
483
+				pv.flags = PV_VAL_INT | PV_TYPE_INT;
484
+				pv.ri = (int)dbval->val.bitmap_val;
485
+			break;
486
+			case DB1_BIGINT:
487
+				/* BIGINT is stored as string */
488
+				pv.flags = PV_VAL_STR;
489
+				pv.rs.len = LL_LEN;
490
+				db_longlong2str(dbval->val.ll_val, ll_buf, &pv.rs.len);
491
+				pv.rs.s = ll_buf;
492
+				/* if it fits, also store as 32 bit integer*/
493
+				if (! ((unsigned long long)dbval->val.ll_val & 0xffffffff00000000ULL)) {
494
+					pv.flags |= PV_VAL_INT | PV_TYPE_INT;
495
+					pv.ri = (int)dbval->val.ll_val;
496
+				}
497
+			break;
498
+			default:
499
+				LM_NOTICE("unknown field type: %d, setting value to null\n",
500
+							dbval->type);
501
+				pv.flags = PV_VAL_NULL;
502
+		}
503
+	}
504
+
505
+	/* null values are ignored for avp type PV */
506
+	if (pv.flags == PV_VAL_NULL && pvs->type == PVT_AVP)
507
+		return 0;
508
+
509
+	/* add value to result pv */
510
+	if (pv_set_spec_value(msg, pvs, 0, &pv) != 0)
511
+	{
512
+		LM_ERR("Failed to add value to spec\n");
513
+		return -1;
514
+	}
515
+
516
+	return 0;
517
+}