Skip to content

Commit d0f5c3d

Browse files
author
ionutrazvanionita
committed
db in string or int pvar for avp_db_query()
(cherry picked from commit 8a51273) Conflicts: modules/avpops/avpops.c
1 parent 0a642c5 commit d0f5c3d

File tree

3 files changed

+178
-34
lines changed

3 files changed

+178
-34
lines changed

modules/avpops/README

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,8 @@ avp_db_delete("$ru","$avp(1)","3");
401401
(string or integer) will be derived from the type of the
402402
columns.
403403
* db_id - reference to a defined DB URL (a numerical id) -
404-
see the “db_url” module parameter.
404+
see the “db_url” module parameter. It can be either a
405+
constant, or a string/int variable.
405406

406407
This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
407408
BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE.
@@ -413,6 +414,10 @@ avp_db_query("select password, ha1 from subscriber where username='$tu'"
413414
"$avp(678);$avp(679)");
414415
avp_db_query("delete from subscriber");
415416
avp_db_query("delete from subscriber","","2");
417+
418+
$avp(id)=2;#also works $avp(id)="2"
419+
avp_db_query("delete from subscriber","","$avp(id)");
420+
416421
...
417422

418423
1.5.5. avp_delete(name)

modules/avpops/avpops.c

Lines changed: 138 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,22 @@
4141
#include "../../dprint.h"
4242
#include "../../error.h"
4343
#include "../../ut.h"
44+
#include "../../mod_fix.h"
4445
#include "avpops_parse.h"
4546
#include "avpops_impl.h"
4647
#include "avpops_db.h"
4748

4849
#define AVPDB "avp_db"
50+
typedef enum {GPARAM=0, URL} db_id_type;
51+
52+
struct db_url_container {
53+
db_id_type type;
54+
union {
55+
struct db_url *url;
56+
gparam_p gp;
57+
} u;
58+
};
59+
4960

5061
char *printbuf = NULL;
5162

@@ -341,6 +352,34 @@ static int fixup_db_url(void ** param, int require_raw_query, int is_async)
341352
return 0;
342353
}
343354

355+
static int id2db_url(int id, int require_raw_query, int is_async,
356+
struct db_url** url)
357+
{
358+
359+
*url = get_db_url((unsigned int)id);
360+
if (*url==NULL) {
361+
LM_ERR("no db_url with id <%d>\n", id);
362+
return E_CFG;
363+
}
364+
365+
/*
366+
* Since mod_init() is run before function fixups, all DB structs
367+
* are initialized and all DB capabilities are populated
368+
*/
369+
if (require_raw_query && !DB_CAPABILITY((*url)->dbf, DB_CAP_RAW_QUERY)) {
370+
LM_ERR("driver for DB URL [%u] does not support raw queries\n",
371+
(unsigned int)id);
372+
return -1;
373+
}
374+
375+
if (is_async && !DB_CAPABILITY((*url)->dbf, DB_CAP_ASYNC_RAW_QUERY))
376+
LM_WARN("async() calls for DB URL [%u] will work "
377+
"in normal mode due to driver limitations\n",
378+
(unsigned int)id);
379+
380+
return 0;
381+
}
382+
344383
/* parse the name avp again when adding an avp name prefix (param 4) */
345384
struct db_param *dbp_fixup;
346385

