00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
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
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