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