sql_api.c

Go to the documentation of this file.
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 = &param->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                         /* Add column to current row, under the column's name */
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                 /* Add row to result xavp */
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         /* parse: name=>db_url*/
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