modules_s/dbtext/dbt_tb.c

00001 /*
00002  * $Id$
00003  *
00004  * DBText library
00005  *
00006  * Copyright (C) 2001-2003 FhG Fokus
00007  *
00008  * This file is part of ser, a free SIP server.
00009  *
00010  * ser 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  * For a license to use the ser software under conditions
00016  * other than those described here, or to purchase support for this
00017  * software, please contact iptel.org by e-mail at the following addresses:
00018  *    info@iptel.org
00019  *
00020  * ser is distributed in the hope that it will be useful,
00021  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  * GNU General Public License for more details.
00024  *
00025  * You should have received a copy of the GNU General Public License 
00026  * along with this program; if not, write to the Free Software 
00027  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028  */
00029 
00037 #include <stdio.h>
00038 #include <string.h>
00039 #include <time.h>
00040 #include <sys/types.h>
00041 #include <dirent.h>
00042 
00043 #include "../../mem/shm_mem.h"
00044 #include "../../mem/mem.h"
00045 #include "../../dprint.h"
00046 #include "../../locking.h"
00047 
00048 #include "dbt_util.h"
00049 #include "dbt_lib.h"
00050 
00051 
00055 dbt_column_p dbt_column_new(char *_s, int _l)
00056 {
00057         dbt_column_p dcp = NULL;
00058         if(!_s || _l <=0)
00059                 return NULL;
00060         dcp = (dbt_column_p)shm_malloc(sizeof(dbt_column_t));
00061         if(!dcp)
00062                 return NULL;
00063         dcp->name.s  = (char*)shm_malloc(_l*sizeof(char));
00064         if(!dcp->name.s)
00065         {
00066                 shm_free(dcp);
00067                 return NULL;
00068         }
00069         dcp->name.len = _l;
00070         strncpy(dcp->name.s, _s, _l);
00071         dcp->next = dcp->prev = NULL;
00072         dcp->type = 0;
00073         dcp->flag = DBT_FLAG_UNSET;
00074 
00075         return dcp;
00076 }
00077 
00081 int dbt_column_free(dbt_column_p dcp)
00082 {
00083         
00084         if(!dcp)
00085                 return -1;
00086         if(dcp->name.s)
00087                 shm_free(dcp->name.s);
00088         shm_free(dcp);
00089  
00090         return 0;
00091 }
00092 
00096 dbt_row_p dbt_row_new(int _nf)
00097 {
00098         int i;
00099         dbt_row_p _drp = NULL;
00100 
00101         _drp = (dbt_row_p)shm_malloc(sizeof(dbt_row_t));
00102         if(!_drp)
00103                 return NULL;
00104         
00105         _drp->fields = (dbt_val_p)shm_malloc(_nf*sizeof(dbt_val_t));
00106         if(!_drp->fields)
00107         {
00108                 shm_free(_drp);
00109                 return NULL;
00110         }
00111         memset(_drp->fields, 0, _nf*sizeof(dbt_val_t));
00112         for(i=0; i<_nf; i++)
00113                 _drp->fields[i].nul = 1;
00114 
00115         _drp->next = _drp->prev = NULL;
00116 
00117         return _drp;
00118 }
00119 
00123 int dbt_row_free(dbt_table_p _dtp, dbt_row_p _drp)
00124 {
00125         int i;
00126         
00127         if(!_dtp || !_drp)
00128                 return -1;
00129         
00130         if(_drp->fields)
00131         {
00132                 for(i=0; i<_dtp->nrcols; i++)
00133                         if(_dtp->colv[i]->type==DB_STR
00134                                         && _drp->fields[i].val.str_val.s)
00135                                 shm_free(_drp->fields[i].val.str_val.s);
00136                 shm_free(_drp->fields);
00137         }
00138         shm_free(_drp);
00139 
00140         return 0;
00141 }
00142 
00146 dbt_table_p dbt_table_new(char *_s, int _l)
00147 {
00148         dbt_table_p dtp = NULL;
00149         if(!_s || _l <= 0)
00150                 return NULL;
00151         
00152         dtp = (dbt_table_p)shm_malloc(sizeof(dbt_table_t));
00153         if(!dtp)
00154                 goto done;
00155         dtp->name.s = (char*)shm_malloc(_l*sizeof(char));
00156         if(!dtp->name.s)
00157         {
00158                 shm_free(dtp);
00159                 dtp = NULL;
00160                 goto done;
00161         }
00162         memcpy(dtp->name.s, _s, _l);
00163         dtp->name.len = _l;
00164 
00165         dtp->rows = NULL;
00166         dtp->cols = NULL;
00167         dtp->colv = NULL;
00168         dtp->mark = (int)time(NULL);
00169         dtp->flag = DBT_TBFL_ZERO;
00170         dtp->nrrows = dtp->nrcols = dtp->auto_val = 0;
00171         dtp->auto_col = -1;
00172         
00173 done:
00174         return dtp;
00175 }
00176 
00180 int dbt_table_free_rows(dbt_table_p _dtp)
00181 {
00182         dbt_row_p _rp=NULL, _rp0=NULL;
00183         
00184         if(!_dtp || !_dtp->rows || !_dtp->colv)
00185                 return -1;
00186         _rp = _dtp->rows;
00187         while(_rp)
00188         {
00189                 _rp0=_rp;
00190                 _rp=_rp->next;
00191                 dbt_row_free(_dtp, _rp0);
00192         }
00193         
00194         dbt_table_update_flags(_dtp, DBT_TBFL_MODI, DBT_FL_SET, 1);
00195         
00196         _dtp->rows = NULL;
00197         _dtp->nrrows = 0;
00198 
00199         return 0;
00200 }
00201 
00205 int dbt_table_add_row(dbt_table_p _dtp, dbt_row_p _drp)
00206 {
00207         if(!_dtp || !_drp)
00208                 return -1;
00209         
00210         if(dbt_table_check_row(_dtp, _drp))
00211                 return -1;
00212         
00213         dbt_table_update_flags(_dtp, DBT_TBFL_MODI, DBT_FL_SET, 1);
00214         
00215         if(_dtp->rows)
00216                 (_dtp->rows)->prev = _drp;
00217         _drp->next = _dtp->rows;
00218         _dtp->rows = _drp;
00219         _dtp->nrrows++;
00220 
00221         return 0;
00222 }
00223 
00227 int dbt_table_free(dbt_table_p _dtp)
00228 {
00229         dbt_column_p _cp=NULL, _cp0=NULL;
00230         
00231         if(!_dtp)
00232                 return -1;
00233 
00234         if(_dtp->name.s)
00235                 shm_free(_dtp->name.s);
00236         
00237         if(_dtp->rows && _dtp->nrrows>0)
00238                 dbt_table_free_rows(_dtp);
00239         
00240         _cp = _dtp->cols;
00241         while(_cp)
00242         {
00243                 _cp0=_cp;
00244                 _cp=_cp->next;
00245                 dbt_column_free(_cp0);
00246         }
00247         if(_dtp->colv)
00248                 shm_free(_dtp->colv);
00249 
00250         shm_free(_dtp);
00251 
00252         return 0;
00253 }
00254 
00258 int dbt_row_set_val(dbt_row_p _drp, dbt_val_p _vp, int _t, int _idx)
00259 {
00260         if(!_drp || !_vp || _idx<0)
00261                 return -1;
00262         
00263         _drp->fields[_idx].nul = _vp->nul;
00264         _drp->fields[_idx].type = _t;
00265 
00266         if(!_vp->nul)
00267         {
00268                 switch(_t)
00269                 {
00270                         case DB_STR:
00271                         case DB_BLOB:
00272                                 _drp->fields[_idx].type = DB_STR;
00273                                 _drp->fields[_idx].val.str_val.s = 
00274                                         (char*)shm_malloc(_vp->val.str_val.len*sizeof(char));
00275                                 if(!_drp->fields[_idx].val.str_val.s)
00276                                 {
00277                                         _drp->fields[_idx].nul = 1;
00278                                         return -1;
00279                                 }
00280                                 memcpy(_drp->fields[_idx].val.str_val.s, _vp->val.str_val.s,
00281                                         _vp->val.str_val.len);
00282                                 _drp->fields[_idx].val.str_val.len = _vp->val.str_val.len;
00283                         break;
00284                         
00285                         case DB_STRING:
00286                                 _drp->fields[_idx].type = DB_STR;
00287                                 _drp->fields[_idx].val.str_val.len=strlen(_vp->val.string_val);
00288                                 
00289                                 _drp->fields[_idx].val.str_val.s = 
00290                                         (char*)shm_malloc(_drp->fields[_idx].val.str_val.len
00291                                                                           *sizeof(char));
00292                                 if(!_drp->fields[_idx].val.str_val.s)
00293                                 {
00294                                         _drp->fields[_idx].nul = 1;
00295                                         return -1;
00296                                 }
00297                                 memcpy(_drp->fields[_idx].val.str_val.s, _vp->val.string_val,
00298                                         _drp->fields[_idx].val.str_val.len);
00299                         break;
00300 
00301                         case DB_FLOAT:
00302                                 _drp->fields[_idx].type = DB_FLOAT;
00303                                 _drp->fields[_idx].val.float_val = _vp->val.float_val;
00304                         break;                  
00305 
00306                         case DB_DOUBLE:
00307                                 _drp->fields[_idx].type = DB_DOUBLE;
00308                                 _drp->fields[_idx].val.double_val = _vp->val.double_val;
00309                         break;
00310                         
00311                         case DB_INT:
00312                                 _drp->fields[_idx].type = DB_INT;
00313                                 _drp->fields[_idx].val.int_val = _vp->val.int_val;
00314                         break;
00315                         
00316                         case DB_DATETIME:
00317                                 _drp->fields[_idx].type = DB_INT;
00318                                 _drp->fields[_idx].val.int_val = (int)_vp->val.time_val;
00319                         break;
00320                         
00321                         default:
00322                                 _drp->fields[_idx].nul = 1;
00323                                 return -1;
00324                 }
00325         }
00326         
00327         return 0;
00328 }
00329 
00333 int dbt_row_update_val(dbt_row_p _drp, dbt_val_p _vp, int _t, int _idx)
00334 {
00335         if(!_drp || !_vp || _idx<0)
00336                 return -1;
00337         
00338         _drp->fields[_idx].nul = _vp->nul;
00339         _drp->fields[_idx].type = _t;
00340         
00341         if(!_vp->nul)
00342         {
00343                 switch(_t)
00344                 {
00345                         case DB_BLOB:
00346                         case DB_STR:
00347                                 _drp->fields[_idx].type = DB_STR;
00348                                 // free if already exists
00349                                 if(_drp->fields[_idx].val.str_val.s)
00350                                         shm_free(_drp->fields[_idx].val.str_val.s);
00351                         
00352                                 _drp->fields[_idx].val.str_val.s = 
00353                                         (char*)shm_malloc(_vp->val.str_val.len*sizeof(char));
00354                                 if(!_drp->fields[_idx].val.str_val.s)
00355                                 {
00356                                         _drp->fields[_idx].nul = 1;
00357                                         return -1;
00358                                 }
00359                                 memcpy(_drp->fields[_idx].val.str_val.s, _vp->val.str_val.s,
00360                                         _vp->val.str_val.len);
00361                                 _drp->fields[_idx].val.str_val.len = _vp->val.str_val.len;
00362                         break;
00363                         
00364                         case DB_STRING:
00365                                 _drp->fields[_idx].type = DB_STR;
00366                                 /* free if already exists */
00367                                 if(_drp->fields[_idx].val.str_val.s)
00368                                         shm_free(_drp->fields[_idx].val.str_val.s);
00369 
00370                                 _drp->fields[_idx].type = DB_STR;
00371                                 _drp->fields[_idx].val.str_val.len=strlen(_vp->val.string_val);
00372                                 
00373                                 _drp->fields[_idx].val.str_val.s = 
00374                                         (char*)shm_malloc(_drp->fields[_idx].val.str_val.len
00375                                                                           *sizeof(char));
00376                                 if(!_drp->fields[_idx].val.str_val.s)
00377                                 {
00378                                         _drp->fields[_idx].nul = 1;
00379                                         return -1;
00380                                 }
00381                                 memcpy(_drp->fields[_idx].val.str_val.s, _vp->val.string_val,
00382                                         _drp->fields[_idx].val.str_val.len);
00383                         break;
00384                         
00385                         case DB_FLOAT:
00386                                 _drp->fields[_idx].type = DB_FLOAT;
00387                                 _drp->fields[_idx].val.float_val = _vp->val.float_val;
00388                         break;
00389 
00390                         case DB_DOUBLE:
00391                                 _drp->fields[_idx].type = DB_DOUBLE;
00392                                 _drp->fields[_idx].val.double_val = _vp->val.double_val;
00393                         break;
00394                         
00395                         case DB_INT:
00396                                 _drp->fields[_idx].type = DB_INT;
00397                                 _drp->fields[_idx].val.int_val = _vp->val.int_val;
00398                         break;
00399                         
00400                         case DB_DATETIME:
00401                                 _drp->fields[_idx].type = DB_INT;
00402                                 _drp->fields[_idx].val.int_val = (int)_vp->val.time_val;
00403                         break;
00404                         
00405                         default:
00406                                 LOG(L_ERR,"ERROR:dbtext: unsupported type %d in update\n",_t);
00407                                 _drp->fields[_idx].nul = 1;
00408                                 return -1;
00409                 }
00410         }
00411         
00412         return 0;
00413 }
00414 
00418 int dbt_table_check_row(dbt_table_p _dtp, dbt_row_p _drp)
00419 {
00420         int i;
00421         if(!_dtp || _dtp->nrcols <= 0 || !_drp)
00422                 return -1;
00423         
00424         for(i=0; i<_dtp->nrcols; i++)
00425         {
00426                 if(!_drp->fields[i].nul &&(_dtp->colv[i]->type!=_drp->fields[i].type))
00427                 {
00428                         DBG("DBT:dbt_table_check_row: incompatible types - field %d\n",i);
00429                         return -1;
00430                 }
00431                 if(_dtp->colv[i]->flag & DBT_FLAG_NULL)
00432                         continue;
00433                 
00434                 if(!_drp->fields[i].nul)
00435                         continue;
00436 
00437                 if(_dtp->colv[i]->type==DB_INT
00438                         && (_dtp->colv[i]->flag & DBT_FLAG_AUTO)
00439                         && i==_dtp->auto_col)
00440                 {
00441                         _drp->fields[i].nul = 0;
00442                         _drp->fields[i].val.int_val = ++_dtp->auto_val;
00443                         continue;
00444                 }
00445 
00446                 DBG("DBT:dbt_table_check_row: NULL value not allowed - field %d\n",i);
00447                 return -1;
00448         }
00449         
00450         return 0;
00451 }
00452 
00456 int dbt_table_update_flags(dbt_table_p _dtp, int _f, int _o, int _m)
00457 {
00458         if(!_dtp)
00459                 return -1;
00460         
00461         if(_o == DBT_FL_SET)
00462                 _dtp->flag |= _f;
00463         else if(_o == DBT_FL_UNSET)
00464                         _dtp->flag &= ~_f;
00465         
00466         if(_m)
00467                 _dtp->mark = (int)time(NULL);
00468         
00469         return 0;
00470 }
00471