dbt_api.c

Go to the documentation of this file.
00001 /*
00002  * $Id: dbt_api.c 5362 2008-12-15 16:33:22Z henningw $
00003  *
00004  * DBText library
00005  *
00006  * Copyright (C) 2001-2003 FhG Fokus
00007  *
00008  * This file is part of Kamailio, a free SIP server.
00009  *
00010  * Kamailio is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version
00014  *
00015  * Kamailio is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License 
00021  * along with this program; if not, write to the Free Software 
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  * History:
00025  * --------
00026  * 2003-02-05  created by Daniel
00027  * 
00028  */
00029 
00030 #include <string.h>
00031 
00032 #include "../../db/db.h"
00033 #include "../../mem/mem.h"
00034 
00035 #include "dbt_res.h"
00036 #include "dbt_api.h"
00037 
00038 int dbt_use_table(db_con_t* _h, const str* _t)
00039 {
00040    return db_use_table(_h, _t);
00041 }
00042 
00043 
00044 /*
00045  * Get and convert columns from a result
00046  */
00047 static int dbt_get_columns(db_con_t* _h, db_res_t* _r)
00048 {
00049    int col;
00050    
00051    if (!_h || !_r) {
00052       LM_ERR("invalid parameter\n");
00053       return -1;
00054    }
00055    
00056    RES_COL_N(_r) = DBT_CON_RESULT(_h)->nrcols;
00057    if (!RES_COL_N(_r)) {
00058       LM_ERR("no columns\n");
00059       return -2;
00060    }
00061    if (db_allocate_columns(_r, RES_COL_N(_r)) != 0) {
00062       LM_ERR("could not allocate columns");
00063       return -3;
00064    }
00065 
00066    for(col = 0; col < RES_COL_N(_r); col++) {
00067       /* 
00068        * Its would be not necessary to allocate here new memory, because of
00069        * the internal structure of the db_text module. But we do this anyway
00070        * to stay confirm to the other database modules.
00071        */
00072       RES_NAMES(_r)[col] = (str*)pkg_malloc(sizeof(str));
00073       if (! RES_NAMES(_r)[col]) {
00074          LM_ERR("no private memory left\n");
00075          db_free_columns(_r);
00076          return -4;
00077       }
00078       LM_DBG("allocate %d bytes for RES_NAMES[%d] at %p",
00079             (int)sizeof(str), col,
00080             RES_NAMES(_r)[col]);
00081       RES_NAMES(_r)[col]->s = DBT_CON_RESULT(_h)->colv[col].name.s;
00082       RES_NAMES(_r)[col]->len = DBT_CON_RESULT(_h)->colv[col].name.len;
00083 
00084       switch(DBT_CON_RESULT(_h)->colv[col].type)
00085       {
00086          case DB_STR:
00087          case DB_STRING:
00088          case DB_BLOB:
00089          case DB_INT:
00090          case DB_DATETIME:
00091          case DB_DOUBLE:
00092             RES_TYPES(_r)[col] = DBT_CON_RESULT(_h)->colv[col].type;
00093          break;
00094          default:
00095             LM_WARN("unhandled data type column (%.*s) type id (%d), "
00096                   "use STR as default\n", RES_NAMES(_r)[col]->len,
00097                   RES_NAMES(_r)[col]->s, DBT_CON_RESULT(_h)->colv[col].type);
00098             RES_TYPES(_r)[col] = DB_STR;
00099          break;
00100       }
00101    }
00102    return 0;
00103 }
00104 
00105 /*
00106  * Convert a row from result into db API representation
00107  */
00108 static int dbt_convert_row(db_con_t* _h, db_res_t* _res, db_row_t* _r)
00109 {
00110    int i;
00111    if (!_h || !_r || !_res) {
00112       LM_ERR("invalid parameter value\n");
00113       return -1;
00114    }
00115 
00116    if (db_allocate_row(_res, _r) != 0) {
00117       LM_ERR("could not allocate row");
00118       return -2;
00119    }
00120 
00121    for(i = 0; i < RES_COL_N(_res); i++) {
00122       (ROW_VALUES(_r)[i]).nul = DBT_CON_ROW(_h)->fields[i].nul;
00123       switch(RES_TYPES(_res)[i])
00124       {
00125          case DB_INT:
00126             VAL_INT(&(ROW_VALUES(_r)[i])) = 
00127                   DBT_CON_ROW(_h)->fields[i].val.int_val;
00128             VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_INT;
00129          break;
00130 
00131          case DB_BIGINT:
00132             LM_ERR("BIGINT not supported");
00133             return -1;
00134 
00135          case DB_DOUBLE:
00136             VAL_DOUBLE(&(ROW_VALUES(_r)[i])) = 
00137                   DBT_CON_ROW(_h)->fields[i].val.double_val;
00138             VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_DOUBLE;
00139          break;
00140 
00141          case DB_STRING:
00142             VAL_STR(&(ROW_VALUES(_r)[i])).s = 
00143                   DBT_CON_ROW(_h)->fields[i].val.str_val.s;
00144             VAL_STR(&(ROW_VALUES(_r)[i])).len =
00145                   DBT_CON_ROW(_h)->fields[i].val.str_val.len;
00146             VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_STRING;
00147             VAL_FREE(&(ROW_VALUES(_r)[i])) = 0;
00148          break;
00149 
00150          case DB_STR:
00151             VAL_STR(&(ROW_VALUES(_r)[i])).s = 
00152                   DBT_CON_ROW(_h)->fields[i].val.str_val.s;
00153             VAL_STR(&(ROW_VALUES(_r)[i])).len =
00154                   DBT_CON_ROW(_h)->fields[i].val.str_val.len;
00155             VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_STR;
00156             VAL_FREE(&(ROW_VALUES(_r)[i])) = 0;
00157          break;
00158 
00159          case DB_DATETIME:
00160             VAL_INT(&(ROW_VALUES(_r)[i])) = 
00161                   DBT_CON_ROW(_h)->fields[i].val.int_val;
00162             VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_DATETIME;
00163          break;
00164 
00165          case DB_BLOB:
00166             VAL_STR(&(ROW_VALUES(_r)[i])).s =
00167                   DBT_CON_ROW(_h)->fields[i].val.str_val.s;
00168             VAL_STR(&(ROW_VALUES(_r)[i])).len =
00169                   DBT_CON_ROW(_h)->fields[i].val.str_val.len;
00170             VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_BLOB;
00171             VAL_FREE(&(ROW_VALUES(_r)[i])) = 0;
00172          break;
00173 
00174          case DB_BITMAP:
00175             VAL_INT(&(ROW_VALUES(_r)[i])) =
00176                DBT_CON_ROW(_h)->fields[i].val.bitmap_val;
00177             VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_INT;
00178          break;
00179       }
00180    }
00181    return 0;
00182 }
00183 
00184 
00185 /*
00186  * Convert rows from internal to db API representation
00187  */
00188 static int dbt_convert_rows(db_con_t* _h, db_res_t* _r)
00189 {
00190    int col;
00191    dbt_row_p _rp = NULL;
00192    if (!_h || !_r) {
00193       LM_ERR("invalid parameter\n");
00194       return -1;
00195    }
00196    RES_ROW_N(_r) = DBT_CON_RESULT(_h)->nrrows;
00197    if (!RES_ROW_N(_r)) {
00198       return 0;
00199    }
00200    if (db_allocate_rows(_r) < 0) {
00201       LM_ERR("could not allocate rows");
00202       return -2;
00203    }
00204    col = 0;
00205    _rp = DBT_CON_RESULT(_h)->rows;
00206    while(_rp) {
00207       DBT_CON_ROW(_h) = _rp;
00208       if (!DBT_CON_ROW(_h)) {
00209          LM_ERR("failed to get current row\n");
00210          RES_ROW_N(_r) = col;
00211          db_free_rows(_r);
00212          return -3;
00213       }
00214       if (dbt_convert_row(_h, _r, &(RES_ROWS(_r)[col])) < 0) {
00215          LM_ERR("failed to convert row #%d\n", col);
00216          RES_ROW_N(_r) = col;
00217          db_free_rows(_r);
00218          return -4;
00219       }
00220       col++;
00221       _rp = _rp->next;
00222    }
00223    return 0;
00224 }
00225 
00226 
00227 /*
00228  * Fill the structure with data from database
00229  */
00230 static int dbt_convert_result(db_con_t* _h, db_res_t* _r)
00231 {
00232    if (!_h || !_r) {
00233       LM_ERR("invalid parameter\n");
00234       return -1;
00235    }
00236    if (dbt_get_columns(_h, _r) < 0) {
00237       LM_ERR("failed to get column names\n");
00238       return -2;
00239    }
00240 
00241    if (dbt_convert_rows(_h, _r) < 0) {
00242       LM_ERR("failed to convert rows\n");
00243       db_free_columns(_r);
00244       return -3;
00245    }
00246    return 0;
00247 }
00248 
00249 /*
00250  * Retrieve result set
00251  */
00252 int dbt_get_result(db_con_t* _h, db_res_t** _r)
00253 {
00254    if (!_h || !_r) {
00255       LM_ERR("invalid parameter value\n");
00256       return -1;
00257    }
00258 
00259    if (!DBT_CON_RESULT(_h))
00260    {
00261       LM_ERR("failed to get result\n");
00262       *_r = 0;
00263       return -3;
00264    }
00265 
00266    *_r = db_new_result();
00267    if (*_r == 0) 
00268    {
00269       LM_ERR("no private memory left\n");
00270       return -2;
00271    }
00272 
00273    if (dbt_convert_result(_h, *_r) < 0) 
00274    {
00275       LM_ERR("failed to convert result\n");
00276       pkg_free(*_r);
00277       return -4;
00278    }
00279    
00280    return 0;
00281 }

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