Hi Francesco,
.:: Francesco la Torre ::. wrote:
> Hi all,
> is there any reference to new *db* API ?
not yet, but there are many modules that use the new api so you can
use them as examples.
> There is a snippet of the code :
>
> 471 static int db_example(char* db_url){
> 472 str result;
> 473 db_cmd_t *query = NULL;
> 474 db_res_t *result_t;
> 475 db_rec_t *row;
> 476
> 477 str id_column;
> 478 str value_column;
> 479 str table;
> 480 str id;
> 481
> 482 table.s = "value_att";
> 483 table.len = 10;
> 484 id_column.s = "id_value";
> 485 id_column.len = 9;
> 486 value_column.s = "value";
> 487 value_column.len = 5;
> 488 int len;
> 489
> 490 module_db_handle = db_ctx("module_db");
> 491 if (!module_db_handle) goto err;
> 492 if (db_add_db(module_db_handle, db_url) < 0) goto err;
> 493 if (db_connect(module_db_handle) < 0)
> 494 goto err;
> 495 else
> 496 LOG(L_INFO,"DB connected.\n");
Correct, the code above should be executed from mod_init or
child_init, this initializes the database context (db_ctx) which is
some sort of handle to the database layer. db_add_db adds a new
connection to the context to the server specified in the parameter.
db_connect establishes a connection to the server.
> 498 /* Setup query */
> 499
> 500 db_fld_t match_with[] = {
> 501 { .name = id_column.s, .type = DB_INT },
> 502 { .name = NULL }
> 503 };
> 504 db_fld_t *result_cols = NULL;
> 505
> 506
> 507 len = sizeof(*result_cols);
> 508 result_cols = pkg_malloc(len);
> 509 if (!result_cols) {
> 510 ERR("can't allocate pkg mem\n");
> 511 return -1;
> 512 }
> 513 memset(result_cols, 0, len);
> 514
> 515 result_cols->name = value_column.s;
> 516 result_cols->type = DB_STR;
There is no need to allocate the result array on the heap. You can
initialize it pretty much the same way as match_with:
db_fld_t result_cols[] = {
{.name = value_column.s, .type = DB_STR},
{.name = NULL}
};
> 517
> 518 query = db_cmd(DB_GET, module_db_handle, table.s, result_cols,
> match_with, NULL);
Correct. The command above compiles the database query and
uploads the command to the database server. The code above
should be executed in child_init function, again see existing
modules, for example gflags if you need an example.
> 519
> 520 id.s="2";
> 521 id.len=2;
> 522 query->match[0].v.lstr = id;
id.len should be 1, not 2. This is the length of the string in
id.s.
If you know that your string will always be zero-terminated then you
can declare the column as DB_CSTR above (instead of DB_STR), and then
you can just do:
query->match[0].v.cstr = "2";
> if (db_exec(&result_t, query) < 0 ) {
> 525 ERR("Error while querying database\n");
> 526 return -1;
> 527 }
Yes, correct.
> 528
> 529 if (result_t) row = db_first(result_t);
> 530 else row=NULL;
Yes, correct.
> 531
> 532 while (row) {
> 533 if (IS_NULL((row)->fld[0]) || IS_NULL((row)->fld[1])) {
Here the test for NULL values changed, it should be written this
way:
if ((row->fld[0].flags & DB_NULL) || (row->fld[1].flags & DB_NULL))
> 534
> 535 } else {
> 536 if ((row)->fld[1].v.int4 & DB_DISABLED) {
> 537 } else {
> 538 if ((row)->fld[1].v.int4 & DB_LOAD_SER) {
> 539 break;
> 540 }
> 541 }
> 542 }
> 543 row = db_next(result_t);
> 544 }
> 545
> 546 if (!row) {
> 547 DBG("Value not found\n");
> 548 return 1;
> 549 }
> 550
> 551 result.s = (row)->fld[0].v.cstr;
> 552 result.len = strlen(result.s);
Don't forget to free the result obtained from the database when you
don't need it anymore:
if (result_t) db_res_free(result_t);
Jan.
_______________________________________________
Serdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/serdev