sql_var.c

Go to the documentation of this file.
00001 
00031 #include "../../mem/mem.h"
00032 #include "../../dprint.h"
00033 #include "../../mod_fix.h"
00034 
00035 #include "sql_api.h"
00036 #include "sql_var.h"
00037 
00038 typedef struct _sql_pv {
00039         str resname;
00040         sql_result_t *res;
00041         int type;
00042         gparam_t row;
00043         gparam_t col;
00044 } sql_pv_t;
00045 
00046 int pv_get_dbr(struct sip_msg *msg,  pv_param_t *param,
00047                 pv_value_t *res)
00048 {
00049         sql_pv_t *spv;
00050         int row;
00051         int col;
00052 
00053         spv = (sql_pv_t*)param->pvn.u.dname;
00054 
00055         if(spv->res==NULL)
00056         {
00057                 spv->res = sql_get_result(&spv->resname);
00058                 if(spv->res==NULL)
00059                         return pv_get_null(msg, param, res);
00060         }
00061 
00062         switch(spv->type)
00063         {
00064                 case 1:
00065                         return pv_get_sintval(msg, param, res, spv->res->nrows);
00066                 break;
00067                 case 2:
00068                         return pv_get_sintval(msg, param, res, spv->res->ncols);
00069                 break;
00070                 case 3:
00071                         if(fixup_get_ivalue(msg, &spv->row, &row)!=0)
00072                                 return pv_get_null(msg, param, res);
00073                         if(fixup_get_ivalue(msg, &spv->col, &col)!=0)
00074                                 return pv_get_null(msg, param, res);
00075                         if(row>=spv->res->nrows)
00076                                 return pv_get_null(msg, param, res);
00077                         if(col>=spv->res->ncols)
00078                                 return pv_get_null(msg, param, res);
00079                         if(spv->res->vals[row][col].flags&PV_VAL_NULL)
00080                                 return pv_get_null(msg, param, res);
00081                         if(spv->res->vals[row][col].flags&PV_VAL_INT)
00082                                 return pv_get_sintval(msg, param, res, 
00083                                                 spv->res->vals[row][col].value.n);
00084                         return pv_get_strval(msg, param, res, 
00085                                                 &spv->res->vals[row][col].value.s);
00086                 break;
00087                 case 4:
00088                         if(fixup_get_ivalue(msg, &spv->col, &col)!=0)
00089                                 return pv_get_null(msg, param, res);
00090                         if(col>=spv->res->ncols)
00091                                 return pv_get_null(msg, param, res);
00092                         return pv_get_strval(msg, param, res, 
00093                                                 &spv->res->cols[col].name);
00094                 break;
00095         }
00096         return 0;
00097 }
00098 
00099 
00100 int sql_parse_index(str *in, gparam_t *gp)
00101 {
00102         if(in->s[0]==PV_MARKER)
00103         {
00104                 gp->type = GPARAM_TYPE_PVS;
00105                 gp->v.pvs = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t));
00106                 if (gp->v.pvs == NULL)
00107                 {
00108                         LM_ERR("no pkg memory left for pv_spec_t\n");
00109                     pkg_free(gp);
00110                     return -1;
00111                 }
00112 
00113                 if(pv_parse_spec(in, gp->v.pvs)==NULL)
00114                 {
00115                         LM_ERR("invalid PV identifier\n");
00116                     pkg_free(gp->v.pvs);
00117                     pkg_free(gp);
00118                         return -1;
00119                 }
00120         } else {
00121                 gp->type = GPARAM_TYPE_INT;
00122                 if(str2sint(in, &gp->v.i) != 0)
00123                 {
00124                         LM_ERR("bad number <%.*s>\n", in->len, in->s);
00125                         return -1;
00126                 }
00127         }
00128         return 0;
00129 }
00130 
00131 int pv_parse_dbr_name(pv_spec_p sp, str *in)
00132 {
00133         sql_pv_t *spv=NULL;
00134         char *p;
00135         str pvs;
00136         str tok;
00137 
00138         spv = (sql_pv_t*)pkg_malloc(sizeof(sql_pv_t));
00139         if(spv==NULL)
00140                 return -1;
00141 
00142         memset(spv, 0, sizeof(sql_pv_t));
00143 
00144         p = in->s;
00145 
00146         while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
00147                 p++;
00148         if(p>in->s+in->len || *p=='\0')
00149                 goto error;
00150         spv->resname.s = p;
00151         while(p < in->s + in->len)
00152         {
00153                 if(*p=='=' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
00154                         break;
00155                 p++;
00156         }
00157         if(p>in->s+in->len || *p=='\0')
00158                 goto error;
00159         spv->resname.len = p - spv->resname.s;
00160         spv->res = sql_get_result(&spv->resname);
00161 
00162         if(*p!='=')
00163         {
00164                 while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
00165                         p++;
00166                 if(p>in->s+in->len || *p=='\0' || *p!='=')
00167                         goto error;
00168         }
00169         p++;
00170         if(*p!='>')
00171                 goto error;
00172         p++;
00173 
00174         pvs.len = in->len - (int)(p - in->s);
00175         pvs.s = p;
00176         p = pvs.s+pvs.len-1;
00177         while(p>pvs.s && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
00178                         p--;
00179         if(p==pvs.s)
00180         {
00181                 LM_ERR("invalid key in [%.*s]\n", in->len, in->s);
00182                 goto error;
00183         }
00184         pvs.len = p - pvs.s + 1;
00185 
00186         LM_DBG("res [%.*s] - key [%.*s]\n", spv->resname.len, spv->resname.s,
00187                         pvs.len, pvs.s);
00188         if(pvs.len==4 && strncmp(pvs.s, "rows", 4)==0)
00189         {
00190                 spv->type = 1;
00191         } else if(pvs.len==4 && strncmp(pvs.s, "cols", 4)==0) {
00192                 spv->type = 2;
00193         } else if(pvs.s[0]=='[') {
00194                 spv->type = 3;
00195                 p = pvs.s+1;
00196                 while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
00197                         p++;
00198                 if(p>in->s+in->len || *p=='\0')
00199                         goto error_index;
00200                 tok.s = p;
00201                 while(p < in->s + in->len)
00202                 {
00203                         if(*p==',' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
00204                                 break;
00205                         p++;
00206                 }
00207                 if(p>in->s+in->len || *p=='\0')
00208                         goto error_index;
00209                 tok.len = p - tok.s;
00210                 if(sql_parse_index(&tok, &spv->row)!=0)
00211                         goto error_index;
00212                 while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
00213                         p++;
00214                 if(p>in->s+in->len || *p=='\0' || *p!=',')
00215                         goto error_index;
00216                 p++;
00217                 while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
00218                         p++;
00219                 if(p>in->s+in->len || *p=='\0')
00220                         goto error_index;
00221                 tok.s = p;
00222                 while(p < in->s + in->len)
00223                 {
00224                         if(*p==']' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
00225                                 break;
00226                         p++;
00227                 }
00228                 if(p>in->s+in->len || *p=='\0')
00229                         goto error_index;
00230                 tok.len = p - tok.s;
00231                 if(sql_parse_index(&tok, &spv->col)!=0)
00232                         goto error_index;
00233                 while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
00234                         p++;
00235                 if(p>in->s+in->len || *p=='\0' || *p!=']')
00236                         goto error_index;
00237         } else if(pvs.len>9 && strncmp(pvs.s, "colname", 7)==0) {
00238                 spv->type = 4;
00239                 p = pvs.s+7;
00240                 while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
00241                         p++;
00242                 if(p>in->s+in->len || *p=='\0' || *p!='[')
00243                         goto error_index;
00244                 p++;
00245                 tok.s = p;
00246                 while(p < in->s + in->len)
00247                 {
00248                         if(*p==']' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
00249                                 break;
00250                         p++;
00251                 }
00252                 if(p>in->s+in->len || *p=='\0')
00253                         goto error_index;
00254                 tok.len = p - tok.s;
00255                 if(sql_parse_index(&tok, &spv->col)!=0)
00256                         goto error_index;
00257                 while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
00258                         p++;
00259                 if(p>in->s+in->len || *p=='\0' || *p!=']')
00260                         goto error_index;
00261         } else {
00262                 LM_ERR("unknow key [%.*s]\n", pvs.len, pvs.s);
00263                 return -1;
00264         }
00265         sp->pvp.pvn.u.dname = (void*)spv;
00266         sp->pvp.pvn.type = PV_NAME_PVAR;
00267 
00268         return 0;
00269 
00270 error:
00271         LM_ERR("invalid pv name [%.*s]\n", in->len, in->s);
00272         if(spv!=NULL)
00273                 pkg_free(spv);
00274         return -1;
00275 
00276 error_index:
00277         LM_ERR("invalid index in [%.*s]\n", pvs.len, pvs.s);
00278         if(spv!=NULL)
00279                 pkg_free(spv);
00280         return -1;
00281 }
00282