@@ -509,6 +548,8 @@ static int fixup_db_store_avp(void** param, int param_no)
509548
*/
510549
static int __fixup_db_query_avp(void** param, int param_no, int is_async)
511550
{
551+
int type;
552+
512553
pv_elem_t *model = NULL;
513554
pvname_list_t *anlist = NULL;
514555
str s;
@@ -552,7 +593,54 @@ static int __fixup_db_query_avp(void** param, int param_no, int is_async)
552593
*param = (void*)anlist;
553594
return 0;
554595
} else if (param_no==3) {
555-
return fixup_db_url(param, 1, is_async);
596+
struct db_url_container *db_id;
597+
598+
if (*param==NULL)
599+
return 0;
600+
601+
if (fixup_igp(param) < 0) {
602+
LM_ERR("fixup failed for param #3!\n");
603+
return -1;
604+
}
605+
606+
db_id=pkg_malloc(sizeof(struct db_url_container));
607+
if (db_id==NULL) {
608+
LM_ERR("no more pkg!\n");
609+
return -1;
610+
}
611+
612+
if ((type=((gparam_p)*param)->type) == GPARAM_TYPE_INT) {
613+
db_id->type = URL;
614+
615+
if (id2db_url(((gparam_p)*param)->v.ival,
616+
1, is_async, &db_id->u.url) < 0) {
617+
LM_ERR("failed to get db url!\n");
618+
619+
return E_CFG;
620+
}
621+
} else if (type == GPARAM_TYPE_STR) {
622+
unsigned int int_id;
623+
if (str2int(&((gparam_p)*param)->v.sval, &int_id) < 0) {
624+
LM_ERR("failed to get db id!\n");
625+
return -1;
626+
}
627+
628+
db_id->type = URL;
629+
630+
if (id2db_url(int_id, 1, is_async, &db_id->u.url) < 0) {
631+
LM_ERR("failed to get db url!\n");
632+
return E_CFG;
633+
}
634+
}
635+
else if(type==GPARAM_TYPE_PVS||type==GPARAM_TYPE_PVE){
636+
db_id->type = GPARAM;
637+
db_id->u.gp = (gparam_p)*param;
638+
} else {
639+
LM_ERR("invalid value for param #3!\n");
640+
return E_CFG;
641+
}
642+
643+
*param = db_id;
556644
}
557645

558646
return 0;
@@ -1260,19 +1348,65 @@ static int w_dbstore_avps(struct sip_msg* msg, char* source,
12601348
use_domain);
12611349
}
12621350

1351+
1352+
static inline int get_url(struct sip_msg* msg, struct db_url_container* _url_struc,
1353+
struct db_url** parsed_url, int is_async)
1354+
{
1355+
int id=0;
1356+
unsigned int gp_flags;
1357+
1358+
str sid;
1359+
gparam_p gp;
1360+
1361+
if (_url_struc) {
1362+
if (_url_struc->type == GPARAM) {
1363+
gp = _url_struc->u.gp;
1364+
if (fixup_get_isvalue(msg, gp, &id, &sid, &gp_flags) < 0
1365+
|| !(gp_flags&GPARAM_INT_VALUE_FLAG)) {
1366+
LM_ERR("Failed to fetch PVAR str value!\n");
1367+
return -1;
1368+
}
1369+
1370+
if (id2db_url(id,1, is_async, parsed_url)) {
1371+
LM_ERR("faild to get db url!\n");
1372+
return -1;
1373+
}
1374+
} else {
1375+
*parsed_url = _url_struc->u.url;
1376+
}
1377+
} else {
1378+
*parsed_url = default_db_url;
1379+
}
1380+
1381+
return 0;
1382+
}
1383+
12631384
static int w_dbquery_avps(struct sip_msg* msg, char* query,
12641385
char* dest, char *url)
12651386
{
1387+
struct db_url *parsed_url;
1388+
1389+
if (get_url(msg, (struct db_url_container*)url, &parsed_url, 0) < 0) {
1390+
LM_ERR("failed to get db url\n");
1391+
return -1;
1392+
}
1393+
12661394
return ops_dbquery_avps ( msg, (pv_elem_t*)query,
1267-
url?(struct db_url*)url:default_db_url,
1268-
(pvname_list_t*)dest);
1395+
parsed_url, (pvname_list_t*)dest);
12691396
}
12701397

12711398
static int w_async_dbquery_avps(struct sip_msg* msg, async_resume_module **rf,
12721399
void **rparam, char* query, char* dest, char* url)
12731400
{
1401+
struct db_url *parsed_url;
1402+
1403+
if (get_url(msg, (struct db_url_container*)url, &parsed_url, 1) < 0) {
1404+
LM_ERR("failed to get db url\n");
1405+
return -1;
1406+
}
1407+
12741408
return ops_async_dbquery(msg, rf, rparam, (pv_elem_t *)query,
1275-
url ? (struct db_url *)url : default_db_url, (pvname_list_t *)dest);
1409+
parsed_url, (pvname_list_t *)dest);
12761410
}
12771411

12781412
static int w_delete_avps(struct sip_msg* msg, char* param, char* foo)

0 commit comments

Comments
 (0)