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
00031 #include <string.h>
00032
00033 #include "../../str.h"
00034 #include "../../mem/mem.h"
00035 #include "../../mem/shm_mem.h"
00036
00037 #include "dbtext.h"
00038 #include "dbt_res.h"
00039 #include "dbt_api.h"
00040
00041 #ifndef CFG_DIR
00042 #define CFG_DIR "/tmp"
00043 #endif
00044
00045 #define DBT_ID "text://"
00046 #define DBT_ID_LEN (sizeof(DBT_ID)-1)
00047 #define DBT_PATH_LEN 256
00048
00049
00050
00051 db_con_t* dbt_init(const str* _sqlurl)
00052 {
00053 db_con_t* _res;
00054 str _s;
00055 char dbt_path[DBT_PATH_LEN];
00056
00057 if (!_sqlurl || !_sqlurl->s)
00058 {
00059 LM_ERR("invalid parameter value\n");
00060 return NULL;
00061 }
00062 _s.s = _sqlurl->s;
00063 _s.len = _sqlurl->len;
00064 if(_s.len <= DBT_ID_LEN || strncmp(_s.s, DBT_ID, DBT_ID_LEN)!=0)
00065 {
00066 LM_ERR("invalid database URL - should be:"
00067 " <%s[/]path/to/directory>\n", DBT_ID);
00068 return NULL;
00069 }
00070
00071
00072
00073
00074 _s.s += DBT_ID_LEN;
00075 _s.len -= DBT_ID_LEN;
00076 if(_s.s[0]!='/')
00077 {
00078 if(sizeof(CFG_DIR)+_s.len+2 > DBT_PATH_LEN)
00079 {
00080 LM_ERR("path to database is too long\n");
00081 return NULL;
00082 }
00083 strcpy(dbt_path, CFG_DIR);
00084 dbt_path[sizeof(CFG_DIR)] = '/';
00085 strncpy(&dbt_path[sizeof(CFG_DIR)+1], _s.s, _s.len);
00086 _s.len += sizeof(CFG_DIR);
00087 _s.s = dbt_path;
00088 }
00089
00090 _res = pkg_malloc(sizeof(db_con_t)+sizeof(dbt_con_t));
00091 if (!_res)
00092 {
00093 LM_ERR("no pkg memory left\n");
00094 return NULL;
00095 }
00096 memset(_res, 0, sizeof(db_con_t) + sizeof(dbt_con_t));
00097 _res->tail = (unsigned long)((char*)_res+sizeof(db_con_t));
00098
00099 LM_INFO("using database at: %.*s", _s.len, _s.s);
00100 DBT_CON_CONNECTION(_res) = dbt_cache_get_db(&_s);
00101 if (!DBT_CON_CONNECTION(_res))
00102 {
00103 LM_ERR("cannot get the link to database\n");
00104 return NULL;
00105 }
00106
00107 return _res;
00108 }
00109
00110
00111
00112
00113
00114 void dbt_close(db_con_t* _h)
00115 {
00116 if (!_h)
00117 {
00118 LM_ERR("invalid parameter value\n");
00119 return;
00120 }
00121
00122 if (DBT_CON_RESULT(_h))
00123 dbt_result_free(DBT_CON_RESULT(_h));
00124
00125 pkg_free(_h);
00126 return;
00127 }
00128
00129
00130
00131
00132
00133 int dbt_free_result(db_con_t* _h, db_res_t* _r)
00134 {
00135 if ((!_h) || (!_r))
00136 {
00137 LM_ERR("invalid parameter value\n");
00138 return -1;
00139 }
00140
00141 if(db_free_result(_r) < 0)
00142 {
00143 LM_ERR("unable to free result structure\n");
00144 return -1;
00145 }
00146
00147
00148 if(dbt_result_free(DBT_CON_RESULT(_h)) < 0)
00149 {
00150 LM_ERR("unable to free internal structure\n");
00151 return -1;
00152 }
00153 DBT_CON_RESULT(_h) = NULL;
00154 return 0;
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 int dbt_query(db_con_t* _h, db_key_t* _k, db_op_t* _op, db_val_t* _v,
00171 db_key_t* _c, int _n, int _nc, db_key_t _o, db_res_t** _r)
00172 {
00173 dbt_table_p _tbc = NULL;
00174 dbt_row_p _drp = NULL;
00175 dbt_result_p _dres = NULL;
00176
00177 int *lkey=NULL, *lres=NULL;
00178
00179 db_key_t *_o_k=NULL;
00180 char *_o_op=NULL;
00181 int _o_n;
00182 int *_o_l=NULL;
00183 int _o_nc;
00184
00185 if ((!_h) || (!_r) || !CON_TABLE(_h))
00186 {
00187 LM_ERR("invalid parameters\n");
00188 return -1;
00189 }
00190 *_r = NULL;
00191
00192
00193 if (_o)
00194 {
00195 if (dbt_parse_orderbyclause(&_o_k, &_o_op, &_o_n, _o) < 0)
00196 return -1;
00197 }
00198
00199
00200 _tbc = dbt_db_get_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
00201 if(!_tbc)
00202 {
00203 LM_ERR("table %.*s does not exist!\n", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
00204 return -1;
00205 }
00206
00207
00208 if(!_tbc || _tbc->nrcols < _nc)
00209 {
00210 LM_ERR("table not loaded!\n");
00211 goto error;
00212 }
00213 if(_k)
00214 {
00215 lkey = dbt_get_refs(_tbc, _k, _n);
00216 if(!lkey)
00217 goto error;
00218 }
00219 if(_c)
00220 {
00221 lres = dbt_get_refs(_tbc, _c, _nc);
00222 if(!lres)
00223 goto error;
00224 }
00225 if(_o_k)
00226 {
00227 _o_l = dbt_get_refs(_tbc, _o_k, _o_n);
00228 if (!_o_l)
00229 goto error;
00230
00231 if (dbt_mangle_columnselection(&lres, &_nc, &_o_nc, _o_l, _o_n) < 0)
00232 goto error;
00233 }
00234
00235 LM_DBG("new res with %d cols\n", _nc);
00236 _dres = dbt_result_new(_tbc, lres, _nc);
00237
00238 if(!_dres)
00239 goto error;
00240
00241 _drp = _tbc->rows;
00242 while(_drp)
00243 {
00244 if(dbt_row_match(_tbc, _drp, lkey, _op, _v, _n))
00245 {
00246 if(dbt_result_extract_fields(_tbc, _drp, lres, _dres))
00247 {
00248 LM_ERR("failed to extract result fields!\n");
00249 goto clean;
00250 }
00251 }
00252 _drp = _drp->next;
00253 }
00254
00255 dbt_table_update_flags(_tbc, DBT_TBFL_ZERO, DBT_FL_IGN, 1);
00256
00257
00258 dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
00259
00260 if (_o_l)
00261 {
00262 if (_dres->nrrows > 1)
00263 {
00264 if (dbt_sort_result(_dres, _o_l, _o_op, _o_n, lres, _nc) < 0)
00265 goto error_nounlock;
00266 }
00267
00268
00269 if (_o_nc)
00270 dbt_project_result(_dres, _o_nc);
00271 }
00272
00273
00274
00275
00276 DBT_CON_RESULT(_h) = _dres;
00277
00278 if(lkey)
00279 pkg_free(lkey);
00280 if(lres)
00281 pkg_free(lres);
00282 if(_o_k)
00283 pkg_free(_o_k);
00284 if(_o_op)
00285 pkg_free(_o_op);
00286 if(_o_l)
00287 pkg_free(_o_l);
00288
00289 return dbt_get_result(_h, _r);
00290
00291 error:
00292
00293 dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
00294 error_nounlock:
00295 if(lkey)
00296 pkg_free(lkey);
00297 if(lres)
00298 pkg_free(lres);
00299 if(_o_k)
00300 pkg_free(_o_k);
00301 if(_o_op)
00302 pkg_free(_o_op);
00303 if(_o_l)
00304 pkg_free(_o_l);
00305 LM_ERR("failed to query the table!\n");
00306
00307 return -1;
00308
00309 clean:
00310
00311 dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
00312 if(lkey)
00313 pkg_free(lkey);
00314 if(lres)
00315 pkg_free(lres);
00316 if(_o_k)
00317 pkg_free(_o_k);
00318 if(_o_op)
00319 pkg_free(_o_op);
00320 if(_o_l)
00321 pkg_free(_o_l);
00322 if(_dres)
00323 dbt_result_free(_dres);
00324
00325 return -1;
00326 }
00327
00328
00329
00330
00331 int dbt_raw_query(db_con_t* _h, char* _s, db_res_t** _r)
00332 {
00333 *_r = NULL;
00334 return -1;
00335 }
00336
00337
00338
00339
00340 int dbt_insert(db_con_t* _h, db_key_t* _k, db_val_t* _v, int _n)
00341 {
00342 dbt_table_p _tbc = NULL;
00343 dbt_row_p _drp = NULL;
00344
00345 int *lkey=NULL, i, j;
00346
00347 if (!_h || !CON_TABLE(_h))
00348 {
00349 LM_ERR("invalid parameter\n");
00350 return -1;
00351 }
00352 if(!_k || !_v || _n<=0)
00353 {
00354 LM_ERR("no key-value to insert\n");
00355 return -1;
00356 }
00357
00358
00359 _tbc = dbt_db_get_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
00360 if(!_tbc)
00361 {
00362 LM_ERR("table %.*s does not exist!\n", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
00363 return -1;
00364 }
00365
00366 if(_tbc->nrcols<_n)
00367 {
00368 LM_ERR("more values than columns!!\n");
00369 goto error;
00370 }
00371
00372 if(_k)
00373 {
00374 lkey = dbt_get_refs(_tbc, _k, _n);
00375 if(!lkey)
00376 goto error;
00377 }
00378 _drp = dbt_row_new(_tbc->nrcols);
00379 if(!_drp)
00380 {
00381 LM_ERR("no shm memory for a new row!!\n");
00382 goto error;
00383 }
00384
00385 for(i=0; i<_n; i++)
00386 {
00387 j = (lkey)?lkey[i]:i;
00388 if(dbt_is_neq_type(_tbc->colv[j]->type, _v[i].type))
00389 {
00390 LM_ERR("incompatible types v[%d] - c[%d]!\n", i, j);
00391 goto clean;
00392 }
00393 if(_v[i].type == DB_STRING && !_v[i].nul)
00394 _v[i].val.str_val.len = strlen(_v[i].val.string_val);
00395 if(dbt_row_set_val(_drp, &(_v[i]), _tbc->colv[j]->type, j))
00396 {
00397 LM_ERR("cannot set v[%d] in c[%d]!\n", i, j);
00398 goto clean;
00399 }
00400
00401 }
00402
00403 if(dbt_table_add_row(_tbc, _drp))
00404 {
00405 LM_ERR("cannot insert the new row!!\n");
00406 goto clean;
00407 }
00408
00409
00410
00411
00412 dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
00413
00414 if(lkey)
00415 pkg_free(lkey);
00416
00417 return 0;
00418
00419 error:
00420
00421 dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
00422 if(lkey)
00423 pkg_free(lkey);
00424 LM_ERR("failed to insert row in table!\n");
00425 return -1;
00426
00427 clean:
00428 if(lkey)
00429 pkg_free(lkey);
00430
00431 if(_drp)
00432 dbt_row_free(_tbc, _drp);
00433
00434 dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
00435
00436 return -1;
00437 }
00438
00439
00440
00441
00442 int dbt_delete(db_con_t* _h, db_key_t* _k, db_op_t* _o, db_val_t* _v, int _n)
00443 {
00444 dbt_table_p _tbc = NULL;
00445 dbt_row_p _drp = NULL, _drp0 = NULL;
00446 int *lkey = NULL;
00447
00448 if (!_h || !CON_TABLE(_h))
00449 {
00450 LM_ERR("invalid parameters\n");
00451 return -1;
00452 }
00453
00454
00455 _tbc = dbt_db_get_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
00456 if(!_tbc)
00457 {
00458 LM_ERR("failed to load table <%.*s>!\n", CON_TABLE(_h)->len,
00459 CON_TABLE(_h)->s);
00460 return -1;
00461 }
00462
00463 if(!_k || !_v || _n<=0)
00464 {
00465 LM_DBG("deleting all records\n");
00466 dbt_table_free_rows(_tbc);
00467
00468 dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
00469 return 0;
00470 }
00471
00472 lkey = dbt_get_refs(_tbc, _k, _n);
00473 if(!lkey)
00474 goto error;
00475
00476 _drp = _tbc->rows;
00477 while(_drp)
00478 {
00479 _drp0 = _drp->next;
00480 if(dbt_row_match(_tbc, _drp, lkey, _o, _v, _n))
00481 {
00482
00483 if(_drp->prev)
00484 (_drp->prev)->next = _drp->next;
00485 else
00486 _tbc->rows = _drp->next;
00487 if(_drp->next)
00488 (_drp->next)->prev = _drp->prev;
00489 _tbc->nrrows--;
00490
00491 dbt_row_free(_tbc, _drp);
00492 }
00493 _drp = _drp0;
00494 }
00495
00496 dbt_table_update_flags(_tbc, DBT_TBFL_MODI, DBT_FL_SET, 1);
00497
00498
00499
00500
00501 dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
00502
00503 if(lkey)
00504 pkg_free(lkey);
00505
00506 return 0;
00507
00508 error:
00509
00510 dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
00511
00512 LM_ERR("failed to delete from table!\n");
00513 return -1;
00514 }
00515
00516
00517
00518
00519 int dbt_update(db_con_t* _h, db_key_t* _k, db_op_t* _o, db_val_t* _v,
00520 db_key_t* _uk, db_val_t* _uv, int _n, int _un)
00521 {
00522 dbt_table_p _tbc = NULL;
00523 dbt_row_p _drp = NULL;
00524 int i;
00525 int *lkey=NULL, *lres=NULL;
00526
00527 if (!_h || !CON_TABLE(_h) || !_uk || !_uv || _un <= 0)
00528 {
00529 LM_ERR("invalid parameters\n");
00530 return -1;
00531 }
00532
00533
00534 _tbc = dbt_db_get_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
00535 if(!_tbc)
00536 {
00537 LM_ERR("table %.*s does not exist!\n", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
00538 return -1;
00539 }
00540
00541 if(_k)
00542 {
00543 lkey = dbt_get_refs(_tbc, _k, _n);
00544 if(!lkey)
00545 goto error;
00546 }
00547 lres = dbt_get_refs(_tbc, _uk, _un);
00548 if(!lres)
00549 goto error;
00550 _drp = _tbc->rows;
00551 while(_drp)
00552 {
00553 if(dbt_row_match(_tbc, _drp, lkey, _o, _v, _n))
00554 {
00555 for(i=0; i<_un; i++)
00556 {
00557 if(dbt_is_neq_type(_tbc->colv[lres[i]]->type, _uv[i].type))
00558 {
00559 LM_ERR("incompatible types!\n");
00560 goto error;
00561 }
00562
00563 if(dbt_row_update_val(_drp, &(_uv[i]),
00564 _tbc->colv[lres[i]]->type, lres[i]))
00565 {
00566 LM_ERR("cannot set v[%d] in c[%d]!\n",
00567 i, lres[i]);
00568 goto error;
00569 }
00570 }
00571 }
00572 _drp = _drp->next;
00573 }
00574
00575 dbt_table_update_flags(_tbc, DBT_TBFL_MODI, DBT_FL_SET, 1);
00576
00577
00578
00579
00580 dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
00581
00582 if(lkey)
00583 pkg_free(lkey);
00584 if(lres)
00585 pkg_free(lres);
00586
00587 return 0;
00588
00589 error:
00590
00591 dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
00592
00593 if(lkey)
00594 pkg_free(lkey);
00595 if(lres)
00596 pkg_free(lres);
00597
00598 LM_ERR("failed to update the table!\n");
00599
00600 return -1;
00601 }
00602