dbt_lib.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. /*
  2. * $Id$
  3. *
  4. * DBText library
  5. *
  6. * Copyright (C) 2001-2003 FhG Fokus
  7. *
  8. * This file is part of Kamailio, a free SIP server.
  9. *
  10. * Kamailio is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version
  14. *
  15. * Kamailio is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * History:
  25. * --------
  26. * 2003-01-30 created by Daniel
  27. *
  28. */
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <time.h>
  32. #include <sys/types.h>
  33. #include <dirent.h>
  34. #include "../../mem/shm_mem.h"
  35. #include "../../mem/mem.h"
  36. #include "../../dprint.h"
  37. #include "../../hashes.h"
  38. #include "dbt_util.h"
  39. #include "dbt_lib.h"
  40. static dbt_cache_p *_dbt_cachedb = NULL;
  41. static gen_lock_t *_dbt_cachesem = NULL;
  42. static dbt_tbl_cachel_p _dbt_cachetbl = NULL;
  43. #define DBT_CACHETBL_SIZE 16
  44. /**
  45. *
  46. */
  47. int dbt_init_cache(void)
  48. {
  49. int i, j;
  50. if(!_dbt_cachesem)
  51. {
  52. /* init locks */
  53. _dbt_cachesem = lock_alloc();
  54. if(!_dbt_cachesem)
  55. {
  56. LM_CRIT("could not alloc a lock\n");
  57. return -1;
  58. }
  59. if (lock_init(_dbt_cachesem)==0)
  60. {
  61. LM_CRIT("could not initialize a lock\n");
  62. lock_dealloc(_dbt_cachesem);
  63. return -1;
  64. }
  65. }
  66. /* init pointer to caches list */
  67. if (!_dbt_cachedb) {
  68. _dbt_cachedb = shm_malloc( sizeof(dbt_cache_p) );
  69. if (!_dbt_cachedb) {
  70. LM_CRIT("no enough shm mem\n");
  71. lock_dealloc(_dbt_cachesem);
  72. return -1;
  73. }
  74. *_dbt_cachedb = NULL;
  75. }
  76. /* init tables' hash table */
  77. if (!_dbt_cachetbl) {
  78. _dbt_cachetbl
  79. = (dbt_tbl_cachel_p)shm_malloc(DBT_CACHETBL_SIZE*
  80. sizeof(dbt_tbl_cachel_t));
  81. if(_dbt_cachetbl==NULL)
  82. {
  83. LM_CRIT("no enough shm mem\n");
  84. lock_dealloc(_dbt_cachesem);
  85. shm_free(_dbt_cachedb);
  86. return -1;
  87. }
  88. memset(_dbt_cachetbl, 0, DBT_CACHETBL_SIZE*sizeof(dbt_tbl_cachel_t));
  89. for(i=0; i<DBT_CACHETBL_SIZE; i++)
  90. {
  91. if (lock_init(&_dbt_cachetbl[i].sem)==0)
  92. {
  93. LM_CRIT("cannot init tables' sem's\n");
  94. for(j=i-1; j>=0; j--)
  95. lock_destroy(&_dbt_cachetbl[j].sem);
  96. lock_dealloc(_dbt_cachesem);
  97. shm_free(_dbt_cachedb);
  98. return -1;
  99. }
  100. }
  101. }
  102. return 0;
  103. }
  104. /**
  105. *
  106. */
  107. dbt_cache_p dbt_cache_get_db(str *_s)
  108. {
  109. dbt_cache_p _dcache=NULL;;
  110. if(!_dbt_cachesem || !_dbt_cachedb)
  111. {
  112. LM_ERR("dbtext cache is not initialized! Check if you loaded"
  113. " dbtext before any other module that uses it\n");
  114. return NULL;
  115. }
  116. if(!_s || !_s->s || _s->len<=0)
  117. return NULL;
  118. LM_DBG("looking for db %.*s!\n",_s->len,_s->s);
  119. lock_get(_dbt_cachesem);
  120. _dcache = *_dbt_cachedb;
  121. while(_dcache)
  122. {
  123. if(_dcache->name.len==_s->len
  124. && !strncasecmp(_dcache->name.s, _s->s, _s->len))
  125. {
  126. LM_DBG("db already cached!\n");
  127. goto done;
  128. }
  129. _dcache = _dcache->next;
  130. }
  131. if(!dbt_is_database(_s))
  132. {
  133. LM_ERR("database [%.*s] does not exists!\n", _s->len, _s->s);
  134. goto done;
  135. }
  136. LM_DBG("new db!\n");
  137. _dcache = (dbt_cache_p)shm_malloc(sizeof(dbt_cache_t));
  138. if(!_dcache)
  139. {
  140. LM_ERR(" no shm memory for dbt_cache_t.\n");
  141. goto done;
  142. }
  143. memset(_dcache, 0, sizeof(dbt_cache_t));
  144. _dcache->name.s = (char*)shm_malloc((_s->len+1)*sizeof(char));
  145. if(!_dcache->name.s)
  146. {
  147. LM_ERR(" no shm memory for s!!\n");
  148. shm_free(_dcache);
  149. _dcache = NULL;
  150. goto done;
  151. }
  152. memcpy(_dcache->name.s, _s->s, _s->len);
  153. _dcache->name.s[_s->len] = '\0';
  154. _dcache->name.len = _s->len;
  155. if(*_dbt_cachedb)
  156. _dcache->next = *_dbt_cachedb;
  157. *_dbt_cachedb = _dcache;
  158. done:
  159. lock_release(_dbt_cachesem);
  160. return _dcache;
  161. }
  162. /**
  163. *
  164. */
  165. int dbt_cache_check_db(str *_s)
  166. {
  167. dbt_cache_p _dcache=NULL;;
  168. if(!_dbt_cachesem || !(*_dbt_cachedb)
  169. || !_s || !_s->s || _s->len<=0)
  170. return -1;
  171. lock_get(_dbt_cachesem);
  172. _dcache = *_dbt_cachedb;
  173. while(_dcache)
  174. {
  175. if(_dcache->name.len == _s->len &&
  176. strncasecmp(_dcache->name.s, _s->s, _s->len))
  177. {
  178. lock_release(_dbt_cachesem);
  179. return 0;
  180. }
  181. _dcache = _dcache->next;
  182. }
  183. lock_release(_dbt_cachesem);
  184. return -1;
  185. }
  186. /**
  187. *
  188. */
  189. int dbt_db_del_table(dbt_cache_p _dc, const str *_s, int sync)
  190. {
  191. dbt_table_p _tbc = NULL;
  192. int hash;
  193. int hashidx;
  194. if(!_dbt_cachetbl || !_dc || !_s || !_s->s || _s->len<=0)
  195. return -1;
  196. hash = core_hash(&_dc->name, _s, DBT_CACHETBL_SIZE);
  197. hashidx = hash % DBT_CACHETBL_SIZE;
  198. if(sync)
  199. lock_get(&_dbt_cachetbl[hashidx].sem);
  200. _tbc = _dbt_cachetbl[hashidx].dtp;
  201. while(_tbc)
  202. {
  203. if(_tbc->hash==hash && _tbc->dbname.len == _dc->name.len
  204. && _tbc->name.len == _s->len
  205. && !strncasecmp(_tbc->dbname.s, _dc->name.s, _dc->name.len)
  206. && !strncasecmp(_tbc->name.s, _s->s, _s->len))
  207. {
  208. if(_tbc->prev)
  209. (_tbc->prev)->next = _tbc->next;
  210. else
  211. _dbt_cachetbl[hashidx].dtp = _tbc->next;
  212. if(_tbc->next)
  213. (_tbc->next)->prev = _tbc->prev;
  214. break;
  215. }
  216. _tbc = _tbc->next;
  217. }
  218. if(sync)
  219. lock_release(&_dbt_cachetbl[hashidx].sem);
  220. dbt_table_free(_tbc);
  221. return 0;
  222. }
  223. /**
  224. *
  225. */
  226. dbt_table_p dbt_db_get_table(dbt_cache_p _dc, const str *_s)
  227. {
  228. dbt_table_p _tbc = NULL;
  229. int hash;
  230. int hashidx;
  231. if(!_dbt_cachetbl || !_dc || !_s || !_s->s || _s->len<=0) {
  232. LM_ERR("invalid parameter");
  233. return NULL;
  234. }
  235. hash = core_hash(&_dc->name, _s, DBT_CACHETBL_SIZE);
  236. hashidx = hash % DBT_CACHETBL_SIZE;
  237. lock_get(&_dbt_cachetbl[hashidx].sem);
  238. _tbc = _dbt_cachetbl[hashidx].dtp;
  239. while(_tbc)
  240. {
  241. if(_tbc->hash==hash && _tbc->dbname.len == _dc->name.len
  242. && _tbc->name.len == _s->len
  243. && !strncasecmp(_tbc->dbname.s, _dc->name.s, _dc->name.len)
  244. && !strncasecmp(_tbc->name.s, _s->s, _s->len))
  245. {
  246. /* found - if cache mode or no-change, return */
  247. if(db_mode==0 || dbt_check_mtime(_s, &(_dc->name), &(_tbc->mt))!=1)
  248. {
  249. LM_DBG("cache or mtime succeeded for [%.*s]\n",
  250. _tbc->name.len, _tbc->name.s);
  251. return _tbc;
  252. }
  253. break;
  254. }
  255. _tbc = _tbc->next;
  256. }
  257. /* new table */
  258. if(_tbc) /* free old one */
  259. {
  260. dbt_db_del_table(_dc, _s, 0);
  261. }
  262. _tbc = dbt_load_file(_s, &(_dc->name));
  263. if(!_tbc)
  264. {
  265. LM_ERR("could not load database from file [%.*s]", _s->len, _s->s);
  266. lock_release(&_dbt_cachetbl[hashidx].sem);
  267. return NULL;
  268. }
  269. _tbc->hash = hash;
  270. _tbc->next = _dbt_cachetbl[hashidx].dtp;
  271. if(_dbt_cachetbl[hashidx].dtp)
  272. _dbt_cachetbl[hashidx].dtp->prev = _tbc;
  273. _dbt_cachetbl[hashidx].dtp = _tbc;
  274. /* table is locked */
  275. return _tbc;
  276. }
  277. int dbt_release_table(dbt_cache_p _dc, const str *_s)
  278. {
  279. int hash;
  280. int hashidx;
  281. if(!_dbt_cachetbl || !_dc || !_s || !_s->s || _s->len<=0)
  282. return -1;
  283. hash = core_hash(&_dc->name, _s, DBT_CACHETBL_SIZE);
  284. hashidx = hash % DBT_CACHETBL_SIZE;
  285. lock_release(&_dbt_cachetbl[hashidx].sem);
  286. return 0;
  287. }
  288. /**
  289. *
  290. */
  291. int dbt_cache_destroy(void)
  292. {
  293. int i;
  294. dbt_cache_p _dc=NULL, _dc0=NULL;
  295. dbt_table_p _tbc = NULL;
  296. dbt_table_p _tbc0 = NULL;
  297. if(!_dbt_cachesem)
  298. return -1;
  299. lock_get(_dbt_cachesem);
  300. if( _dbt_cachedb!=NULL )
  301. {
  302. _dc = *_dbt_cachedb;
  303. while(_dc)
  304. {
  305. _dc0 = _dc;
  306. _dc = _dc->next;
  307. shm_free(_dc0->name.s);
  308. shm_free(_dc0);
  309. }
  310. shm_free(_dbt_cachedb);
  311. }
  312. lock_destroy(_dbt_cachesem);
  313. lock_dealloc(_dbt_cachesem);
  314. /* destroy tables' hash table*/
  315. if(_dbt_cachetbl==0)
  316. return 0;
  317. for(i=0; i<DBT_CACHETBL_SIZE; i++)
  318. {
  319. lock_destroy(&_dbt_cachetbl[i].sem);
  320. _tbc = _dbt_cachetbl[i].dtp;
  321. while(_tbc)
  322. {
  323. _tbc0 = _tbc;
  324. _tbc = _tbc->next;
  325. dbt_table_free(_tbc0);
  326. }
  327. }
  328. shm_free(_dbt_cachetbl);
  329. return 0;
  330. }
  331. /**
  332. *
  333. */
  334. int dbt_cache_print(int _f)
  335. {
  336. int i;
  337. dbt_table_p _tbc;
  338. if(!_dbt_cachetbl)
  339. return -1;
  340. for(i=0; i< DBT_CACHETBL_SIZE; i++)
  341. {
  342. lock_get(&_dbt_cachetbl[i].sem);
  343. _tbc = _dbt_cachetbl[i].dtp;
  344. while(_tbc)
  345. {
  346. if(_f)
  347. fprintf(stdout, "\n--- Database [%.*s]\n", _tbc->dbname.len,
  348. _tbc->dbname.s);
  349. if(_f)
  350. {
  351. fprintf(stdout, "\n----- Table [%.*s]\n",
  352. _tbc->name.len, _tbc->name.s);
  353. fprintf(stdout, "------- LA=<%d> FL=<%x> AC=<%d>"
  354. " AV=<%d>\n", _tbc->mark, _tbc->flag,
  355. _tbc->auto_col, _tbc->auto_val);
  356. dbt_print_table(_tbc, NULL);
  357. } else {
  358. if(_tbc->flag & DBT_TBFL_MODI)
  359. {
  360. dbt_print_table(_tbc, &(_tbc->dbname));
  361. dbt_table_update_flags(_tbc,DBT_TBFL_MODI, DBT_FL_UNSET, 0);
  362. }
  363. }
  364. _tbc = _tbc->next;
  365. }
  366. lock_release(&_dbt_cachetbl[i].sem);
  367. }
  368. return 0;
  369. }
  370. int dbt_is_neq_type(db_type_t _t0, db_type_t _t1)
  371. {
  372. // LM_DBG("t0=%d t1=%d!\n", _t0, _t1);
  373. if(_t0 == _t1)
  374. return 0;
  375. switch(_t1)
  376. {
  377. case DB1_INT:
  378. if(_t0==DB1_DATETIME || _t0==DB1_BITMAP)
  379. return 0;
  380. case DB1_BIGINT:
  381. LM_ERR("BIGINT not supported");
  382. return 0;
  383. case DB1_DATETIME:
  384. if(_t0==DB1_INT)
  385. return 0;
  386. if(_t0==DB1_BITMAP)
  387. return 0;
  388. case DB1_DOUBLE:
  389. break;
  390. case DB1_STRING:
  391. if(_t0==DB1_STR)
  392. return 0;
  393. case DB1_STR:
  394. if(_t0==DB1_STRING || _t0==DB1_BLOB)
  395. return 0;
  396. case DB1_BLOB:
  397. if(_t0==DB1_STR)
  398. return 0;
  399. case DB1_BITMAP:
  400. if (_t0==DB1_INT)
  401. return 0;
  402. default:
  403. LM_ERR("invalid datatype %d\n", _t1);
  404. return 1;
  405. }
  406. return 1;
  407. }