dbt_tb.c

Go to the documentation of this file.
00001 /*
00002  * $Id: dbt_tb.c 4518 2008-07-28 15:39:28Z 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-03 created by Daniel
00027  * 
00028  */
00029 
00030 #include <stdio.h>
00031 #include <string.h>
00032 #include <time.h>
00033 #include <sys/types.h>
00034 #include <sys/stat.h>
00035 #include <dirent.h>
00036 
00037 #include "../../mem/shm_mem.h"
00038 #include "../../mem/mem.h"
00039 #include "../../dprint.h"
00040 #include "../../locking.h"
00041 
00042 #include "dbt_util.h"
00043 #include "dbt_lib.h"
00044 
00045 
00046 /**
00047  *
00048  */
00049 dbt_column_p dbt_column_new(char *_s, int _l)
00050 {
00051    dbt_column_p dcp = NULL;
00052    if(!_s || _l <=0)
00053       return NULL;
00054    dcp = (dbt_column_p)shm_malloc(sizeof(dbt_column_t));
00055    if(!dcp)
00056       return NULL;
00057    dcp->name.s  = (char*)shm_malloc((_l+1)*sizeof(char));
00058    if(!dcp->name.s)
00059    {
00060       shm_free(dcp);
00061       return NULL;
00062    }
00063    dcp->name.len = _l;
00064    strncpy(dcp->name.s, _s, _l);
00065    dcp->name.s[_l] = '\0';
00066    dcp->next = dcp->prev = NULL;
00067    dcp->type = 0;
00068    dcp->flag = DBT_FLAG_UNSET;
00069 
00070    return dcp;
00071 }
00072 
00073 /**
00074  *
00075  */
00076 int dbt_column_free(dbt_column_p dcp)
00077 {
00078    
00079    if(!dcp)
00080       return -1;
00081    if(dcp->name.s)
00082       shm_free(dcp->name.s);
00083    shm_free(dcp);
00084  
00085    return 0;
00086 }
00087 
00088 /**
00089  *
00090  */
00091 dbt_row_p dbt_row_new(int _nf)
00092 {
00093    int i;
00094    dbt_row_p _drp = NULL;
00095 
00096    _drp = (dbt_row_p)shm_malloc(sizeof(dbt_row_t));
00097    if(!_drp)
00098       return NULL;
00099    
00100    _drp->fields = (dbt_val_p)shm_malloc(_nf*sizeof(dbt_val_t));
00101    if(!_drp->fields)
00102    {
00103       shm_free(_drp);
00104       return NULL;
00105    }
00106    memset(_drp->fields, 0, _nf*sizeof(dbt_val_t));
00107    for(i=0; i<_nf; i++)
00108       _drp->fields[i].nul = 1;
00109 
00110    _drp->next = _drp->prev = NULL;
00111 
00112    return _drp;
00113 }
00114 
00115 /**
00116  *
00117  */
00118 int dbt_row_free(dbt_table_p _dtp, dbt_row_p _drp)
00119 {
00120    int i;
00121    
00122    if(!_dtp || !_drp)
00123       return -1;
00124    
00125    if(_drp->fields)
00126    {
00127       for(i=0; i<_dtp->nrcols; i++)
00128          if((_dtp->colv[i]->type==DB_STR || _dtp->colv[i]->type==DB_STRING
00129                   || _dtp->colv[i]->type==DB_BLOB)
00130                && _drp->fields[i].val.str_val.s)
00131             shm_free(_drp->fields[i].val.str_val.s);
00132       shm_free(_drp->fields);
00133    }
00134    shm_free(_drp);
00135 
00136    return 0;
00137 }
00138 
00139 /**
00140  *
00141  */
00142 dbt_table_p dbt_table_new(const str *_tbname, const str *_dbname, const char *path)
00143 {
00144    struct stat s;
00145    dbt_table_p dtp = NULL;
00146    if(!_tbname || !_dbname || !path)
00147       return NULL;
00148    
00149    dtp = (dbt_table_p)shm_malloc(sizeof(dbt_table_t));
00150    if(!dtp)
00151       goto done;
00152    dtp->name.s = (char*)shm_malloc((_tbname->len+1)*sizeof(char));
00153    if(!dtp->name.s)
00154    {
00155       shm_free(dtp);
00156       dtp = NULL;
00157       goto done;
00158    }
00159    memcpy(dtp->name.s, _tbname->s, _tbname->len);
00160    dtp->name.s[_tbname->len] = '\0';
00161    dtp->name.len = _tbname->len;
00162    
00163    dtp->dbname.s = (char*)shm_malloc((_dbname->len+1)*sizeof(char));
00164    if(!dtp->dbname.s)
00165    {
00166       shm_free(dtp->name.s);
00167       shm_free(dtp);
00168       dtp = NULL;
00169       goto done;
00170    }
00171    memcpy(dtp->dbname.s, _dbname->s, _dbname->len);
00172    dtp->dbname.s[_dbname->len] = '\0';
00173    dtp->dbname.len = _dbname->len;
00174 
00175    dtp->rows = NULL;
00176    dtp->cols = NULL;
00177    dtp->colv = NULL;
00178    dtp->mark = (int)time(NULL);
00179    dtp->flag = DBT_TBFL_ZERO;
00180    dtp->nrrows = dtp->nrcols = dtp->auto_val = 0;
00181    dtp->auto_col = -1;
00182    dtp->mt = 0;
00183    if(stat(path, &s) == 0)
00184    {
00185       dtp->mt = s.st_mtime;
00186       LM_DBG("mtime is %d\n", (int)s.st_mtime);
00187    }
00188    
00189 done:
00190    return dtp;
00191 }
00192 
00193 /**
00194  *
00195  */
00196 int dbt_table_free_rows(dbt_table_p _dtp)
00197 {
00198    dbt_row_p _rp=NULL, _rp0=NULL;
00199    
00200    if(!_dtp || !_dtp->rows || !_dtp->colv)
00201       return -1;
00202    _rp = _dtp->rows;
00203    while(_rp)
00204    {
00205       _rp0=_rp;
00206       _rp=_rp->next;
00207       dbt_row_free(_dtp, _rp0);
00208    }
00209    
00210    dbt_table_update_flags(_dtp, DBT_TBFL_MODI, DBT_FL_SET, 1);
00211    
00212    _dtp->rows = NULL;
00213    _dtp->nrrows = 0;
00214 
00215    return 0;
00216 }
00217 
00218 /**
00219  *
00220  */
00221 int dbt_table_add_row(dbt_table_p _dtp, dbt_row_p _drp)
00222 {
00223    if(!_dtp || !_drp)
00224       return -1;
00225    
00226    if(dbt_table_check_row(_dtp, _drp))
00227       return -1;
00228    
00229    dbt_table_update_flags(_dtp, DBT_TBFL_MODI, DBT_FL_SET, 1);
00230    
00231    if(_dtp->rows)
00232       (_dtp->rows)->prev = _drp;
00233    _drp->next = _dtp->rows;
00234    _dtp->rows = _drp;
00235    _dtp->nrrows++;
00236 
00237    return 0;
00238 }
00239 
00240 /**
00241  *
00242  */
00243 int dbt_table_free(dbt_table_p _dtp)
00244 {
00245    dbt_column_p _cp=NULL, _cp0=NULL;
00246    
00247    if(!_dtp)
00248       return -1;
00249 
00250    if(_dtp->name.s)
00251       shm_free(_dtp->name.s);
00252    if(_dtp->dbname.s)
00253       shm_free(_dtp->dbname.s);
00254    
00255    if(_dtp->rows && _dtp->nrrows>0)
00256       dbt_table_free_rows(_dtp);
00257    
00258    _cp = _dtp->cols;
00259    while(_cp)
00260    {
00261       _cp0=_cp;
00262       _cp=_cp->next;
00263       dbt_column_free(_cp0);
00264    }
00265    if(_dtp->colv)
00266       shm_free(_dtp->colv);
00267 
00268    shm_free(_dtp);
00269 
00270    return 0;
00271 }
00272 
00273 /**
00274  *
00275  */
00276 int dbt_row_set_val(dbt_row_p _drp, dbt_val_p _vp, int _t, int _idx)
00277 {
00278    if(!_drp || !_vp || _idx<0)
00279       return -1;
00280    
00281    _drp->fields[_idx].nul = _vp->nul;
00282    _drp->fields[_idx].type = _t;
00283 
00284    if(!_vp->nul)
00285    {
00286       switch(_t)
00287       {
00288          case DB_STR:
00289          case DB_BLOB:
00290             _drp->fields[_idx].type = _t;
00291             _drp->fields[_idx].val.str_val.s = 
00292                (char*)shm_malloc((_vp->val.str_val.len+1)*sizeof(char));
00293             if(!_drp->fields[_idx].val.str_val.s)
00294             {
00295                _drp->fields[_idx].nul = 1;
00296                return -1;
00297             }
00298             memcpy(_drp->fields[_idx].val.str_val.s, _vp->val.str_val.s,
00299                _vp->val.str_val.len);
00300             _drp->fields[_idx].val.str_val.s[_vp->val.str_val.len] = '\0';
00301             _drp->fields[_idx].val.str_val.len = _vp->val.str_val.len;
00302          break;
00303          
00304          case DB_STRING:
00305             _drp->fields[_idx].type = _t;
00306             _drp->fields[_idx].val.str_val.len=_vp->val.str_val.len;
00307             
00308             _drp->fields[_idx].val.str_val.s = 
00309                (char*)shm_malloc((_drp->fields[_idx].val.str_val.len+1)
00310                              *sizeof(char));
00311             if(!_drp->fields[_idx].val.str_val.s)
00312             {
00313                _drp->fields[_idx].nul = 1;
00314                return -1;
00315             }
00316             memcpy(_drp->fields[_idx].val.str_val.s, _vp->val.string_val,
00317                _drp->fields[_idx].val.str_val.len);
00318             _drp->fields[_idx].val.str_val.s[_drp->fields[_idx].val.str_val.len] = '\0';
00319          break;
00320          
00321          case DB_DOUBLE:
00322             _drp->fields[_idx].type = DB_DOUBLE;
00323             _drp->fields[_idx].val.double_val = _vp->val.double_val;
00324          break;
00325          
00326          case DB_INT:
00327             _drp->fields[_idx].type = DB_INT;
00328             _drp->fields[_idx].val.int_val = _vp->val.int_val;
00329          break;
00330          
00331          case DB_DATETIME:
00332             _drp->fields[_idx].type = _t;
00333             _drp->fields[_idx].val.int_val = (int)_vp->val.time_val;
00334          break;
00335          
00336          case DB_BITMAP:
00337             _drp->fields[_idx].type = DB_INT;
00338             _drp->fields[_idx].val.int_val = (int)_vp->val.bitmap_val;
00339          break;
00340          
00341          default:
00342             _drp->fields[_idx].nul = 1;
00343             return -1;
00344       }
00345    }
00346    
00347    return 0;
00348 }
00349 
00350 /**
00351  *
00352  */
00353 int dbt_row_update_val(dbt_row_p _drp, dbt_val_p _vp, int _t, int _idx)
00354 {
00355    if(!_drp || !_vp || _idx<0)
00356       return -1;
00357    
00358    _drp->fields[_idx].nul = _vp->nul;
00359    _drp->fields[_idx].type = _t;
00360    
00361    if(!_vp->nul)
00362    {
00363       switch(_t)
00364       {
00365          case DB_BLOB:
00366          case DB_STR:
00367             _drp->fields[_idx].type = _t;
00368             // free if already exists
00369             if(_drp->fields[_idx].val.str_val.s)
00370                shm_free(_drp->fields[_idx].val.str_val.s);
00371          
00372             _drp->fields[_idx].val.str_val.s = 
00373                (char*)shm_malloc((_vp->val.str_val.len+1)*sizeof(char));
00374             if(!_drp->fields[_idx].val.str_val.s)
00375             {
00376                _drp->fields[_idx].nul = 1;
00377                return -1;
00378             }
00379             memcpy(_drp->fields[_idx].val.str_val.s, _vp->val.str_val.s,
00380                _vp->val.str_val.len);
00381             _drp->fields[_idx].val.str_val.s[_vp->val.str_val.len] = '\0';
00382             _drp->fields[_idx].val.str_val.len = _vp->val.str_val.len;
00383          break;
00384          
00385          case DB_STRING:
00386             /* free if already exists */
00387             if(_drp->fields[_idx].val.str_val.s)
00388                shm_free(_drp->fields[_idx].val.str_val.s);
00389 
00390             _drp->fields[_idx].type = _t;
00391             if(_vp->type==DB_STR)
00392                _drp->fields[_idx].val.str_val.len=_vp->val.str_val.len;
00393             else
00394                _drp->fields[_idx].val.str_val.len
00395                                  =strlen(_vp->val.string_val);
00396             
00397             _drp->fields[_idx].val.str_val.s = 
00398                (char*)shm_malloc((_drp->fields[_idx].val.str_val.len+1)
00399                              *sizeof(char));
00400             if(!_drp->fields[_idx].val.str_val.s)
00401             {
00402                _drp->fields[_idx].nul = 1;
00403                return -1;
00404             }
00405             memcpy(_drp->fields[_idx].val.str_val.s, _vp->val.string_val,
00406                _drp->fields[_idx].val.str_val.len);
00407             _drp->fields[_idx].val.str_val.s[_vp->val.str_val.len] = '\0';
00408          break;
00409          
00410          case DB_DOUBLE:
00411             _drp->fields[_idx].type = _t;
00412             _drp->fields[_idx].val.double_val = _vp->val.double_val;
00413          break;
00414          
00415          case DB_INT:
00416             _drp->fields[_idx].type = _t;
00417             _drp->fields[_idx].val.int_val = _vp->val.int_val;
00418          break;
00419          
00420          case DB_DATETIME:
00421             _drp->fields[_idx].type = _t;
00422             _drp->fields[_idx].val.int_val = (int)_vp->val.time_val;
00423          break;
00424          
00425          case DB_BITMAP:
00426             _drp->fields[_idx].type = _t;
00427             _drp->fields[_idx].val.int_val = (int)_vp->val.bitmap_val;
00428          break;
00429          
00430          default:
00431             LM_ERR("unsupported type %d in update\n",_t);
00432             _drp->fields[_idx].nul = 1;
00433             return -1;
00434       }
00435    }
00436    
00437    return 0;
00438 }
00439 
00440 /**
00441  *
00442  */
00443 int dbt_table_check_row(dbt_table_p _dtp, dbt_row_p _drp)
00444 {
00445    int i;
00446    if(!_dtp || _dtp->nrcols <= 0 || !_drp)
00447       return -1;
00448    
00449    for(i=0; i<_dtp->nrcols; i++)
00450    {
00451       if(!_drp->fields[i].nul 
00452             && dbt_is_neq_type(_dtp->colv[i]->type, _drp->fields[i].type))
00453       {
00454          LM_DBG("incompatible types - field %d [%d/%d]\n",i,
00455                _dtp->colv[i]->type, _drp->fields[i].type);
00456          return -1;
00457       }
00458       if(_dtp->colv[i]->flag & DBT_FLAG_NULL)
00459          continue;
00460       
00461       if(!_drp->fields[i].nul)
00462          continue;
00463 
00464       if(_dtp->colv[i]->type==DB_INT
00465          && (_dtp->colv[i]->flag & DBT_FLAG_AUTO)
00466          && i==_dtp->auto_col)
00467       {
00468          _drp->fields[i].nul = 0;
00469          _drp->fields[i].val.int_val = ++_dtp->auto_val;
00470          continue;
00471       }
00472 
00473       LM_DBG("null value not allowed - field %d\n",i);
00474       return -1;
00475    }
00476    
00477    return 0;
00478 }
00479 
00480 /**
00481  *
00482  */
00483 int dbt_table_update_flags(dbt_table_p _dtp, int _f, int _o, int _m)
00484 {
00485    if(!_dtp)
00486       return -1;
00487    
00488    if(_o == DBT_FL_SET)
00489       _dtp->flag |= _f;
00490    else if(_o == DBT_FL_UNSET)
00491          _dtp->flag &= ~_f;
00492    
00493    if(_m)
00494       _dtp->mark = (int)time(NULL);
00495    
00496    return 0;
00497 }
00498 

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