00001
00031 #include "../../mem/mem.h"
00032 #include "../../dprint.h"
00033 #include "../../hashes.h"
00034 #include "../../ut.h"
00035 #include "../../lib/srdb1/db_ut.h"
00036 #ifdef WITH_XAVP
00037 #include "../../xavp.h"
00038 #endif
00039
00040 #include "sql_api.h"
00041
00042 sql_con_t *_sql_con_root = NULL;
00043 sql_result_t *_sql_result_root = NULL;
00044
00045 static str _sql_empty_str = {"", 0};
00046
00047 sql_con_t* sql_get_connection(str *name)
00048 {
00049 sql_con_t *sc;
00050 unsigned int conid;
00051
00052 conid = core_case_hash(name, 0, 0);
00053
00054 sc = _sql_con_root;
00055 while(sc)
00056 {
00057 if(conid==sc->conid && sc->name.len==name->len
00058 && strncmp(sc->name.s, name->s, name->len)==0)
00059 return sc;
00060 sc = sc->next;
00061 }
00062 return NULL;
00063 }
00064
00065 int sql_init_con(str *name, str *url)
00066 {
00067 sql_con_t *sc;
00068 unsigned int conid;
00069
00070 conid = core_case_hash(name, 0, 0);
00071
00072 sc = _sql_con_root;
00073 while(sc)
00074 {
00075 if(conid==sc->conid && sc->name.len==name->len
00076 && strncmp(sc->name.s, name->s, name->len)==0)
00077 {
00078 LM_ERR("duplicate connection name\n");
00079 return -1;
00080 }
00081 sc = sc->next;
00082 }
00083 sc = (sql_con_t*)pkg_malloc(sizeof(sql_con_t));
00084 if(sc==NULL)
00085 {
00086 LM_ERR("no pkg memory\n");
00087 return -1;
00088 }
00089 memset(sc, 0, sizeof(sql_con_t));
00090 sc->conid = conid;
00091 sc->name = *name;
00092 sc->db_url = *url;
00093 sc->next = _sql_con_root;
00094 _sql_con_root = sc;
00095
00096 return 0;
00097 }
00098
00099 int pv_parse_con_name(pv_spec_p sp, str *in)
00100 {
00101 sql_con_t *con;
00102
00103 if(sp==NULL || in==NULL || in->len<=0)
00104 return -1;
00105
00106 con = sql_get_connection(in);
00107 if (con==NULL) {
00108 LM_ERR("invalid connection [%.*s]\n", in->len, in->s);
00109 return -1;
00110 }
00111
00112 sp->pvp.pvn.type = PV_NAME_INTSTR;
00113 sp->pvp.pvn.u.isname.type = AVP_VAL_STR;
00114 sp->pvp.pvn.u.isname.name.s = *in;
00115 return 0;
00116 }
00117
00118 int pv_get_sqlrows(struct sip_msg *msg, pv_param_t *param,
00119 pv_value_t *res)
00120 {
00121 sql_con_t *con;
00122 str* sc;
00123
00124 sc = ¶m->pvn.u.isname.name.s;
00125 con = sql_get_connection(sc);
00126 if(con==NULL)
00127 {
00128 LM_ERR("invalid connection [%.*s]\n", sc->len, sc->s);
00129 return -1;
00130 }
00131
00132 if (!DB_CAPABILITY(con->dbf, DB_CAP_AFFECTED_ROWS))
00133 {
00134 LM_ERR("con: %p database module does not have DB_CAP_AFFECTED_ROWS [%.*s]\n",
00135 con, sc->len, sc->s);
00136 return -1;
00137 }
00138
00139 return pv_get_sintval(msg, param, res, con->dbf.affected_rows(con->dbh));
00140 }
00141
00142 int sql_connect(void)
00143 {
00144 sql_con_t *sc;
00145 sc = _sql_con_root;
00146 while(sc)
00147 {
00148 if (db_bind_mod(&sc->db_url, &sc->dbf))
00149 {
00150 LM_DBG("database module not found for [%.*s]\n",
00151 sc->name.len, sc->name.s);
00152 return -1;
00153 }
00154 if (!DB_CAPABILITY(sc->dbf, DB_CAP_RAW_QUERY))
00155 {
00156 LM_ERR("database module does not have DB_CAP_ALL [%.*s]\n",
00157 sc->name.len, sc->name.s);
00158 return -1;
00159 }
00160 sc->dbh = sc->dbf.init(&sc->db_url);
00161 if (sc->dbh==NULL)
00162 {
00163 LM_ERR("failed to connect to the database [%.*s]\n",
00164 sc->name.len, sc->name.s);
00165 return -1;
00166 }
00167 sc = sc->next;
00168 }
00169 return 0;
00170 }
00171
00172 void sql_disconnect(void)
00173 {
00174 sql_con_t *sc;
00175 sc = _sql_con_root;
00176 while(sc)
00177 {
00178 if (sc->dbh!=NULL)
00179 sc->dbf.close(sc->dbh);
00180 sc->dbh= NULL;
00181 sc = sc->next;
00182 }
00183 }
00184
00185 sql_result_t* sql_get_result(str *name)
00186 {
00187 sql_result_t *sr;
00188 unsigned int resid;
00189
00190 resid = core_case_hash(name, 0, 0);
00191
00192 sr = _sql_result_root;
00193 while(sr)
00194 {
00195 if(sr->resid==resid && sr->name.len==name->len
00196 && strncmp(sr->name.s, name->s, name->len)==0)
00197 return sr;
00198 sr = sr->next;
00199 }
00200 sr = (sql_result_t*)pkg_malloc(sizeof(sql_result_t));
00201 if(sr==NULL)
00202 {
00203 LM_ERR("no pkg memory\n");
00204 return NULL;
00205 }
00206 memset(sr, 0, sizeof(sql_result_t));
00207 sr->name = *name;
00208 sr->resid = resid;
00209 sr->next = _sql_result_root;
00210 _sql_result_root = sr;
00211 return sr;
00212 }
00213
00214 void sql_reset_result(sql_result_t *res)
00215 {
00216 int i, j;
00217 if(res->cols)
00218 {
00219 for(i=0; i<res->ncols; i++)
00220 if(res->cols[i].name.s!=NULL)
00221 pkg_free(res->cols[i].name.s);
00222 pkg_free(res->cols);
00223 res->cols = NULL;
00224 }
00225 if(res->vals)
00226 {
00227 for(i=0; i<res->nrows; i++)
00228 {
00229 for(j=0; j<res->ncols; j++)
00230 {
00231 if(res->vals[i][j].flags&PV_VAL_STR
00232 && res->vals[i][j].value.s.len>0)
00233 pkg_free(res->vals[i][j].value.s.s);
00234 }
00235 pkg_free(res->vals[i]);
00236 }
00237 pkg_free(res->vals);
00238 res->vals = NULL;
00239 }
00240 res->nrows = 0;
00241 res->ncols = 0;
00242 }
00243
00244 int sql_do_query(sql_con_t *con, str *query, sql_result_t *res)
00245 {
00246 db1_res_t* db_res = NULL;
00247 int i, j;
00248 str sv;
00249
00250 if(query==NULL)
00251 {
00252 LM_ERR("bad parameters\n");
00253 return -1;
00254 }
00255 if(con->dbf.raw_query(con->dbh, query, &db_res)!=0)
00256 {
00257 LM_ERR("cannot do the query\n");
00258 return -1;
00259 }
00260
00261 if(db_res==NULL || RES_ROW_N(db_res)<=0 || RES_COL_N(db_res)<=0)
00262 {
00263 LM_DBG("no result after query\n");
00264 con->dbf.free_result(con->dbh, db_res);
00265 return 2;
00266 }
00267 if(!res)
00268 {
00269 LM_DBG("no sqlresult parameter, ignoring result from query\n");
00270 con->dbf.free_result(con->dbh, db_res);
00271 return 3;
00272 }
00273
00274 sql_reset_result(res);
00275 res->ncols = RES_COL_N(db_res);
00276 res->nrows = RES_ROW_N(db_res);
00277 LM_DBG("rows [%d] cols [%d]\n", res->nrows, res->ncols);
00278
00279 res->cols = (sql_col_t*)pkg_malloc(res->ncols*sizeof(sql_col_t));
00280 if(res->cols==NULL)
00281 {
00282 res->ncols = 0;
00283 res->nrows = 0;
00284 LM_ERR("no more memory\n");
00285 return -1;
00286 }
00287 memset(res->cols, 0, res->ncols*sizeof(sql_col_t));
00288 for(i=0; i<res->ncols; i++)
00289 {
00290 res->cols[i].name.len = (RES_NAMES(db_res)[i])->len;
00291 res->cols[i].name.s = (char*)pkg_malloc((res->cols[i].name.len+1)
00292 *sizeof(char));
00293 if(res->cols[i].name.s==NULL)
00294 {
00295 LM_ERR("no more memory\n");
00296 goto error;
00297 }
00298 memcpy(res->cols[i].name.s, RES_NAMES(db_res)[i]->s,
00299 res->cols[i].name.len);
00300 res->cols[i].name.s[res->cols[i].name.len]='\0';
00301 res->cols[i].colid = core_case_hash(&res->cols[i].name, 0, 0);
00302 }
00303
00304 res->vals = (sql_val_t**)pkg_malloc(res->nrows*sizeof(sql_val_t*));
00305 if(res->vals==NULL)
00306 {
00307 LM_ERR("no more memory\n");
00308 goto error;
00309 }
00310 memset(res->vals, 0, res->nrows*sizeof(sql_val_t*));
00311 for(i=0; i<res->nrows; i++)
00312 {
00313 res->vals[i] = (sql_val_t*)pkg_malloc(res->ncols*sizeof(sql_val_t));
00314 if(res->vals[i]==NULL)
00315 {
00316 LM_ERR("no more memory\n");
00317 goto error;
00318 }
00319 memset(res->vals[i], 0, res->ncols*sizeof(sql_val_t));
00320 for(j=0; j<res->ncols; j++)
00321 {
00322 if(RES_ROWS(db_res)[i].values[j].nul)
00323 {
00324 res->vals[i][j].flags = PV_VAL_NULL;
00325 continue;
00326 }
00327 sv.s = NULL;
00328 sv.len = 0;
00329 switch(RES_ROWS(db_res)[i].values[j].type)
00330 {
00331 case DB1_STRING:
00332 res->vals[i][j].flags = PV_VAL_STR;
00333 sv.s=
00334 (char*)RES_ROWS(db_res)[i].values[j].val.string_val;
00335 sv.len=strlen(sv.s);
00336 break;
00337 case DB1_STR:
00338 res->vals[i][j].flags = PV_VAL_STR;
00339 sv.len=
00340 RES_ROWS(db_res)[i].values[j].val.str_val.len;
00341 sv.s=
00342 (char*)RES_ROWS(db_res)[i].values[j].val.str_val.s;
00343 break;
00344 case DB1_BLOB:
00345 res->vals[i][j].flags = PV_VAL_STR;
00346 sv.len=
00347 RES_ROWS(db_res)[i].values[j].val.blob_val.len;
00348 sv.s=
00349 (char*)RES_ROWS(db_res)[i].values[j].val.blob_val.s;
00350 break;
00351 case DB1_INT:
00352 res->vals[i][j].flags = PV_VAL_INT;
00353 res->vals[i][j].value.n
00354 = (int)RES_ROWS(db_res)[i].values[j].val.int_val;
00355 break;
00356 case DB1_DATETIME:
00357 res->vals[i][j].flags = PV_VAL_INT;
00358 res->vals[i][j].value.n
00359 = (int)RES_ROWS(db_res)[i].values[j].val.time_val;
00360 break;
00361 case DB1_BITMAP:
00362 res->vals[i][j].flags = PV_VAL_INT;
00363 res->vals[i][j].value.n
00364 = (int)RES_ROWS(db_res)[i].values[j].val.bitmap_val;
00365 break;
00366 case DB1_BIGINT:
00367 res->vals[i][j].flags = PV_VAL_STR;
00368 res->vals[i][j].value.s.len = 21*sizeof(char);
00369 res->vals[i][j].value.s.s
00370 = (char*)pkg_malloc(res->vals[i][j].value.s.len);
00371 if(res->vals[i][j].value.s.s==NULL)
00372 {
00373 LM_ERR("no more memory\n");
00374 goto error;
00375 }
00376 db_longlong2str(RES_ROWS(db_res)[i].values[j].val.ll_val, res->vals[i][j].value.s.s, &res->vals[i][j].value.s.len);
00377 break;
00378 default:
00379 res->vals[i][j].flags = PV_VAL_NULL;
00380 }
00381 if(res->vals[i][j].flags == PV_VAL_STR && sv.s)
00382 {
00383 if(sv.len==0)
00384 {
00385 res->vals[i][j].value.s = _sql_empty_str;
00386 continue;
00387 }
00388 res->vals[i][j].value.s.s
00389 = (char*)pkg_malloc(sv.len*sizeof(char));
00390 if(res->vals[i][j].value.s.s==NULL)
00391 {
00392 LM_ERR("no more memory\n");
00393 goto error;
00394 }
00395 memcpy(res->vals[i][j].value.s.s, sv.s, sv.len);
00396 res->vals[i][j].value.s.len = sv.len;
00397 }
00398 }
00399 }
00400
00401 con->dbf.free_result(con->dbh, db_res);
00402 return 1;
00403
00404 error:
00405 con->dbf.free_result(con->dbh, db_res);
00406 sql_reset_result(res);
00407 return -1;
00408 }
00409
00410 #ifdef WITH_XAVP
00411 int sql_exec_xquery(struct sip_msg *msg, sql_con_t *con, str *query,
00412 str *xavp)
00413 {
00414 db1_res_t* db_res = NULL;
00415 sr_xavp_t *row = NULL;
00416 sr_xval_t val;
00417 int i, j;
00418 str sv;
00419
00420 if(msg==NULL || query==NULL || xavp==NULL)
00421 {
00422 LM_ERR("bad parameters\n");
00423 return -1;
00424 }
00425
00426 if(con->dbf.raw_query(con->dbh, query, &db_res)!=0)
00427 {
00428 LM_ERR("cannot do the query\n");
00429 return -1;
00430 }
00431
00432 if(db_res==NULL || RES_ROW_N(db_res)<=0 || RES_COL_N(db_res)<=0)
00433 {
00434 LM_DBG("no result after query\n");
00435 con->dbf.free_result(con->dbh, db_res);
00436 return 2;
00437 }
00438
00439 for(i=RES_ROW_N(db_res)-1; i>=0; i--)
00440 {
00441 row = NULL;
00442 for(j=RES_COL_N(db_res)-1; j>=0; j--)
00443 {
00444 if(RES_ROWS(db_res)[i].values[j].nul)
00445 {
00446 val.type = SR_XTYPE_NULL;
00447 } else
00448 {
00449 switch(RES_ROWS(db_res)[i].values[j].type)
00450 {
00451 case DB1_STRING:
00452 val.type = SR_XTYPE_STR;
00453 sv.s=
00454 (char*)RES_ROWS(db_res)[i].values[j].val.string_val;
00455 sv.len=strlen(sv.s);
00456 break;
00457 case DB1_STR:
00458 val.type = SR_XTYPE_STR;
00459 sv.len=
00460 RES_ROWS(db_res)[i].values[j].val.str_val.len;
00461 sv.s=
00462 (char*)RES_ROWS(db_res)[i].values[j].val.str_val.s;
00463 break;
00464 case DB1_BLOB:
00465 val.type = SR_XTYPE_STR;
00466 sv.len=
00467 RES_ROWS(db_res)[i].values[j].val.blob_val.len;
00468 sv.s=
00469 (char*)RES_ROWS(db_res)[i].values[j].val.blob_val.s;
00470 break;
00471 case DB1_INT:
00472 val.type = SR_XTYPE_INT;
00473 val.v.i
00474 = (int)RES_ROWS(db_res)[i].values[j].val.int_val;
00475 break;
00476 case DB1_DATETIME:
00477 val.type = SR_XTYPE_INT;
00478 val.v.i
00479 = (int)RES_ROWS(db_res)[i].values[j].val.time_val;
00480 break;
00481 case DB1_BITMAP:
00482 val.type = SR_XTYPE_INT;
00483 val.v.i
00484 = (int)RES_ROWS(db_res)[i].values[j].val.bitmap_val;
00485 break;
00486 case DB1_BIGINT:
00487 val.type = SR_XTYPE_LLONG;
00488 val.v.ll
00489 = RES_ROWS(db_res)[i].values[j].val.ll_val;
00490 break;
00491 default:
00492 val.type = SR_XTYPE_NULL;
00493 }
00494 if(val.type == SR_XTYPE_STR)
00495 {
00496 if(sv.len==0)
00497 {
00498 val.v.s = _sql_empty_str;
00499 } else {
00500 val.v.s.s = (char*)pkg_malloc(sv.len*sizeof(char));
00501 if(val.v.s.s == NULL)
00502 {
00503 LM_ERR("no more memory\n");
00504 goto error;
00505 }
00506 memcpy(val.v.s.s, sv.s, sv.len);
00507 val.v.s.len = sv.len;
00508 }
00509 }
00510 }
00511
00512 LM_DBG("Adding column: %.*s\n", RES_NAMES(db_res)[j]->len, RES_NAMES(db_res)[j]->s);
00513 xavp_add_value(RES_NAMES(db_res)[j], &val, &row);
00514 if (val.type == SR_XTYPE_STR && val.v.s.len > 0)
00515 pkg_free(val.v.s.s);
00516 }
00517
00518 val.type = SR_XTYPE_XAVP;
00519 val.v.xavp = row;
00520 LM_DBG("Adding row\n");
00521 xavp_add_value(xavp, &val, NULL);
00522 }
00523
00524 con->dbf.free_result(con->dbh, db_res);
00525 return 1;
00526
00527 error:
00528 con->dbf.free_result(con->dbh, db_res);
00529 return -1;
00530
00531 }
00532
00533 int sql_do_xquery(struct sip_msg *msg, sql_con_t *con, pv_elem_t *query,
00534 pv_elem_t *res)
00535 {
00536 str sv, xavp;
00537 if(msg==NULL || query==NULL || res==NULL)
00538 {
00539 LM_ERR("bad parameters\n");
00540 return -1;
00541 }
00542 if(pv_printf_s(msg, query, &sv)!=0)
00543 {
00544 LM_ERR("cannot print the sql query\n");
00545 return -1;
00546 }
00547
00548 if(pv_printf_s(msg, res, &xavp)!=0)
00549 {
00550 LM_ERR("cannot print the result parameter\n");
00551 return -1;
00552 }
00553 return sql_exec_xquery(msg, con, &sv, &xavp);
00554 }
00555
00556 #endif
00557
00558
00559 int sql_do_pvquery(struct sip_msg *msg, sql_con_t *con, pv_elem_t *query,
00560 pvname_list_t *res)
00561 {
00562 db1_res_t* db_res = NULL;
00563 pvname_list_t* pv;
00564 str sv;
00565 int i, j;
00566
00567 if(msg==NULL || query==NULL || res==NULL)
00568 {
00569 LM_ERR("bad parameters\n");
00570 return -1;
00571 }
00572 if(pv_printf_s(msg, query, &sv)!=0)
00573 {
00574 LM_ERR("cannot print the sql query\n");
00575 return -1;
00576 }
00577
00578 if(con->dbf.raw_query(con->dbh, &sv, &db_res)!=0)
00579 {
00580 LM_ERR("cannot do the query\n");
00581 return -1;
00582 }
00583
00584 if(db_res==NULL || RES_ROW_N(db_res)<=0 || RES_COL_N(db_res)<=0)
00585 {
00586 LM_DBG("no result after query\n");
00587 con->dbf.free_result(con->dbh, db_res);
00588 return 2;
00589 }
00590
00591 for(i=RES_ROW_N(db_res)-1; i>=0; i--)
00592 {
00593 pv = res;
00594 for(j=0; j<RES_COL_N(db_res); j++)
00595 {
00596 if (db_val2pv_spec(msg, &RES_ROWS(db_res)[0].values[j], &pv->sname) != 0) {
00597 LM_ERR("Failed to convert value for column %.*s\n",
00598 RES_NAMES(db_res)[j]->len, RES_NAMES(db_res)[j]->s);
00599 goto error;
00600 }
00601 pv = pv->next;
00602 }
00603 }
00604
00605 con->dbf.free_result(con->dbh, db_res);
00606 return 1;
00607
00608 error:
00609 con->dbf.free_result(con->dbh, db_res);
00610 return -1;
00611 }
00612
00613
00614 int sql_parse_param(char *val)
00615 {
00616 str name;
00617 str tok;
00618 str in;
00619 char *p;
00620
00621
00622 in.s = val;
00623 in.len = strlen(in.s);
00624 p = in.s;
00625
00626 while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
00627 p++;
00628 if(p>in.s+in.len || *p=='\0')
00629 goto error;
00630 name.s = p;
00631 while(p < in.s + in.len)
00632 {
00633 if(*p=='=' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
00634 break;
00635 p++;
00636 }
00637 if(p>in.s+in.len || *p=='\0')
00638 goto error;
00639 name.len = p - name.s;
00640 if(*p!='=')
00641 {
00642 while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
00643 p++;
00644 if(p>in.s+in.len || *p=='\0' || *p!='=')
00645 goto error;
00646 }
00647 p++;
00648 if(*p!='>')
00649 goto error;
00650 p++;
00651 while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
00652 p++;
00653 tok.s = p;
00654 tok.len = in.len + (int)(in.s - p);
00655
00656 LM_DBG("cname: [%.*s] url: [%.*s]\n", name.len, name.s, tok.len, tok.s);
00657
00658 return sql_init_con(&name, &tok);
00659 error:
00660 LM_ERR("invalid sqlops parameter [%.*s] at [%d]\n", in.len, in.s,
00661 (int)(p-in.s));
00662 return -1;
00663 }
00664
00665 void sql_destroy(void)
00666 {
00667 sql_result_t *r;
00668 sql_result_t *r0;
00669
00670 sql_disconnect();
00671
00672 r=_sql_result_root;
00673 while(r)
00674 {
00675 r0 = r->next;
00676 sql_reset_result(r);
00677 pkg_free(r);
00678 r = r0;
00679 }
00680 }
00681
00685 int sqlops_do_query(str *scon, str *squery, str *sres)
00686 {
00687 sql_con_t *con = NULL;
00688 sql_result_t *res = NULL;
00689
00690 con = sql_get_connection(scon);
00691 if(con==NULL)
00692 {
00693 LM_ERR("invalid connection [%.*s]\n", scon->len, scon->s);
00694 goto error;
00695 }
00696 res = sql_get_result(sres);
00697 if(res==NULL)
00698 {
00699 LM_ERR("invalid result [%.*s]\n", sres->len, sres->s);
00700 goto error;
00701 }
00702 if(sql_do_query(con, squery, res)<0)
00703 goto error;
00704
00705 return 0;
00706 error:
00707 return -1;
00708 }
00709
00713 int sqlops_get_value(str *sres, int i, int j, sql_val_t **val)
00714 {
00715 sql_result_t *res = NULL;
00716
00717 res = sql_get_result(sres);
00718 if(res==NULL)
00719 {
00720 LM_ERR("invalid result [%.*s]\n", sres->len, sres->s);
00721 goto error;
00722 }
00723 if(i>=res->nrows)
00724 {
00725 LM_ERR("row index out of bounds [%d/%d]\n", i, res->nrows);
00726 goto error;
00727 }
00728 if(j>=res->ncols)
00729 {
00730 LM_ERR("column index out of bounds [%d/%d]\n", j, res->ncols);
00731 goto error;
00732 }
00733 *val = &res->vals[i][j];
00734
00735 return 0;
00736 error:
00737 return -1;
00738 }
00739
00743 int sqlops_is_null(str *sres, int i, int j)
00744 {
00745 sql_result_t *res = NULL;
00746
00747 res = sql_get_result(sres);
00748 if(res==NULL)
00749 {
00750 LM_ERR("invalid result [%.*s]\n", sres->len, sres->s);
00751 goto error;
00752 }
00753 if(i>=res->nrows)
00754 {
00755 LM_ERR("row index out of bounds [%d/%d]\n", i, res->nrows);
00756 goto error;
00757 }
00758 if(i>=res->ncols)
00759 {
00760 LM_ERR("column index out of bounds [%d/%d]\n", j, res->ncols);
00761 goto error;
00762 }
00763 if(res->vals[i][j].flags&PV_VAL_NULL)
00764 return 1;
00765 return 0;
00766 error:
00767 return -1;
00768 }
00769
00773 int sqlops_get_column(str *sres, int i, str *col)
00774 {
00775 sql_result_t *res = NULL;
00776
00777 res = sql_get_result(sres);
00778 if(res==NULL)
00779 {
00780 LM_ERR("invalid result [%.*s]\n", sres->len, sres->s);
00781 goto error;
00782 }
00783 if(i>=res->ncols)
00784 {
00785 LM_ERR("column index out of bounds [%d/%d]\n", i, res->ncols);
00786 goto error;
00787 }
00788 *col = res->cols[i].name;
00789 return 0;
00790 error:
00791 return -1;
00792 }
00793
00797 int sqlops_num_columns(str *sres)
00798 {
00799 sql_result_t *res = NULL;
00800
00801 res = sql_get_result(sres);
00802 if(res==NULL)
00803 {
00804 LM_ERR("invalid result [%.*s]\n", sres->len, sres->s);
00805 goto error;
00806 }
00807 return res->ncols;
00808 error:
00809 return -1;
00810 }
00811
00815 int sqlops_num_rows(str *sres)
00816 {
00817 sql_result_t *res = NULL;
00818
00819 res = sql_get_result(sres);
00820 if(res==NULL)
00821 {
00822 LM_ERR("invalid result [%.*s]\n", sres->len, sres->s);
00823 goto error;
00824 }
00825 return res->nrows;
00826 error:
00827 return -1;
00828 }
00829
00833 void sqlops_reset_result(str *sres)
00834 {
00835 sql_result_t *res = NULL;
00836
00837 res = sql_get_result(sres);
00838 if(res==NULL)
00839 {
00840 LM_ERR("invalid result [%.*s]\n", sres->len, sres->s);
00841 return;
00842 }
00843 sql_reset_result(res);
00844
00845 return;
00846 }
00847
00851 int sqlops_do_xquery(sip_msg_t *msg, str *scon, str *squery, str *xavp)
00852 {
00853 sql_con_t *con = NULL;
00854
00855 con = sql_get_connection(scon);
00856 if(con==NULL)
00857 {
00858 LM_ERR("invalid connection [%.*s]\n", scon->len, scon->s);
00859 goto error;
00860 }
00861 if(sql_exec_xquery(msg, con, squery, xavp)<0)
00862 goto error;
00863
00864 return 0;
00865 error:
00866 return -1;
00867 }
00868