db_ut.c

Go to the documentation of this file.
00001 /*
00002  * $Id: db_ut.c 4941 2008-09-17 14:46:05Z henningw $
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  * Copyright (C) 2007-2008 1&1 Internet AG
00006  *
00007  * This file is part of Kamailio, a free SIP server.
00008  *
00009  * Kamailio is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version
00013  *
00014  * Kamailio is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License 
00020  * along with this program; if not, write to the Free Software 
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  */
00023 
00024 /**
00025  * \file db/db_ut.c
00026  * \brief Utility functions for database drivers.
00027  *
00028  * This utility methods are used from the database SQL driver to convert
00029  * values and print SQL queries from the internal API representation.
00030  * \ingroup db
00031  */
00032 
00033 #include "db_ut.h"
00034 
00035 #include "../mem/mem.h"
00036 #include "../dprint.h"
00037 #include <limits.h>
00038 #include </usr/include/limits.h>
00039 #include <errno.h>
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 
00044 
00045 inline int db_str2int(const char* _s, int* _v)
00046 {
00047    long tmp;
00048 
00049    if (!_s || !_v) {
00050           LM_ERR("Invalid parameter value\n");
00051           return -1;
00052    }
00053 
00054    tmp = strtoul(_s, 0, 10);
00055    if ((tmp == ULONG_MAX && errno == ERANGE) || 
00056        (tmp < INT_MIN) || (tmp > UINT_MAX)) {
00057       LM_ERR("Value out of range\n");
00058       return -1;
00059    }
00060 
00061    *_v = (int)tmp;
00062    return 0;
00063 }
00064 
00065 
00066 inline int db_str2longlong(const char* _s, long long * _v)
00067 {
00068    long long tmp;
00069 
00070    if (!_s || !_v) {
00071           LM_ERR("Invalid parameter value\n");
00072           return -1;
00073    }
00074 
00075    tmp = strtoll(_s, 0, 10);
00076    if (errno == ERANGE) {
00077       LM_ERR("Value out of range\n");
00078       return -1;
00079    }
00080 
00081    *_v = tmp;
00082    return 0;
00083 }
00084 
00085 
00086 /*
00087  * Convert a string to double
00088  */
00089 inline int db_str2double(const char* _s, double* _v)
00090 {
00091    if ((!_s) || (!_v)) {
00092       LM_ERR("Invalid parameter value\n");
00093       return -1;
00094    }
00095 
00096    *_v = atof(_s);
00097    return 0;
00098 }
00099 
00100 
00101 
00102 /*
00103  * Convert an integer to string
00104  */
00105 inline int db_int2str(int _v, char* _s, int* _l)
00106 {
00107    int ret;
00108 
00109    if ((!_s) || (!_l) || (!*_l)) {
00110       LM_ERR("Invalid parameter value\n");
00111       return -1;
00112    }
00113 
00114    ret = snprintf(_s, *_l, "%-d", _v);
00115    if (ret < 0 || ret >= *_l) {
00116       LM_ERR("Error in snprintf\n");
00117       return -1;
00118    }
00119    *_l = ret;
00120 
00121    return 0;
00122 }
00123 
00124 
00125 /*
00126  * Convert an long long to string
00127  */
00128 inline int db_longlong2str(long long _v, char* _s, int* _l)
00129 {
00130    int ret;
00131 
00132    if ((!_s) || (!_l) || (!*_l)) {
00133       LM_ERR("Invalid parameter value\n");
00134       return -1;
00135    }
00136 
00137    ret = snprintf(_s, *_l, "%-lld", _v);
00138    if (ret < 0 || ret >= *_l) {
00139       LM_ERR("Error in snprintf\n");
00140       return -1;
00141    }
00142    *_l = ret;
00143 
00144    return 0;
00145 }
00146 
00147 
00148 /*
00149  * Convert a double to string
00150  */
00151 inline int db_double2str(double _v, char* _s, int* _l)
00152 {
00153    int ret;
00154 
00155    if ((!_s) || (!_l) || (!*_l)) {
00156       LM_ERR("Invalid parameter value\n");
00157       return -1;
00158    }
00159 
00160    ret = snprintf(_s, *_l, "%-10.2f", _v);
00161    if (ret < 0 || ret >= *_l) {
00162       LM_ERR("Error in snprintf\n");
00163       return -1;
00164    }
00165    *_l = ret;
00166 
00167    return 0;
00168 }
00169 
00170 
00171 /* 
00172  * Convert a string to time_t
00173  */
00174 inline int db_str2time(const char* _s, time_t* _v)
00175 {
00176    struct tm time;
00177 
00178    if ((!_s) || (!_v)) {
00179       LM_ERR("Invalid parameter value\n");
00180       return -1;
00181    }
00182 
00183    /* Convert database time representation to time_t structure
00184       It is necessary to zero tm structure first */
00185    memset(&time, '\0', sizeof(struct tm));
00186    if (strptime(_s, "%Y-%m-%d %H:%M:%S", &time) == NULL) {
00187       LM_ERR("Error during time conversion\n");
00188       return -1;
00189    }
00190 
00191    /* Daylight saving information got lost in the database
00192    * so let mktime to guess it. This eliminates the bug when
00193    * contacts reloaded from the database have different time
00194    * of expiration by one hour when daylight saving is used
00195    */ 
00196    time.tm_isdst = -1;
00197    *_v = mktime(&time);
00198 
00199    return 0;
00200 }
00201 
00202 
00203 inline int db_time2str(time_t _v, char* _s, int* _l)
00204 {
00205    struct tm* t;
00206    int l;
00207 
00208    if ((!_s) || (!_l) || (*_l < 2)) {
00209       LM_ERR("Invalid parameter value\n");
00210       return -1;
00211    }
00212 
00213    *_s++ = '\'';
00214 
00215    /* Convert time_t structure to format accepted by the database */
00216    t = localtime(&_v);
00217    l = strftime(_s, *_l -1, "%Y-%m-%d %H:%M:%S", t);
00218 
00219    if (l == 0) {
00220       LM_ERR("Error during time conversion\n");
00221       /* the value of _s is now unspecified */
00222       _s = NULL;
00223       _l = 0;
00224       return -1;
00225    }
00226    *_l = l;
00227 
00228    *(_s + l) = '\'';
00229    *_l = l + 2;
00230    return 0;
00231 }
00232 
00233 
00234 /*
00235  * Print list of columns separated by comma
00236  */
00237 inline int db_print_columns(char* _b, const int _l, const db_key_t* _c, const int _n)
00238 {
00239    int i, ret, len = 0;
00240 
00241    if ((!_c) || (!_n) || (!_b) || (!_l)) {
00242       LM_ERR("Invalid parameter value\n");
00243       return -1;
00244    }
00245 
00246    for(i = 0; i < _n; i++) {
00247       if (i == (_n - 1)) {
00248          ret = snprintf(_b + len, _l - len, "%.*s ", _c[i]->len, _c[i]->s);
00249          if (ret < 0 || ret >= (_l - len)) goto error;
00250          len += ret;
00251       } else {
00252          ret = snprintf(_b + len, _l - len, "%.*s,", _c[i]->len, _c[i]->s);
00253          if (ret < 0 || ret >= (_l - len)) goto error;
00254          len += ret;
00255       }
00256    }
00257    return len;
00258 
00259    error:
00260    LM_ERR("Error in snprintf\n");
00261    return -1;
00262 }
00263 
00264 
00265 /*
00266  * Print values of SQL statement
00267  */
00268 int db_print_values(const db_con_t* _c, char* _b, const int _l, const db_val_t* _v,
00269    const int _n, int (*val2str)(const db_con_t*, const db_val_t*, char*, int*))
00270 {
00271    int i, l, len = 0;
00272 
00273    if (!_c || !_b || !_l || !_v || !_n) {
00274       LM_ERR("Invalid parameter value\n");
00275       return -1;
00276    }
00277 
00278    for(i = 0; i < _n; i++) {
00279       l = _l - len;
00280       if ( (*val2str)(_c, _v + i, _b + len, &l) < 0) {
00281          LM_ERR("Error while converting value to string\n");
00282          return -1;
00283       }
00284       len += l;
00285       if (i != (_n - 1)) {
00286          *(_b + len) = ',';
00287          len++;
00288       }
00289    }
00290    return len;
00291 }
00292 
00293 
00294 /*
00295  * Print where clause of SQL statement
00296  */
00297 int db_print_where(const db_con_t* _c, char* _b, const int _l, const db_key_t* _k,
00298    const db_op_t* _o, const db_val_t* _v, const int _n, int (*val2str)
00299    (const   db_con_t*, const db_val_t*, char*, int*))
00300 {
00301    int i, l, ret, len = 0;
00302 
00303    if (!_c || !_b || !_l || !_k || !_v || !_n) {
00304       LM_ERR("Invalid parameter value\n");
00305       return -1;
00306    }
00307 
00308    for(i = 0; i < _n; i++) {
00309       if (_o) {
00310          ret = snprintf(_b + len, _l - len, "%.*s%s", _k[i]->len, _k[i]->s, _o[i]);
00311          if (ret < 0 || ret >= (_l - len)) goto error;
00312          len += ret;
00313       } else {
00314          ret = snprintf(_b + len, _l - len, "%.*s=", _k[i]->len, _k[i]->s);
00315          if (ret < 0 || ret >= (_l - len)) goto error;
00316          len += ret;
00317       }
00318       l = _l - len;
00319       if ( (*val2str)(_c, &(_v[i]), _b + len, &l) < 0) {
00320          LM_ERR("Error while converting value to string\n");
00321          return -1;
00322       }
00323       len += l;
00324       if (i != (_n - 1)) {
00325          ret = snprintf(_b + len, _l - len, " AND ");
00326          if (ret < 0 || ret >= (_l - len)) goto error;
00327          len += ret;
00328       }
00329    }
00330    return len;
00331 
00332  error:
00333    LM_ERR("Error in snprintf\n");
00334    return -1;
00335 }
00336 
00337 
00338 /*
00339  * Print set clause of update SQL statement
00340  */
00341 int db_print_set(const db_con_t* _c, char* _b, const int _l, const db_key_t* _k,
00342    const db_val_t* _v, const int _n, int (*val2str)(const db_con_t*,
00343    const db_val_t*,char*, int*))
00344 {
00345    int i, l, ret, len = 0;
00346 
00347    if (!_c || !_b || !_l || !_k || !_v || !_n) {
00348       LM_ERR("Invalid parameter value\n");
00349       return -1;
00350    }
00351 
00352    for(i = 0; i < _n; i++) {
00353       ret = snprintf(_b + len, _l - len, "%.*s=", _k[i]->len, _k[i]->s);
00354       if (ret < 0 || ret >= (_l - len)) goto error;
00355       len += ret;
00356 
00357       l = _l - len;
00358       if ( (*val2str)(_c, &(_v[i]), _b + len, &l) < 0) {
00359          LM_ERR("Error while converting value to string\n");
00360          return -1;
00361       }
00362       len += l;
00363       if (i != (_n - 1)) {
00364          if ((_l - len) >= 1) {
00365             *(_b + len++) = ',';
00366          }
00367       }
00368    }
00369    return len;
00370 
00371  error:
00372    LM_ERR("Error in snprintf\n");
00373    return -1;
00374 }

Generated on Tue May 22 14:00:25 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6