mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
281 lines
6.5 KiB
281 lines
6.5 KiB
/**
|
|
* Copyright (C) 2008 Elena-Ramona Modroiu (asipto.com)
|
|
*
|
|
* This file is part of kamailio, a free SIP server.
|
|
*
|
|
* Kamailio is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version
|
|
*
|
|
* Kamailio is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
/*! \file
|
|
* \ingroup sqlops
|
|
* \brief Kamailio SQL-operations :: Variables
|
|
*
|
|
* - Module: \ref sqlops
|
|
*/
|
|
|
|
|
|
#include "../../mem/mem.h"
|
|
#include "../../dprint.h"
|
|
#include "../../mod_fix.h"
|
|
|
|
#include "sql_api.h"
|
|
#include "sql_var.h"
|
|
|
|
typedef struct _sql_pv {
|
|
str resname;
|
|
sql_result_t *res;
|
|
int type;
|
|
gparam_t row;
|
|
gparam_t col;
|
|
} sql_pv_t;
|
|
|
|
int pv_get_dbr(struct sip_msg *msg, pv_param_t *param,
|
|
pv_value_t *res)
|
|
{
|
|
sql_pv_t *spv;
|
|
int row;
|
|
int col;
|
|
|
|
spv = (sql_pv_t*)param->pvn.u.dname;
|
|
|
|
if(spv->res==NULL)
|
|
{
|
|
spv->res = sql_get_result(&spv->resname);
|
|
if(spv->res==NULL)
|
|
return pv_get_null(msg, param, res);
|
|
}
|
|
|
|
switch(spv->type)
|
|
{
|
|
case 1:
|
|
return pv_get_sintval(msg, param, res, spv->res->nrows);
|
|
break;
|
|
case 2:
|
|
return pv_get_sintval(msg, param, res, spv->res->ncols);
|
|
break;
|
|
case 3:
|
|
if(fixup_get_ivalue(msg, &spv->row, &row)!=0)
|
|
return pv_get_null(msg, param, res);
|
|
if(fixup_get_ivalue(msg, &spv->col, &col)!=0)
|
|
return pv_get_null(msg, param, res);
|
|
if(row>=spv->res->nrows)
|
|
return pv_get_null(msg, param, res);
|
|
if(col>=spv->res->ncols)
|
|
return pv_get_null(msg, param, res);
|
|
if(spv->res->vals[row][col].flags&PV_VAL_NULL)
|
|
return pv_get_null(msg, param, res);
|
|
if(spv->res->vals[row][col].flags&PV_VAL_INT)
|
|
return pv_get_sintval(msg, param, res,
|
|
spv->res->vals[row][col].value.n);
|
|
return pv_get_strval(msg, param, res,
|
|
&spv->res->vals[row][col].value.s);
|
|
break;
|
|
case 4:
|
|
if(fixup_get_ivalue(msg, &spv->col, &col)!=0)
|
|
return pv_get_null(msg, param, res);
|
|
if(col>=spv->res->ncols)
|
|
return pv_get_null(msg, param, res);
|
|
return pv_get_strval(msg, param, res,
|
|
&spv->res->cols[col].name);
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int sql_parse_index(str *in, gparam_t *gp)
|
|
{
|
|
if(in->s[0]==PV_MARKER)
|
|
{
|
|
gp->type = GPARAM_TYPE_PVS;
|
|
gp->v.pvs = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t));
|
|
if (gp->v.pvs == NULL)
|
|
{
|
|
LM_ERR("no pkg memory left for pv_spec_t\n");
|
|
return -1;
|
|
}
|
|
|
|
if(pv_parse_spec(in, gp->v.pvs)==NULL)
|
|
{
|
|
LM_ERR("invalid PV identifier\n");
|
|
pkg_free(gp->v.pvs);
|
|
return -1;
|
|
}
|
|
} else {
|
|
gp->type = GPARAM_TYPE_INT;
|
|
if(str2sint(in, &gp->v.i) != 0)
|
|
{
|
|
LM_ERR("bad number <%.*s>\n", in->len, in->s);
|
|
return -1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int pv_parse_dbr_name(pv_spec_p sp, str *in)
|
|
{
|
|
sql_pv_t *spv=NULL;
|
|
char *p;
|
|
str pvs;
|
|
str tok;
|
|
|
|
spv = (sql_pv_t*)pkg_malloc(sizeof(sql_pv_t));
|
|
if(spv==NULL)
|
|
return -1;
|
|
|
|
memset(spv, 0, sizeof(sql_pv_t));
|
|
|
|
p = in->s;
|
|
|
|
while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
|
|
p++;
|
|
if(p>in->s+in->len || *p=='\0')
|
|
goto error;
|
|
spv->resname.s = p;
|
|
while(p < in->s + in->len)
|
|
{
|
|
if(*p=='=' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
|
|
break;
|
|
p++;
|
|
}
|
|
if(p>in->s+in->len || *p=='\0')
|
|
goto error;
|
|
spv->resname.len = p - spv->resname.s;
|
|
spv->res = sql_get_result(&spv->resname);
|
|
|
|
if(*p!='=')
|
|
{
|
|
while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
|
|
p++;
|
|
if(p>in->s+in->len || *p=='\0' || *p!='=')
|
|
goto error;
|
|
}
|
|
p++;
|
|
if(*p!='>')
|
|
goto error;
|
|
p++;
|
|
|
|
pvs.len = in->len - (int)(p - in->s);
|
|
pvs.s = p;
|
|
p = pvs.s+pvs.len-1;
|
|
while(p>pvs.s && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
|
|
p--;
|
|
if(p==pvs.s)
|
|
{
|
|
LM_ERR("invalid key in [%.*s]\n", in->len, in->s);
|
|
goto error;
|
|
}
|
|
pvs.len = p - pvs.s + 1;
|
|
|
|
LM_DBG("res [%.*s] - key [%.*s]\n", spv->resname.len, spv->resname.s,
|
|
pvs.len, pvs.s);
|
|
if(pvs.len==4 && strncmp(pvs.s, "rows", 4)==0)
|
|
{
|
|
spv->type = 1;
|
|
} else if(pvs.len==4 && strncmp(pvs.s, "cols", 4)==0) {
|
|
spv->type = 2;
|
|
} else if(pvs.s[0]=='[') {
|
|
spv->type = 3;
|
|
p = pvs.s+1;
|
|
while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
|
|
p++;
|
|
if(p>in->s+in->len || *p=='\0')
|
|
goto error_index;
|
|
tok.s = p;
|
|
while(p < in->s + in->len)
|
|
{
|
|
if(*p==',' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
|
|
break;
|
|
p++;
|
|
}
|
|
if(p>in->s+in->len || *p=='\0')
|
|
goto error_index;
|
|
tok.len = p - tok.s;
|
|
if(sql_parse_index(&tok, &spv->row)!=0)
|
|
goto error_index;
|
|
while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
|
|
p++;
|
|
if(p>in->s+in->len || *p=='\0' || *p!=',')
|
|
goto error_index;
|
|
p++;
|
|
while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
|
|
p++;
|
|
if(p>in->s+in->len || *p=='\0')
|
|
goto error_index;
|
|
tok.s = p;
|
|
while(p < in->s + in->len)
|
|
{
|
|
if(*p==']' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
|
|
break;
|
|
p++;
|
|
}
|
|
if(p>in->s+in->len || *p=='\0')
|
|
goto error_index;
|
|
tok.len = p - tok.s;
|
|
if(sql_parse_index(&tok, &spv->col)!=0)
|
|
goto error_index;
|
|
while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
|
|
p++;
|
|
if(p>in->s+in->len || *p=='\0' || *p!=']')
|
|
goto error_index;
|
|
} else if(pvs.len>9 && strncmp(pvs.s, "colname", 7)==0) {
|
|
spv->type = 4;
|
|
p = pvs.s+7;
|
|
while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
|
|
p++;
|
|
if(p>in->s+in->len || *p=='\0' || *p!='[')
|
|
goto error_index;
|
|
p++;
|
|
tok.s = p;
|
|
while(p < in->s + in->len)
|
|
{
|
|
if(*p==']' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
|
|
break;
|
|
p++;
|
|
}
|
|
if(p>in->s+in->len || *p=='\0')
|
|
goto error_index;
|
|
tok.len = p - tok.s;
|
|
if(sql_parse_index(&tok, &spv->col)!=0)
|
|
goto error_index;
|
|
while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
|
|
p++;
|
|
if(p>in->s+in->len || *p=='\0' || *p!=']')
|
|
goto error_index;
|
|
} else {
|
|
LM_ERR("unknown key [%.*s]\n", pvs.len, pvs.s);
|
|
if(spv!=NULL)
|
|
pkg_free(spv);
|
|
return -1;
|
|
}
|
|
sp->pvp.pvn.u.dname = (void*)spv;
|
|
sp->pvp.pvn.type = PV_NAME_PVAR;
|
|
|
|
return 0;
|
|
|
|
error:
|
|
LM_ERR("invalid pv name [%.*s]\n", in->len, in->s);
|
|
if(spv!=NULL)
|
|
pkg_free(spv);
|
|
return -1;
|
|
|
|
error_index:
|
|
LM_ERR("invalid index in [%.*s]\n", pvs.len, pvs.s);
|
|
if(spv!=NULL)
|
|
pkg_free(spv);
|
|
return -1;
|
|
}
|
|
|