db_postgres/val.c

Go to the documentation of this file.
00001 /*
00002  * $Id: val.c 5459 2009-01-14 13:58:51Z henningw $
00003  *
00004  * Copyright (C) 2003 August.Net Services, LLC
00005  * Copyright (C) 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  * History
00024  * -------
00025  * 2003-04-06 initial code written (Greg Fausak/Andy Fullford)
00026  * 2003-04-14 gmtime changed to localtime because mktime later
00027  *            expects localtime, changed daylight saving bug
00028  *            previously found in mysql module (janakj)
00029  */
00030 
00031 /*! \file
00032  *  \brief DB_POSTGRES :: Core
00033  *  \ingroup db_postgres
00034  *  Module: \ref db_postgres
00035  */
00036 
00037 #include "../../db/db_val.h"
00038 #include "../../db/db_ut.h"
00039 #include "../../dprint.h"
00040 #include "pg_con.h"
00041 
00042 #include "../../mem/mem.h"
00043 #include "val.h"
00044 
00045 
00046 /*!
00047  * \brief Convert a str to a db value, copy strings
00048  *
00049  * Convert a str to a db value, copy strings.
00050  * The postgresql module uses a custom escape function for BLOBs.
00051  * If the _s is linked in the db_val result, it will be returned zero
00052  * \param _t destination value type
00053  * \param _v destination value
00054  * \param _s source string
00055  * \param _l string length
00056  * \return 0 on success, negative on error
00057  */
00058 int db_postgres_str2val(const db_type_t _t, db_val_t* _v, const char* _s, const int _l)
00059 {
00060    /* use common function for non BLOB, NULL setting and input parameter checking */
00061    if ( _t != DB_BLOB || _s == NULL || _v == NULL) {
00062       return db_str2val(_t, _v, _s, _l, 1);
00063    } else {
00064       char * tmp_s = NULL;
00065       LM_DBG("converting BLOB [%.*s]\n", _l, _s);
00066       /*
00067        * The string is stored in new allocated memory, which we could
00068        * not free later thus we need to copy it to some new memory here.
00069        */
00070       tmp_s = (char*)PQunescapeBytea((unsigned char*)_s, (size_t*)(void*)&(VAL_BLOB(_v).len));
00071       if(tmp_s==NULL) {
00072          LM_ERR("PQunescapeBytea failed\n");
00073          return -7;
00074       }
00075       VAL_BLOB(_v).s = pkg_malloc(VAL_BLOB(_v).len);
00076       if (VAL_BLOB(_v).s == NULL) {
00077          LM_ERR("no private memory left\n");
00078          PQfreemem(tmp_s);
00079          return -8;
00080       }
00081       LM_DBG("allocate %d bytes memory for BLOB at %p", VAL_BLOB(_v).len, VAL_BLOB(_v).s);
00082       memcpy(VAL_BLOB(_v).s, tmp_s, VAL_BLOB(_v).len);
00083       PQfreemem(tmp_s);
00084 
00085       VAL_TYPE(_v) = DB_BLOB;
00086       VAL_FREE(_v) = 1;
00087 
00088       LM_DBG("got blob len %d\n", _l);
00089       return 0;
00090 
00091    }
00092 }
00093 
00094 
00095 /*!
00096  * \brief Converting a value to a string
00097  *
00098  * Converting a value to a string, used when converting result from a query
00099  * \param _con database connection
00100  * \param _v source value
00101  * \param _s target string
00102  * \param _len target string length
00103  * \return 0 on success, negative on error
00104  */
00105 int db_postgres_val2str(const db_con_t* _con, const db_val_t* _v, char* _s, int* _len)
00106 {
00107    int l, ret, tmp;
00108    int pgret;
00109    char *tmp_s;
00110    size_t tmp_len;
00111    char* old_s;
00112 
00113    tmp = db_val2str(_con, _v, _s, _len);
00114    if (tmp < 1)
00115       return tmp;
00116 
00117    switch(VAL_TYPE(_v)) {
00118    case DB_STRING:
00119       l = strlen(VAL_STRING(_v));
00120       if (*_len < (l * 2 + 3)) {
00121          LM_ERR("destination buffer too short for string\n");
00122          return -6;
00123       } else {
00124          old_s = _s;
00125          *_s++ = '\'';
00126          ret = PQescapeStringConn(CON_CONNECTION(_con), _s, VAL_STRING(_v),
00127                l, &pgret);
00128          if(pgret!=0)
00129          {
00130             LM_ERR("PQescapeStringConn failed\n");
00131             return -6;
00132          }
00133          LM_DBG("PQescapeStringConn: in: %d chars,"
00134             " out: %d chars\n", l, ret);
00135          _s += ret;
00136          *_s++ = '\'';
00137          *_s = '\0'; /* FIXME */
00138          *_len = _s - old_s;
00139          return 0;
00140       }
00141       break;
00142 
00143    case DB_STR:
00144       l = VAL_STR(_v).len;
00145       if (*_len < (l * 2 + 3)) {
00146          LM_ERR("destination buffer too short for str\n");
00147          return -7;
00148       } else {
00149          old_s = _s;
00150          *_s++ = '\'';
00151          ret = PQescapeStringConn(CON_CONNECTION(_con), _s, VAL_STRING(_v),
00152                l, &pgret);
00153          if(pgret!=0)
00154          {
00155             LM_ERR("PQescapeStringConn failed \n");
00156             return -7;
00157          }
00158            LM_DBG("PQescapeStringConn: in: %d chars, out: %d chars\n", l, ret);
00159          _s += ret;
00160          *_s++ = '\'';
00161          *_s = '\0'; /* FIXME */
00162          *_len = _s - old_s;
00163          return 0;
00164       }
00165       break;
00166 
00167    case DB_BLOB:
00168       l = VAL_BLOB(_v).len;
00169       /* this estimation is not always correct, thus we need to check later again */
00170       if (*_len < (l * 2 + 3)) {
00171          LM_ERR("destination buffer too short for blob\n");
00172          return -9;
00173       } else {
00174          *_s++ = '\'';
00175          tmp_s = (char*)PQescapeByteaConn(CON_CONNECTION(_con), (unsigned char*)VAL_STRING(_v),
00176                (size_t)l, (size_t*)&tmp_len);
00177          if(tmp_s==NULL)
00178          {
00179             LM_ERR("PQescapeByteaConn failed\n");
00180             return -9;
00181          }
00182          if (tmp_len > *_len) {
00183             LM_ERR("escaped result too long\n");
00184             return -9;
00185          }
00186          memcpy(_s, tmp_s, tmp_len);
00187          PQfreemem(tmp_s);
00188          tmp_len = strlen(_s);
00189          *(_s + tmp_len) = '\'';
00190          *(_s + tmp_len + 1) = '\0';
00191          *_len = tmp_len + 2;
00192          return 0;
00193       }
00194       break;
00195 
00196    default:
00197       LM_DBG("unknown data type\n");
00198       return -10;
00199    }
00200 }

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