|
41 | 41 | #include "../../dprint.h"
|
42 | 42 | #include "../../error.h"
|
43 | 43 | #include "../../ut.h"
|
| 44 | +#include "../../mod_fix.h" |
44 | 45 | #include "avpops_parse.h"
|
45 | 46 | #include "avpops_impl.h"
|
46 | 47 | #include "avpops_db.h"
|
47 | 48 |
|
48 | 49 | #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 | + |
49 | 60 |
|
50 | 61 | char *printbuf = NULL;
|
51 | 62 |
|
@@ -341,6 +352,34 @@ static int fixup_db_url(void ** param, int require_raw_query, int is_async)
|
341 | 352 | return 0;
|
342 | 353 | }
|
343 | 354 |
|
| 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 | + |
344 | 383 | /* parse the name avp again when adding an avp name prefix (param 4) */
|
345 | 384 | struct db_param *dbp_fixup;
|
346 | 385 |
|
@@ -509,6 +548,8 @@ static int fixup_db_store_avp(void** param, int param_no)
|
509 | 548 | */
|
510 | 549 | static int __fixup_db_query_avp(void** param, int param_no, int is_async)
|
511 | 550 | {
|
| 551 | + int type; |
| 552 | + |
512 | 553 | pv_elem_t *model = NULL;
|
513 | 554 | pvname_list_t *anlist = NULL;
|
514 | 555 | str s;
|
@@ -552,7 +593,54 @@ static int __fixup_db_query_avp(void** param, int param_no, int is_async)
|
552 | 593 | *param = (void*)anlist;
|
553 | 594 | return 0;
|
554 | 595 | } 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; |
556 | 644 | }
|
557 | 645 |
|
558 | 646 | return 0;
|
@@ -1260,19 +1348,65 @@ static int w_dbstore_avps(struct sip_msg* msg, char* source,
|
1260 | 1348 | use_domain);
|
1261 | 1349 | }
|
1262 | 1350 |
|
| 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 | + |
1263 | 1384 | static int w_dbquery_avps(struct sip_msg* msg, char* query,
|
1264 | 1385 | char* dest, char *url)
|
1265 | 1386 | {
|
| 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 | + |
1266 | 1394 | 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); |
1269 | 1396 | }
|
1270 | 1397 |
|
1271 | 1398 | static int w_async_dbquery_avps(struct sip_msg* msg, async_resume_module **rf,
|
1272 | 1399 | void **rparam, char* query, char* dest, char* url)
|
1273 | 1400 | {
|
| 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 | + |
1274 | 1408 | 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); |
1276 | 1410 | }
|
1277 | 1411 |
|
1278 | 1412 | static int w_delete_avps(struct sip_msg* msg, char* param, char* foo)
|
|
0 commit comments