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 <dirent.h>
00035
00036 #include "../../mem/shm_mem.h"
00037 #include "../../mem/mem.h"
00038 #include "../../dprint.h"
00039
00040 #include "dbt_util.h"
00041 #include "dbt_lib.h"
00042
00043 static dbt_cache_p *_dbt_cachedb = NULL;
00044 static gen_lock_t *_dbt_cachesem = NULL;
00045
00046 static dbt_tbl_cachel_p _dbt_cachetbl = NULL;
00047
00048 #define DBT_CACHETBL_SIZE 16
00049
00050
00051
00052
00053 int dbt_init_cache(void)
00054 {
00055 int i, j;
00056 if(!_dbt_cachesem)
00057 {
00058
00059 _dbt_cachesem = lock_alloc();
00060 if(!_dbt_cachesem)
00061 {
00062 LM_CRIT("could not alloc a lock\n");
00063 return -1;
00064 }
00065 if (lock_init(_dbt_cachesem)==0)
00066 {
00067 LM_CRIT("could not initialize a lock\n");
00068 lock_dealloc(_dbt_cachesem);
00069 return -1;
00070 }
00071 }
00072
00073 if (!_dbt_cachedb) {
00074 _dbt_cachedb = shm_malloc( sizeof(dbt_cache_p) );
00075 if (!_dbt_cachedb) {
00076 LM_CRIT("no enough shm mem\n");
00077 lock_dealloc(_dbt_cachesem);
00078 return -1;
00079 }
00080 *_dbt_cachedb = NULL;
00081 }
00082
00083 if (!_dbt_cachetbl) {
00084 _dbt_cachetbl
00085 = (dbt_tbl_cachel_p)shm_malloc(DBT_CACHETBL_SIZE*
00086 sizeof(dbt_tbl_cachel_t));
00087 if(_dbt_cachetbl==NULL)
00088 {
00089 LM_CRIT("no enough shm mem\n");
00090 lock_dealloc(_dbt_cachesem);
00091 shm_free(_dbt_cachedb);
00092 return -1;
00093 }
00094 memset(_dbt_cachetbl, 0, DBT_CACHETBL_SIZE*sizeof(dbt_tbl_cachel_t));
00095 for(i=0; i<DBT_CACHETBL_SIZE; i++)
00096 {
00097 if (lock_init(&_dbt_cachetbl[i].sem)==0)
00098 {
00099 LM_CRIT("cannot init tables' sem's\n");
00100 for(j=i-1; j>=0; j--)
00101 lock_destroy(&_dbt_cachetbl[j].sem);
00102 lock_dealloc(_dbt_cachesem);
00103 shm_free(_dbt_cachedb);
00104 return -1;
00105 }
00106 }
00107 }
00108
00109
00110 return 0;
00111 }
00112
00113
00114
00115
00116 dbt_cache_p dbt_cache_get_db(str *_s)
00117 {
00118 dbt_cache_p _dcache=NULL;;
00119 if(!_dbt_cachesem || !_dbt_cachedb)
00120 {
00121 LM_ERR("dbtext cache is not initialized! Check if you loaded"
00122 " dbtext before any other module that uses it\n");
00123 return NULL;
00124 }
00125 if(!_s || !_s->s || _s->len<=0)
00126 return NULL;
00127
00128 LM_DBG("looking for db %.*s!\n",_s->len,_s->s);
00129
00130 lock_get(_dbt_cachesem);
00131
00132 _dcache = *_dbt_cachedb;
00133 while(_dcache)
00134 {
00135 if(_dcache->name.len==_s->len
00136 && !strncasecmp(_dcache->name.s, _s->s, _s->len))
00137 {
00138 LM_DBG("db already cached!\n");
00139 goto done;
00140 }
00141
00142 _dcache = _dcache->next;
00143 }
00144 if(!dbt_is_database(_s))
00145 {
00146 LM_ERR("database [%.*s] does not exists!\n", _s->len, _s->s);
00147 goto done;
00148 }
00149 LM_DBG("new db!\n");
00150
00151 _dcache = (dbt_cache_p)shm_malloc(sizeof(dbt_cache_t));
00152 if(!_dcache)
00153 {
00154 LM_ERR(" no shm memory for dbt_cache_t.\n");
00155 goto done;
00156 }
00157 memset(_dcache, 0, sizeof(dbt_cache_t));
00158
00159 _dcache->name.s = (char*)shm_malloc((_s->len+1)*sizeof(char));
00160 if(!_dcache->name.s)
00161 {
00162 LM_ERR(" no shm memory for s!!\n");
00163 shm_free(_dcache);
00164 _dcache = NULL;
00165 goto done;
00166 }
00167
00168 memcpy(_dcache->name.s, _s->s, _s->len);
00169 _dcache->name.s[_s->len] = '\0';
00170 _dcache->name.len = _s->len;
00171
00172 if(*_dbt_cachedb)
00173 _dcache->next = *_dbt_cachedb;
00174
00175 *_dbt_cachedb = _dcache;
00176
00177 done:
00178 lock_release(_dbt_cachesem);
00179 return _dcache;
00180 }
00181
00182
00183
00184
00185 int dbt_cache_check_db(str *_s)
00186 {
00187 dbt_cache_p _dcache=NULL;;
00188 if(!_dbt_cachesem || !(*_dbt_cachedb)
00189 || !_s || !_s->s || _s->len<=0)
00190 return -1;
00191
00192 lock_get(_dbt_cachesem);
00193
00194 _dcache = *_dbt_cachedb;
00195 while(_dcache)
00196 {
00197 if(_dcache->name.len == _s->len &&
00198 strncasecmp(_dcache->name.s, _s->s, _s->len))
00199 {
00200 lock_release(_dbt_cachesem);
00201 return 0;
00202 }
00203 _dcache = _dcache->next;
00204 }
00205
00206 lock_release(_dbt_cachesem);
00207 return -1;
00208 }
00209
00210
00211
00212
00213 int dbt_db_del_table(dbt_cache_p _dc, const str *_s, int sync)
00214 {
00215 dbt_table_p _tbc = NULL;
00216 int hash;
00217 int hashidx;
00218 if(!_dbt_cachetbl || !_dc || !_s || !_s->s || _s->len<=0)
00219 return -1;
00220
00221 hash = core_hash(&_dc->name, _s, DBT_CACHETBL_SIZE);
00222 hashidx = hash % DBT_CACHETBL_SIZE;
00223
00224 if(sync)
00225 lock_get(&_dbt_cachetbl[hashidx].sem);
00226
00227 _tbc = _dbt_cachetbl[hashidx].dtp;
00228
00229 while(_tbc)
00230 {
00231 if(_tbc->hash==hash && _tbc->dbname.len == _dc->name.len
00232 && _tbc->name.len == _s->len
00233 && !strncasecmp(_tbc->dbname.s, _dc->name.s, _dc->name.len)
00234 && !strncasecmp(_tbc->name.s, _s->s, _s->len))
00235 {
00236 if(_tbc->prev)
00237 (_tbc->prev)->next = _tbc->next;
00238 else
00239 _dbt_cachetbl[hashidx].dtp = _tbc->next;
00240
00241 if(_tbc->next)
00242 (_tbc->next)->prev = _tbc->prev;
00243 break;
00244 }
00245 _tbc = _tbc->next;
00246 }
00247
00248 if(sync)
00249 lock_release(&_dbt_cachetbl[hashidx].sem);
00250
00251 dbt_table_free(_tbc);
00252
00253 return 0;
00254 }
00255
00256
00257
00258
00259 dbt_table_p dbt_db_get_table(dbt_cache_p _dc, const str *_s)
00260 {
00261 dbt_table_p _tbc = NULL;
00262 int hash;
00263 int hashidx;
00264
00265 if(!_dbt_cachetbl || !_dc || !_s || !_s->s || _s->len<=0) {
00266 LM_ERR("invalid parameter");
00267 return NULL;
00268 }
00269
00270 hash = core_hash(&_dc->name, _s, DBT_CACHETBL_SIZE);
00271 hashidx = hash % DBT_CACHETBL_SIZE;
00272
00273 lock_get(&_dbt_cachetbl[hashidx].sem);
00274
00275 _tbc = _dbt_cachetbl[hashidx].dtp;
00276
00277 while(_tbc)
00278 {
00279 if(_tbc->hash==hash && _tbc->dbname.len == _dc->name.len
00280 && _tbc->name.len == _s->len
00281 && !strncasecmp(_tbc->dbname.s, _dc->name.s, _dc->name.len)
00282 && !strncasecmp(_tbc->name.s, _s->s, _s->len))
00283 {
00284
00285 if(db_mode==0 || dbt_check_mtime(_s, &(_dc->name), &(_tbc->mt))!=1)
00286 {
00287 LM_DBG("cache or mtime succeeded for [%.*s]\n",
00288 _tbc->name.len, _tbc->name.s);
00289 return _tbc;
00290 }
00291 break;
00292 }
00293 _tbc = _tbc->next;
00294 }
00295
00296
00297 if(_tbc)
00298 {
00299 dbt_db_del_table(_dc, _s, 0);
00300 }
00301
00302 _tbc = dbt_load_file(_s, &(_dc->name));
00303
00304 if(!_tbc)
00305 {
00306 LM_ERR("could not load database from file [%.*s]", _s->len, _s->s);
00307 lock_release(&_dbt_cachetbl[hashidx].sem);
00308 return NULL;
00309 }
00310
00311 _tbc->hash = hash;
00312 _tbc->next = _dbt_cachetbl[hashidx].dtp;
00313 if(_dbt_cachetbl[hashidx].dtp)
00314 _dbt_cachetbl[hashidx].dtp->prev = _tbc;
00315
00316 _dbt_cachetbl[hashidx].dtp = _tbc;
00317
00318
00319 return _tbc;
00320 }
00321
00322 int dbt_release_table(dbt_cache_p _dc, const str *_s)
00323 {
00324 int hash;
00325 int hashidx;
00326
00327 if(!_dbt_cachetbl || !_dc || !_s || !_s->s || _s->len<=0)
00328 return -1;
00329
00330 hash = core_hash(&_dc->name, _s, DBT_CACHETBL_SIZE);
00331 hashidx = hash % DBT_CACHETBL_SIZE;
00332
00333 lock_release(&_dbt_cachetbl[hashidx].sem);
00334
00335 return 0;
00336 }
00337
00338
00339
00340
00341 int dbt_cache_destroy(void)
00342 {
00343 int i;
00344 dbt_cache_p _dc=NULL, _dc0=NULL;
00345 dbt_table_p _tbc = NULL;
00346 dbt_table_p _tbc0 = NULL;
00347
00348 if(!_dbt_cachesem)
00349 return -1;
00350
00351 lock_get(_dbt_cachesem);
00352 if( _dbt_cachedb!=NULL )
00353 {
00354 _dc = *_dbt_cachedb;
00355 while(_dc)
00356 {
00357 _dc0 = _dc;
00358 _dc = _dc->next;
00359 shm_free(_dc0->name.s);
00360 shm_free(_dc0);
00361 }
00362 shm_free(_dbt_cachedb);
00363 }
00364 lock_destroy(_dbt_cachesem);
00365 lock_dealloc(_dbt_cachesem);
00366
00367
00368 if(_dbt_cachetbl==0)
00369 return 0;
00370 for(i=0; i<DBT_CACHETBL_SIZE; i++)
00371 {
00372 lock_destroy(&_dbt_cachetbl[i].sem);
00373 _tbc = _dbt_cachetbl[i].dtp;
00374 while(_tbc)
00375 {
00376 _tbc0 = _tbc;
00377 _tbc = _tbc->next;
00378 dbt_table_free(_tbc0);
00379 }
00380 }
00381 shm_free(_dbt_cachetbl);
00382 return 0;
00383 }
00384
00385
00386
00387
00388 int dbt_cache_print(int _f)
00389 {
00390 int i;
00391 dbt_table_p _tbc;
00392
00393 if(!_dbt_cachetbl)
00394 return -1;
00395
00396 for(i=0; i< DBT_CACHETBL_SIZE; i++)
00397 {
00398 lock_get(&_dbt_cachetbl[i].sem);
00399 _tbc = _dbt_cachetbl[i].dtp;
00400 while(_tbc)
00401 {
00402 if(_f)
00403 fprintf(stdout, "\n--- Database [%.*s]\n", _tbc->dbname.len,
00404 _tbc->dbname.s);
00405 if(_f)
00406 {
00407 fprintf(stdout, "\n----- Table [%.*s]\n",
00408 _tbc->name.len, _tbc->name.s);
00409 fprintf(stdout, "------- LA=<%d> FL=<%x> AC=<%d>"
00410 " AV=<%d>\n", _tbc->mark, _tbc->flag,
00411 _tbc->auto_col, _tbc->auto_val);
00412 dbt_print_table(_tbc, NULL);
00413 } else {
00414 if(_tbc->flag & DBT_TBFL_MODI)
00415 {
00416 dbt_print_table(_tbc, &(_tbc->dbname));
00417 dbt_table_update_flags(_tbc,DBT_TBFL_MODI, DBT_FL_UNSET, 0);
00418 }
00419 }
00420 _tbc = _tbc->next;
00421 }
00422 lock_release(&_dbt_cachetbl[i].sem);
00423 }
00424
00425 return 0;
00426 }
00427
00428 int dbt_is_neq_type(db_type_t _t0, db_type_t _t1)
00429 {
00430
00431 if(_t0 == _t1)
00432 return 0;
00433 switch(_t1)
00434 {
00435 case DB_INT:
00436 if(_t0==DB_DATETIME || _t0==DB_BITMAP)
00437 return 0;
00438
00439 case DB_BIGINT:
00440 LM_ERR("BIGINT not supported");
00441 return 0;
00442
00443 case DB_DATETIME:
00444 if(_t0==DB_INT)
00445 return 0;
00446 if(_t0==DB_BITMAP)
00447 return 0;
00448 case DB_DOUBLE:
00449 break;
00450 case DB_STRING:
00451 if(_t0==DB_STR)
00452 return 0;
00453 case DB_STR:
00454 if(_t0==DB_STRING || _t0==DB_BLOB)
00455 return 0;
00456 case DB_BLOB:
00457 if(_t0==DB_STR)
00458 return 0;
00459 case DB_BITMAP:
00460 if (_t0==DB_INT)
00461 return 0;
00462 }
00463 return 1;
00464 }
00465