db_postgres/km_val.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
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 
00037 #include "../../lib/srdb1/db_val.h"
00038 #include "../../lib/srdb1/db_ut.h"
00039 #include "../../dprint.h"
00040 #include "km_pg_con.h"
00041 
00042 #include "../../mem/mem.h"
00043 #include "km_val.h"
00044 
00045 
00058 int db_postgres_str2val(const db_type_t _t, db_val_t* _v, const char* _s,
00059                 const int _l)
00060 {
00061         /* use common function for non BLOB, NULL setting and input
00062          * parameter checking */
00063         if ( _t != DB1_BLOB || _s == NULL || _v == NULL) {
00064                 return db_str2val(_t, _v, _s, _l, 1);
00065         } else {
00066                 char * tmp_s = NULL;
00067                 LM_DBG("converting BLOB [%.*s]\n", _l, _s);
00068                 /*
00069                  * The string is stored in new allocated memory, which we could
00070                  * not free later thus we need to copy it to some new memory here.
00071                  */
00072                 tmp_s = (char*)PQunescapeBytea((unsigned char*)_s,
00073                                         (size_t*)(void*)&(VAL_BLOB(_v).len));
00074                 if(tmp_s==NULL) {
00075                         LM_ERR("PQunescapeBytea failed\n");
00076                         return -7;
00077                 }
00078                 VAL_BLOB(_v).s = pkg_malloc(VAL_BLOB(_v).len + 1);
00079                 if (VAL_BLOB(_v).s == NULL) {
00080                         LM_ERR("no private memory left\n");
00081                         PQfreemem(tmp_s);
00082                         return -8;
00083                 }
00084                 LM_DBG("allocate %d+1 bytes memory for BLOB at %p",
00085                                 VAL_BLOB(_v).len, VAL_BLOB(_v).s);
00086                 memcpy(VAL_BLOB(_v).s, tmp_s, VAL_BLOB(_v).len);
00087                 PQfreemem(tmp_s);
00088 
00089                 VAL_BLOB(_v).s[VAL_BLOB(_v).len] = '\0';
00090                 VAL_TYPE(_v) = DB1_BLOB;
00091                 VAL_FREE(_v) = 1;
00092 
00093                 LM_DBG("got blob len %d\n", _l);
00094                 return 0;
00095 
00096         }
00097 }
00098 
00099 
00110 int db_postgres_val2str(const db1_con_t* _con, const db_val_t* _v, char* _s, int* _len)
00111 {
00112         int l, ret, tmp;
00113         int pgret;
00114         char *tmp_s;
00115         size_t tmp_len;
00116         char* old_s;
00117 
00118         tmp = db_val2str(_con, _v, _s, _len);
00119         if (tmp < 1)
00120                 return tmp;
00121 
00122         switch(VAL_TYPE(_v)) {
00123         case DB1_STRING:
00124                 l = strlen(VAL_STRING(_v));
00125                 if (*_len < (l * 2 + 3)) {
00126                         LM_ERR("destination buffer too short for string\n");
00127                         return -6;
00128                 } else {
00129                         old_s = _s;
00130                         *_s++ = '\'';
00131                         ret = PQescapeStringConn(CON_CONNECTION(_con), _s, VAL_STRING(_v),
00132                                         l, &pgret);
00133                         if(pgret!=0)
00134                         {
00135                                 LM_ERR("PQescapeStringConn failed\n");
00136                                 return -6;
00137                         }
00138                         LM_DBG("PQescapeStringConn: in: %d chars,"
00139                                 " out: %d chars\n", l, ret);
00140                         _s += ret;
00141                         *_s++ = '\'';
00142                         *_s = '\0'; /* FIXME */
00143                         *_len = _s - old_s;
00144                         return 0;
00145                 }
00146                 break;
00147 
00148         case DB1_STR:
00149                 l = VAL_STR(_v).len;
00150                 if (*_len < (l * 2 + 3)) {
00151                         LM_ERR("destination buffer too short for str\n");
00152                         return -7;
00153                 } else {
00154                         old_s = _s;
00155                         *_s++ = '\'';
00156                         ret = PQescapeStringConn(CON_CONNECTION(_con), _s, VAL_STRING(_v),
00157                                         l, &pgret);
00158                         if(pgret!=0)
00159                         {
00160                                 LM_ERR("PQescapeStringConn failed \n");
00161                                 return -7;
00162                         }
00163                 LM_DBG("PQescapeStringConn: in: %d chars, out: %d chars\n", l, ret);
00164                         _s += ret;
00165                         *_s++ = '\'';
00166                         *_s = '\0'; /* FIXME */
00167                         *_len = _s - old_s;
00168                         return 0;
00169                 }
00170                 break;
00171 
00172         case DB1_BLOB:
00173                 l = VAL_BLOB(_v).len;
00174                 /* this estimation is not always correct, thus we need to check later again */
00175                 if (*_len < (l * 2 + 3)) {
00176                         LM_ERR("destination buffer too short for blob\n");
00177                         return -9;
00178                 } else {
00179                         *_s++ = '\'';
00180                         tmp_s = (char*)PQescapeByteaConn(CON_CONNECTION(_con), (unsigned char*)VAL_STRING(_v),
00181                                         (size_t)l, (size_t*)&tmp_len);
00182                         if(tmp_s==NULL)
00183                         {
00184                                 LM_ERR("PQescapeByteaConn failed\n");
00185                                 return -9;
00186                         }
00187                         if (tmp_len > *_len) {
00188                                 LM_ERR("escaped result too long\n");
00189                                 return -9;
00190                         }
00191                         memcpy(_s, tmp_s, tmp_len);
00192                         PQfreemem(tmp_s);
00193                         tmp_len = strlen(_s);
00194                         *(_s + tmp_len) = '\'';
00195                         *(_s + tmp_len + 1) = '\0';
00196                         *_len = tmp_len + 2;
00197                         return 0;
00198                 }
00199                 break;
00200 
00201         default:
00202                 LM_DBG("unknown data type\n");
00203                 return -10;
00204         }
00205 }