dbt_res.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. /*
  2. * $Id$
  3. *
  4. * DBText module core functions
  5. *
  6. * Copyright (C) 2001-2003 FhG Fokus
  7. *
  8. * This file is part of ser, a free SIP server.
  9. *
  10. * ser 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. * For a license to use the ser software under conditions
  16. * other than those described here, or to purchase support for this
  17. * software, please contact iptel.org by e-mail at the following addresses:
  18. * [email protected]
  19. *
  20. * ser is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU General Public License
  26. * along with this program; if not, write to the Free Software
  27. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  28. */
  29. /**
  30. * DBText module interface
  31. * 2003-06-05 fixed bug: when comparing two values and the first was less than
  32. * the second one, the result of 'dbt_row_match' was always true,
  33. * thanks to Gabriel, (Daniel)
  34. * 2003-02-04 created by Daniel
  35. *
  36. */
  37. #include <stdio.h>
  38. #include <string.h>
  39. #include <sys/types.h>
  40. #include "../../mem/mem.h"
  41. #include "dbt_res.h"
  42. dbt_result_p dbt_result_new(dbt_table_p _dtp, int *_lres, int _sz)
  43. {
  44. dbt_result_p _dres = NULL;
  45. int i, n;
  46. char *p;
  47. if(!_dtp || _sz < 0)
  48. return NULL;
  49. if(!_lres)
  50. _sz = _dtp->nrcols;
  51. _dres = (dbt_result_p)pkg_malloc(sizeof(dbt_result_t));
  52. if(!_dres)
  53. return NULL;
  54. _dres->colv = (dbt_column_p)pkg_malloc(_sz*sizeof(dbt_column_t));
  55. if(!_dres->colv)
  56. {
  57. DBG("DBT:dbt_result_new: no memory!\n");
  58. pkg_free(_dres);
  59. return NULL;
  60. }
  61. DBG("DBT:dbt_result_new: new res with %d cols\n", _sz);
  62. for(i = 0; i < _sz; i++)
  63. {
  64. n = (_lres)?_dtp->colv[_lres[i]]->name.len:_dtp->colv[i]->name.len;
  65. p = (_lres)?_dtp->colv[_lres[i]]->name.s:_dtp->colv[i]->name.s;
  66. _dres->colv[i].name.s = (char*)pkg_malloc((n+1)*sizeof(char));
  67. if(!_dres->colv[i].name.s)
  68. {
  69. DBG("DBT:dbt_result_new: no memory\n");
  70. goto clean;
  71. }
  72. _dres->colv[i].name.len = n;
  73. strncpy(_dres->colv[i].name.s, p, n);
  74. _dres->colv[i].name.s[n] = 0;
  75. _dres->colv[i].type =
  76. (_lres)?_dtp->colv[_lres[i]]->type:_dtp->colv[i]->type;
  77. }
  78. _dres->nrcols = _sz;
  79. _dres->nrrows = 0;
  80. _dres->rows = NULL;
  81. return _dres;
  82. clean:
  83. while(i>=0)
  84. {
  85. if(_dres->colv[i].name.s)
  86. pkg_free(_dres->colv[i].name.s);
  87. i--;
  88. }
  89. pkg_free(_dres->colv);
  90. pkg_free(_dres);
  91. return NULL;
  92. }
  93. int dbt_result_free(dbt_result_p _dres)
  94. {
  95. dbt_row_p _rp=NULL, _rp0=NULL;
  96. int i;
  97. if(!_dres)
  98. return -1;
  99. _rp = _dres->rows;
  100. while(_rp)
  101. {
  102. _rp0=_rp;
  103. if(_rp0->fields)
  104. {
  105. for(i=0; i<_dres->nrcols; i++)
  106. {
  107. if(_dres->colv[i].type==DB_STR
  108. && _rp0->fields[i].val.str_val.s)
  109. pkg_free(_rp0->fields[i].val.str_val.s);
  110. }
  111. pkg_free(_rp0->fields);
  112. }
  113. pkg_free(_rp0);
  114. _rp=_rp->next;
  115. }
  116. if(_dres->colv)
  117. {
  118. for(i=0; i<_dres->nrcols; i++)
  119. {
  120. if(_dres->colv[i].name.s)
  121. pkg_free(_dres->colv[i].name.s);
  122. }
  123. pkg_free(_dres->colv);
  124. }
  125. pkg_free(_dres);
  126. return 0;
  127. }
  128. int dbt_result_add_row(dbt_result_p _dres, dbt_row_p _drp)
  129. {
  130. if(!_dres || !_drp)
  131. return -1;
  132. _dres->nrrows++;
  133. if(_dres->rows)
  134. (_dres->rows)->prev = _drp;
  135. _drp->next = _dres->rows;
  136. _dres->rows = _drp;
  137. return 0;
  138. }
  139. int* dbt_get_refs(dbt_table_p _dtp, db_key_t* _k, int _n)
  140. {
  141. int i, j, *_lref=NULL;
  142. if(!_dtp || !_k || _n < 0)
  143. return NULL;
  144. _lref = (int*)pkg_malloc(_n*sizeof(int));
  145. if(!_lref)
  146. return NULL;
  147. for(i=0; i < _n; i++)
  148. {
  149. for(j=0; j<_dtp->nrcols; j++)
  150. {
  151. if(strlen(_k[i])==_dtp->colv[j]->name.len
  152. && !strncasecmp(_k[i], _dtp->colv[j]->name.s,
  153. _dtp->colv[j]->name.len))
  154. {
  155. _lref[i] = j;
  156. break;
  157. }
  158. }
  159. if(j>=_dtp->nrcols)
  160. {
  161. DBG("DBT:dbt_get_refs: ERROR column <%s> not found\n", _k[i]);
  162. pkg_free(_lref);
  163. return NULL;
  164. }
  165. }
  166. return _lref;
  167. }
  168. int dbt_row_match(dbt_table_p _dtp, dbt_row_p _drp, int* _lkey,
  169. db_op_t* _op, db_val_t* _v, int _n)
  170. {
  171. int i, res;
  172. if(!_dtp || !_drp)
  173. return 0;
  174. if(!_lkey)
  175. return 1;
  176. for(i=0; i<_n; i++)
  177. {
  178. res = dbt_cmp_val(&_drp->fields[_lkey[i]], &_v[i]);
  179. if(!_op || !strcmp(_op[i], OP_EQ))
  180. {
  181. if(res!=0)
  182. return 0;
  183. }else{
  184. if(!strcmp(_op[i], OP_LT))
  185. {
  186. if(res!=-1)
  187. return 0;
  188. }else{
  189. if(!strcmp(_op[i], OP_GT))
  190. {
  191. if(res!=1)
  192. return 0;
  193. }else{
  194. if(!strcmp(_op[i], OP_LEQ))
  195. {
  196. if(res==1)
  197. return 0;
  198. }else{
  199. if(!strcmp(_op[i], OP_GEQ))
  200. {
  201. if(res==-1)
  202. return 0;
  203. }else{
  204. return 0;
  205. }}}}}
  206. }
  207. return 1;
  208. }
  209. int dbt_result_extract_fields(dbt_table_p _dtp, dbt_row_p _drp,
  210. int* _lres, dbt_result_p _dres)
  211. {
  212. dbt_row_p _rp=NULL;
  213. int i, n;
  214. if(!_dtp || !_drp || !_dres || _dres->nrcols<=0)
  215. return -1;
  216. _rp = dbt_result_new_row(_dres);
  217. if(!_rp)
  218. return -1;
  219. for(i=0; i<_dres->nrcols; i++)
  220. {
  221. n = (_lres)?_lres[i]:i;
  222. if(dbt_is_neq_type(_dres->colv[i].type, _dtp->colv[n]->type))
  223. {
  224. DBG("DBT:dbt_result_extract_fields: wrong types!\n");
  225. goto clean;
  226. }
  227. _rp->fields[i].nul = _drp->fields[n].nul;
  228. if(_rp->fields[i].nul)
  229. {
  230. memset(&(_rp->fields[i].val), 0, sizeof(_rp->fields[i].val));
  231. continue;
  232. }
  233. switch(_dres->colv[i].type)
  234. {
  235. case DB_INT:
  236. case DB_DATETIME:
  237. case DB_BITMAP:
  238. _rp->fields[i].type = DB_INT;
  239. _rp->fields[i].val.int_val = _drp->fields[n].val.int_val;
  240. break;
  241. case DB_FLOAT:
  242. _rp->fields[i].type = DB_FLOAT;
  243. _rp->fields[i].val.float_val=_drp->fields[n].val.float_val;
  244. break;
  245. case DB_DOUBLE:
  246. _rp->fields[i].type = DB_DOUBLE;
  247. _rp->fields[i].val.double_val=_drp->fields[n].val.double_val;
  248. break;
  249. case DB_STRING:
  250. case DB_STR:
  251. case DB_BLOB:
  252. _rp->fields[i].type = DB_STR;
  253. _rp->fields[i].val.str_val.len =
  254. _drp->fields[n].val.str_val.len;
  255. _rp->fields[i].val.str_val.s =(char*)pkg_malloc(sizeof(char)*
  256. (_drp->fields[n].val.str_val.len+1));
  257. if(!_rp->fields[i].val.str_val.s)
  258. goto clean;
  259. strncpy(_rp->fields[i].val.str_val.s,
  260. _drp->fields[n].val.str_val.s,
  261. _rp->fields[i].val.str_val.len);
  262. _rp->fields[i].val.str_val.s[_rp->fields[i].val.str_val.len]=0;
  263. break;
  264. default:
  265. goto clean;
  266. }
  267. }
  268. if(_dres->rows)
  269. (_dres->rows)->prev = _rp;
  270. _rp->next = _dres->rows;
  271. _dres->rows = _rp;
  272. _dres->nrrows++;
  273. return 0;
  274. clean:
  275. DBG("DBT:dbt_result_extract_fields: make clean!\n");
  276. while(i>=0)
  277. {
  278. if(_rp->fields[i].type == DB_STR
  279. && !_rp->fields[i].nul
  280. && _rp->fields[i].val.str_val.s)
  281. pkg_free(_rp->fields[i].val.str_val.s);
  282. i--;
  283. }
  284. pkg_free(_rp->fields);
  285. pkg_free(_rp);
  286. return -1;
  287. }
  288. int dbt_result_print(dbt_result_p _dres)
  289. {
  290. #ifdef DBT_EXTRA_DEBUG
  291. int i;
  292. FILE *fout = stdout;
  293. dbt_row_p rowp = NULL;
  294. char *p;
  295. if(!_dres || _dres->nrcols<=0)
  296. return -1;
  297. fprintf(fout, "\nContent of result\n");
  298. for(i=0; i<_dres->nrcols; i++)
  299. {
  300. switch(_dres->colv[i].type)
  301. {
  302. case DB_INT:
  303. fprintf(fout, "%.*s(int", _dres->colv[i].name.len,
  304. _dres->colv[i].name.s);
  305. if(_dres->colv[i].flag & DBT_FLAG_NULL)
  306. fprintf(fout, ",null");
  307. fprintf(fout, ") ");
  308. break;
  309. case DB_FLOAT:
  310. fprintf(fout, "%.*s(float", _dres->colv[i].name.len,
  311. _dres->colv[i].name.s);
  312. if(_dres->colv[i].flag & DBT_FLAG_NULL)
  313. fprintf(fout, ",null");
  314. fprintf(fout, ") ");
  315. break;
  316. case DB_DOUBLE:
  317. fprintf(fout, "%.*s(double", _dres->colv[i].name.len,
  318. _dres->colv[i].name.s);
  319. if(_dres->colv[i].flag & DBT_FLAG_NULL)
  320. fprintf(fout, ",null");
  321. fprintf(fout, ") ");
  322. break;
  323. case DB_STR:
  324. fprintf(fout, "%.*s(str", _dres->colv[i].name.len,
  325. _dres->colv[i].name.s);
  326. if(_dres->colv[i].flag & DBT_FLAG_NULL)
  327. fprintf(fout, ",null");
  328. fprintf(fout, ") ");
  329. break;
  330. default:
  331. return -1;
  332. }
  333. }
  334. fprintf(fout, "\n");
  335. rowp = _dres->rows;
  336. while(rowp)
  337. {
  338. for(i=0; i<_dres->nrcols; i++)
  339. {
  340. switch(_dres->colv[i].type)
  341. {
  342. case DB_INT:
  343. if(rowp->fields[i].nul)
  344. fprintf(fout, "N ");
  345. else
  346. fprintf(fout, "%d ",
  347. rowp->fields[i].val.int_val);
  348. break;
  349. case DB_FLOAT:
  350. if(rowp->fields[i].nul)
  351. fprintf(fout, "N ");
  352. else
  353. fprintf(fout, "%.2f ",
  354. rowp->fields[i].val.float_val);
  355. break;
  356. case DB_DOUBLE:
  357. if(rowp->fields[i].nul)
  358. fprintf(fout, "N ");
  359. else
  360. fprintf(fout, "%.2f ",
  361. rowp->fields[i].val.double_val);
  362. break;
  363. case DB_STR:
  364. fprintf(fout, "\"");
  365. if(!rowp->fields[i].nul)
  366. {
  367. p = rowp->fields[i].val.str_val.s;
  368. while(p < rowp->fields[i].val.str_val.s
  369. + rowp->fields[i].val.str_val.len)
  370. {
  371. switch(*p)
  372. {
  373. case '\n':
  374. fprintf(fout, "\\n");
  375. break;
  376. case '\r':
  377. fprintf(fout, "\\r");
  378. break;
  379. case '\t':
  380. fprintf(fout, "\\t");
  381. break;
  382. case '\\':
  383. fprintf(fout, "\\\\");
  384. break;
  385. case '"':
  386. fprintf(fout, "\\\"");
  387. break;
  388. case '\0':
  389. fprintf(fout, "\\0");
  390. break;
  391. default:
  392. fprintf(fout, "%c", *p);
  393. }
  394. p++;
  395. }
  396. }
  397. fprintf(fout, "\" ");
  398. break;
  399. default:
  400. return -1;
  401. }
  402. }
  403. fprintf(fout, "\n");
  404. rowp = rowp->next;
  405. }
  406. #endif
  407. return 0;
  408. }
  409. int dbt_cmp_val(dbt_val_p _vp, db_val_t* _v)
  410. {
  411. int _l, _n;
  412. if(!_vp && !_v)
  413. return 0;
  414. if(!_v)
  415. return 1;
  416. if(!_vp)
  417. return -1;
  418. if(_vp->nul && _v->nul)
  419. return 0;
  420. if(_v->nul)
  421. return 1;
  422. if(_vp->nul)
  423. return -1;
  424. switch(VAL_TYPE(_v))
  425. {
  426. case DB_INT:
  427. return (_vp->val.int_val<_v->val.int_val)?-1:
  428. (_vp->val.int_val>_v->val.int_val)?1:0;
  429. case DB_FLOAT:
  430. return (_vp->val.float_val<_v->val.float_val)?-1:
  431. (_vp->val.float_val>_v->val.float_val)?1:0;
  432. case DB_DOUBLE:
  433. return (_vp->val.double_val<_v->val.double_val)?-1:
  434. (_vp->val.double_val>_v->val.double_val)?1:0;
  435. case DB_DATETIME:
  436. return (_vp->val.int_val<_v->val.time_val)?-1:
  437. (_vp->val.int_val>_v->val.time_val)?1:0;
  438. case DB_STRING:
  439. _l = strlen(_v->val.string_val);
  440. _l = (_l>_vp->val.str_val.len)?_vp->val.str_val.len:_l;
  441. _n = strncasecmp(_vp->val.str_val.s, _v->val.string_val, _l);
  442. if(_n)
  443. return _n;
  444. if(_vp->val.str_val.len == strlen(_v->val.string_val))
  445. return 0;
  446. if(_l==_vp->val.str_val.len)
  447. return -1;
  448. return 1;
  449. case DB_STR:
  450. _l = _v->val.str_val.len;
  451. _l = (_l>_vp->val.str_val.len)?_vp->val.str_val.len:_l;
  452. _n = strncasecmp(_vp->val.str_val.s, _v->val.str_val.s, _l);
  453. if(_n)
  454. return _n;
  455. if(_vp->val.str_val.len == _v->val.str_val.len)
  456. return 0;
  457. if(_l==_vp->val.str_val.len)
  458. return -1;
  459. return 1;
  460. case DB_BLOB:
  461. _l = _v->val.blob_val.len;
  462. _l = (_l>_vp->val.str_val.len)?_vp->val.str_val.len:_l;
  463. _n = strncasecmp(_vp->val.str_val.s, _v->val.blob_val.s, _l);
  464. if(_n)
  465. return _n;
  466. if(_vp->val.str_val.len == _v->val.blob_val.len)
  467. return 0;
  468. if(_l==_vp->val.str_val.len)
  469. return -1;
  470. return 1;
  471. case DB_BITMAP:
  472. return (_vp->val.int_val<_v->val.bitmap_val)?-1:
  473. (_vp->val.int_val>_v->val.bitmap_val)?1:0;
  474. }
  475. return -2;
  476. }
  477. dbt_row_p dbt_result_new_row(dbt_result_p _dres)
  478. {
  479. dbt_row_p _drp = NULL;
  480. if(!_dres || _dres->nrcols<=0)
  481. return NULL;
  482. _drp = (dbt_row_p)pkg_malloc(sizeof(dbt_row_t));
  483. if(!_drp)
  484. return NULL;
  485. memset(_drp, 0, sizeof(dbt_row_t));
  486. _drp->fields = (dbt_val_p)pkg_malloc(_dres->nrcols*sizeof(dbt_val_t));
  487. if(!_drp->fields)
  488. {
  489. pkg_free(_drp);
  490. return NULL;
  491. }
  492. memset(_drp->fields, 0, _dres->nrcols*sizeof(dbt_val_t));
  493. _drp->next = _drp->prev = NULL;
  494. return _drp;
  495. }
  496. int dbt_is_neq_type(db_type_t _t0, db_type_t _t1)
  497. {
  498. // DBG("DBT:dbt_is_neq_type: t0=%d t1=%d!\n", _t0, _t1);
  499. if(_t0 == _t1)
  500. return 0;
  501. switch(_t1)
  502. {
  503. case DB_INT:
  504. if(_t0==DB_DATETIME || _t0==DB_BITMAP)
  505. return 0;
  506. case DB_DATETIME:
  507. if(_t0==DB_INT)
  508. return 0;
  509. if(_t0==DB_BITMAP)
  510. return 0;
  511. case DB_FLOAT:
  512. break;
  513. case DB_DOUBLE:
  514. break;
  515. case DB_STRING:
  516. if(_t0==DB_STR)
  517. return 0;
  518. case DB_STR:
  519. if(_t0==DB_STRING || _t0==DB_BLOB)
  520. return 0;
  521. case DB_BLOB:
  522. if(_t0==DB_STR)
  523. return 0;
  524. case DB_BITMAP:
  525. if (_t0==DB_INT)
  526. return 0;
  527. }
  528. return 1;
  529. }