2 * pua db - presence user agent database support
4 * Copyright (C) 2011 Crocodile RCS Ltd
6 * This file is part of Kamailio, a free SIP server.
8 * Kamailio is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version
13 * Kamailio is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28 #include "../../core/mem/mem.h"
29 #include "../../core/mem/shm_mem.h"
30 #include "../../core/dprint.h"
31 #include "../../lib/srdb1/db.h"
32 #include "../../core/parser/msg_parser.h"
33 #include "../../core/parser/parse_from.h"
39 static str str_id_col = str_init( "id" );
40 static str str_pres_uri_col = str_init("pres_uri");
41 static str str_pres_id_col = str_init("pres_id");
42 static str str_expires_col= str_init("expires");
43 static str str_flag_col= str_init("flag");
44 static str str_etag_col= str_init("etag");
45 static str str_tuple_id_col= str_init("tuple_id");
46 static str str_watcher_uri_col= str_init("watcher_uri");
47 static str str_call_id_col= str_init("call_id");
48 static str str_to_tag_col= str_init("to_tag");
49 static str str_from_tag_col= str_init("from_tag");
50 static str str_cseq_col= str_init("cseq");
51 static str str_event_col= str_init("event");
52 static str str_record_route_col= str_init("record_route");
53 static str str_contact_col= str_init("contact");
54 static str str_remote_contact_col= str_init("remote_contact");
55 static str str_extra_headers_col= str_init("extra_headers");
56 static str str_desired_expires_col= str_init("desired_expires");
57 static str str_version_col = str_init("version");
60 /******************************************************************************/
62 void free_results_puadb( db1_res_t *res )
67 pua_dbf.free_result(pua_db, res);
72 /******************************************************************************/
74 static void extract_row( db_val_t *values, ua_pres_t *result )
78 if (result->pres_uri != NULL )
80 result->pres_uri->s = (char *)VAL_STRING(values+1);
81 result->pres_uri->len = strlen(VAL_STRING(values+1));
84 result->id.s = (char *)VAL_STRING(values+2);
85 result->id.len = strlen(VAL_STRING(values+2));
87 result->event = VAL_INT(values+3);
89 result->expires = VAL_INT(values+4);
91 result->desired_expires = VAL_INT(values+5);
93 result->flag = VAL_INT(values+6);
96 result->etag.s = (char *)VAL_STRING(values+7);
97 result->etag.len = strlen(VAL_STRING(values+7));
99 result->tuple_id.s = (char *)VAL_STRING(values+8);
100 result->tuple_id.len = strlen(VAL_STRING(values+8));
103 if (result->watcher_uri != NULL )
105 result->watcher_uri->s = (char *)VAL_STRING(values+9);
106 result->watcher_uri->len = strlen(VAL_STRING(values+9));
109 result->call_id.s = (char *)VAL_STRING(values+10);
110 result->call_id.len = strlen(VAL_STRING(values+10));
112 result->to_tag.s = (char *)VAL_STRING(values+11);
113 result->to_tag.len = strlen(VAL_STRING(values+11));
115 result->from_tag.s = (char *)VAL_STRING(values+12);
116 result->from_tag.len = strlen(VAL_STRING(values+12));
118 result->cseq = VAL_INT(values+13);
120 result->record_route.s = (char *)VAL_STRING(values+14);
121 result->record_route.len = strlen(VAL_STRING(values+14));
123 result->contact.s = (char *)VAL_STRING(values+15);
124 result->contact.len = strlen(VAL_STRING(values+15));
126 result->remote_contact.s = (char *)VAL_STRING(values+16);
127 result->remote_contact.len = strlen(VAL_STRING(values+16));
129 result->version = VAL_INT(values+17);
131 if (result->extra_headers != NULL )
133 result->extra_headers->s = (char *)VAL_STRING(values+18);
134 result->extra_headers->len = strlen(VAL_STRING(values+18));
138 /******************************************************************************/
140 int clean_puadb( int update_period, int min_expires )
147 db1_res_t *res= NULL;
153 str pres_uri={0,0}, watcher_uri={0,0}, extra_headers={0,0};
155 memset(&p, 0, sizeof(p));
156 p.pres_uri = &pres_uri;
157 p.watcher_uri = &watcher_uri;
158 p.extra_headers = &extra_headers;
162 /* cols and values used for search query */
163 q_cols[0] = &str_expires_col;
164 q_vals[0].type = DB1_INT;
166 q_vals[0].val.int_val = now+update_period;
169 if (pua_dbf.use_table(pua_db, &db_table) < 0) {
170 LM_ERR("error in use_table pua\n");
174 if(db_fetch_query(&pua_dbf, pua_fetch_rows, pua_db, q_cols, q_ops,
175 q_vals, NULL, 1, 0, 0, &res) < 0)
177 LM_ERR("DB query error\n");
183 LM_ERR("bad result\n");
187 if (RES_ROW_N(res) == 0)
190 LM_DBG( "No records matched for clean\n");
191 pua_dbf.free_result(pua_db, res);
196 nr_rows = RES_ROW_N(res);
198 /* get the results and update matching entries */
199 rows = RES_ROWS(res);
201 for (i=0; i < nr_rows; i++)
203 values = ROW_VALUES(rows+i);
205 extract_row( values, &p );
206 id = VAL_INT(values);
208 if((p.desired_expires> p.expires + min_expires) || (p.desired_expires== 0 ))
210 if(update_pua(&p)< 0)
212 LM_ERR("update_pua failed\n");
217 if(p.expires < now - 10)
219 LM_DBG("Found expired: uri= %.*s\n", p.pres_uri->len, p.pres_uri->s);
220 q_cols[0] = &str_id_col;
221 q_vals[0].type = DB1_INT;
223 q_vals[0].val.int_val = id;
225 if ( pua_dbf.delete(pua_db, q_cols, 0, q_vals, 1) < 0 )
227 LM_ERR( "Failed to delete from db\n" );
232 } while ((db_fetch_next(&pua_dbf, pua_fetch_rows, pua_db, &res)==1)
233 && (RES_ROWS(res)>0));
235 pua_dbf.free_result(pua_db, res);
239 /******************************************************************************/
241 int is_dialog_puadb(ua_pres_t *pres)
245 db_key_t q_cols[3], res_cols[1];
246 db1_res_t *res= NULL;
248 int n_query_cols= 0, n_res_cols=0;
252 LM_ERR("called with NULL param\n");
256 /* cols and values used for search query */
257 q_cols[n_query_cols] = &str_call_id_col;
258 q_vals[n_query_cols].type = DB1_STR;
259 q_vals[n_query_cols].nul = 0;
260 q_vals[n_query_cols].val.str_val = pres->call_id;
263 q_cols[n_query_cols] = &str_to_tag_col;
264 q_vals[n_query_cols].type = DB1_STR;
265 q_vals[n_query_cols].nul = 0;
266 q_vals[n_query_cols].val.str_val = pres->to_tag;
269 q_cols[n_query_cols] = &str_from_tag_col;
270 q_vals[n_query_cols].type = DB1_STR;
271 q_vals[n_query_cols].nul = 0;
272 q_vals[n_query_cols].val.str_val = pres->from_tag;
275 /* return the id column, even though don't actually need */
276 res_cols[n_res_cols] = &str_id_col;
281 LM_ERR("null database connection\n");
285 if (pua_dbf.use_table(pua_db, &db_table) < 0)
287 LM_ERR("error in use_table pua\n");
291 if(pua_dbf.query(pua_db, q_cols, 0, q_vals,
292 res_cols,n_query_cols,n_res_cols,0,&res) < 0)
294 LM_ERR("DB query error\n");
300 LM_ERR("bad result\n");
304 nr_rows = RES_ROW_N(res);
305 pua_dbf.free_result(pua_db, res);
310 LM_DBG("No rows found.\n");
316 LM_WARN("Too many rows found (%d)\n", nr_rows);
317 /* no need to return here - drop thro */
320 /* established dialog */
321 if(pres->to_tag.len>0)
323 /* temporary dialog */
327 /******************************************************************************/
329 int get_record_id_puadb(ua_pres_t *pres, str **rec_id )
334 db_key_t q_cols[3], res_cols[2];
335 db1_res_t *res= NULL;
337 int n_query_cols=0, n_res_cols=0;
344 LM_ERR("called with NULL param\n");
348 /* cols and values used for search query */
349 q_cols[n_query_cols] = &str_call_id_col;
350 q_vals[n_query_cols].type = DB1_STR;
351 q_vals[n_query_cols].nul = 0;
352 q_vals[n_query_cols].val.str_val = pres->call_id;
355 q_cols[n_query_cols] = &str_from_tag_col;
356 q_vals[n_query_cols].type = DB1_STR;
357 q_vals[n_query_cols].nul = 0;
358 q_vals[n_query_cols].val.str_val = pres->from_tag;
361 q_cols[n_query_cols] = &str_to_tag_col;
362 q_vals[n_query_cols].type = DB1_STR;
363 q_vals[n_query_cols].nul = 0;
364 q_vals[n_query_cols].val.str_val = pres->to_tag;
367 res_cols[n_res_cols] = &str_pres_id_col;
374 LM_ERR("null database connection\n");
378 if (pua_dbf.use_table(pua_db, &db_table) < 0)
380 LM_ERR("error in use_table pua\n");
384 if(pua_dbf.query(pua_db, q_cols, 0, q_vals,
385 res_cols,n_query_cols,n_res_cols,0,&res) < 0)
387 LM_ERR("DB query error\n");
393 LM_ERR("bad result\n");
397 nr_rows = RES_ROW_N(res);
402 rows = RES_ROWS(res);
403 values = ROW_VALUES(rows);
408 LM_DBG("No rows found. Looking for temporary dialog\n");
409 pua_dbf.free_result(pua_db, res);
413 res_cols[n_res_cols] = &str_to_tag_col;
416 if(pua_dbf.query(pua_db, q_cols, 0, q_vals,
417 res_cols,n_query_cols,n_res_cols,0,&res) < 0)
419 LM_ERR("DB query error\n");
425 LM_ERR("bad result\n");
429 nr_rows = RES_ROW_N(res);
433 rows = RES_ROWS(res);
434 values = ROW_VALUES(rows);
436 to_tag.s = (char *) VAL_STRING(values + 1);
437 to_tag.len = strlen(to_tag.s);
439 if (to_tag.len == 0 ||
441 && strncmp(to_tag.s, pres->to_tag.s, pres->to_tag.len) == 0))
443 LM_DBG( "Found a (possibly temporary) Dialog\n" );
447 LM_WARN("Failed to find temporary dialog for To-tag: %.*s, found To-tag: %.*s\n",
448 pres->to_tag.len, pres->to_tag.s, to_tag.len, to_tag.s);
453 LM_DBG("Dialog not found\n" );
454 pua_dbf.free_result(pua_db, res);
461 LM_ERR("Too many rows found (%d)\n", nr_rows);
462 pua_dbf.free_result(pua_db, res);
466 id= (str*)pkg_malloc(sizeof(str));
470 LM_ERR("No more memory\n");
471 pua_dbf.free_result(pua_db, res);
475 id->s= (char*)pkg_malloc( strlen(VAL_STRING(values)) * sizeof(char));
479 LM_ERR("No more memory\n");
481 pua_dbf.free_result(pua_db, res);
485 memcpy(id->s, VAL_STRING(values), strlen(VAL_STRING(values)) );
486 id->len= strlen(VAL_STRING(values));
489 pua_dbf.free_result(pua_db, res);
491 LM_DBG("Found id=%.*s\n", id->len, id->s);
495 /******************************************************************************/
496 int convert_temporary_dialog_puadb(ua_pres_t *pres)
498 db_key_t query_cols[18];
499 db_val_t query_vals[18];
500 int n_query_cols = 0;
504 LM_ERR("called with NULL param\n");
508 /* The columns I need to query to find the temporary dialog */
509 query_cols[n_query_cols] = &str_pres_id_col;
510 query_vals[n_query_cols].type = DB1_STR;
511 query_vals[n_query_cols].nul = 0;
512 query_vals[n_query_cols].val.str_val = pres->id;
515 query_cols[n_query_cols] = &str_pres_uri_col;
516 query_vals[n_query_cols].type = DB1_STR;
517 query_vals[n_query_cols].nul = 0;
518 query_vals[n_query_cols].val.str_val.s = pres->pres_uri->s;
519 query_vals[n_query_cols].val.str_val.len = pres->pres_uri->len;
522 query_cols[n_query_cols] = &str_call_id_col;
523 query_vals[n_query_cols].type = DB1_STR;
524 query_vals[n_query_cols].nul = 0;
525 query_vals[n_query_cols].val.str_val = pres->call_id;
528 query_cols[n_query_cols] = &str_from_tag_col;
529 query_vals[n_query_cols].type = DB1_STR;
530 query_vals[n_query_cols].nul = 0;
531 query_vals[n_query_cols].val.str_val = pres->from_tag;
534 /* The columns I need to fill in to convert a temporary dialog to a dialog */
535 query_cols[n_query_cols] = &str_expires_col;
536 query_vals[n_query_cols].type = DB1_INT;
537 query_vals[n_query_cols].nul = 0;
538 query_vals[n_query_cols].val.int_val = pres->expires;
541 query_cols[n_query_cols] = &str_desired_expires_col;
542 query_vals[n_query_cols].type = DB1_INT;
543 query_vals[n_query_cols].nul = 0;
544 query_vals[n_query_cols].val.int_val = pres->desired_expires;
547 query_cols[n_query_cols] = &str_flag_col;
548 query_vals[n_query_cols].type = DB1_INT;
549 query_vals[n_query_cols].nul = 0;
550 query_vals[n_query_cols].val.int_val = pres->flag;
553 query_cols[n_query_cols] = &str_to_tag_col;
554 query_vals[n_query_cols].type = DB1_STR;
555 query_vals[n_query_cols].nul = 0;
556 query_vals[n_query_cols].val.str_val = pres->to_tag;
559 query_cols[n_query_cols] = &str_cseq_col;
560 query_vals[n_query_cols].type = DB1_INT;
561 query_vals[n_query_cols].nul = 0;
562 query_vals[n_query_cols].val.int_val = pres->cseq;
565 query_cols[n_query_cols] = &str_record_route_col;
566 query_vals[n_query_cols].type = DB1_STR;
567 query_vals[n_query_cols].nul = 0;
568 query_vals[n_query_cols].val.str_val = pres->record_route;
571 query_cols[n_query_cols] = &str_contact_col;
572 query_vals[n_query_cols].type = DB1_STR;
573 query_vals[n_query_cols].nul = 0;
574 query_vals[n_query_cols].val.str_val = pres->contact;
577 query_cols[n_query_cols] = &str_remote_contact_col;
578 query_vals[n_query_cols].type = DB1_STR;
579 query_vals[n_query_cols].nul = 0;
580 query_vals[n_query_cols].val.str_val = pres->remote_contact;
583 query_cols[n_query_cols] = &str_version_col;
584 query_vals[n_query_cols].type = DB1_INT;
585 query_vals[n_query_cols].nul = 0;
586 query_vals[n_query_cols].val.int_val = pres->version;
589 query_cols[n_query_cols] = &str_extra_headers_col;
590 query_vals[n_query_cols].type = DB1_STR;
591 query_vals[n_query_cols].nul = 0;
592 if (pres->extra_headers)
594 query_vals[n_query_cols].val.str_val.s = pres->extra_headers->s;
595 query_vals[n_query_cols].val.str_val.len = pres->extra_headers->len;
599 query_vals[n_query_cols].val.str_val.s = "";
600 query_vals[n_query_cols].val.str_val.len = 0;
604 query_cols[n_query_cols] = &str_event_col;
605 query_vals[n_query_cols].type = DB1_INT;
606 query_vals[n_query_cols].nul = 0;
607 query_vals[n_query_cols].val.int_val = pres->event;
610 query_cols[n_query_cols] = &str_watcher_uri_col;
611 query_vals[n_query_cols].type = DB1_STR;
612 query_vals[n_query_cols].nul = 0;
613 query_vals[n_query_cols].val.str_val.s = pres->watcher_uri->s;
614 query_vals[n_query_cols].val.str_val.len = pres->watcher_uri->len;
617 query_cols[n_query_cols] = &str_etag_col;
618 query_vals[n_query_cols].type = DB1_STR;
619 query_vals[n_query_cols].nul = 0;
620 query_vals[n_query_cols].val.str_val.s = 0;
621 query_vals[n_query_cols].val.str_val.len = 0;
624 query_cols[n_query_cols] = &str_tuple_id_col;
625 query_vals[n_query_cols].type = DB1_STR;
626 query_vals[n_query_cols].nul = 0;
627 query_vals[n_query_cols].val.str_val.s = 0;
628 query_vals[n_query_cols].val.str_val.len = 0;
631 if (pua_dbf.use_table(pua_db, &db_table) < 0)
633 LM_ERR("error in use_table pua\n");
637 if (pua_dbf.replace != NULL)
639 if (pua_dbf.replace(pua_db, query_cols, query_vals, n_query_cols,
642 LM_ERR("Failed replace db\n");
648 if (pua_dbf.update(pua_db, query_cols, 0, query_vals,
649 query_cols + 4, query_vals + 4, 4, n_query_cols - 4) < 0)
651 LM_ERR("Failed update db\n");
655 LM_DBG("affected_rows: %d\n", pua_dbf.affected_rows(pua_db));
656 if (pua_dbf.affected_rows(pua_db) == 0)
658 if (pua_dbf.insert(pua_db, query_cols, query_vals, n_query_cols) < 0)
660 LM_ERR("Failed insert db\n");
667 shm_free(pres->remote_contact.s);
673 /******************************************************************************/
675 int insert_record_puadb(ua_pres_t* pres)
678 db_key_t db_cols[18];
679 db_val_t db_vals[18];
684 LM_ERR("called with NULL param\n");
688 db_cols[n_cols] = &str_pres_uri_col;
689 db_vals[n_cols].type = DB1_STR;
690 db_vals[n_cols].nul = 0;
691 db_vals[n_cols].val.str_val.s = pres->pres_uri->s;
692 db_vals[n_cols].val.str_val.len = pres->pres_uri->len;
695 db_cols[n_cols] = &str_pres_id_col;
696 db_vals[n_cols].type = DB1_STR;
697 db_vals[n_cols].nul = 0;
698 db_vals[n_cols].val.str_val.s = pres->id.s;
699 db_vals[n_cols].val.str_val.len = pres->id.len;
702 db_cols[n_cols] = &str_event_col;
703 db_vals[n_cols].type = DB1_INT;
704 db_vals[n_cols].nul = 0;
705 db_vals[n_cols].val.int_val = pres->event;
708 db_cols[n_cols] = &str_expires_col;
709 db_vals[n_cols].type = DB1_INT;
710 db_vals[n_cols].nul = 0;
711 db_vals[n_cols].val.int_val = pres->expires;
714 db_cols[n_cols] = &str_desired_expires_col;
715 db_vals[n_cols].type = DB1_INT;
716 db_vals[n_cols].nul = 0;
717 db_vals[n_cols].val.int_val = pres->desired_expires;
720 db_cols[n_cols] = &str_flag_col;
721 db_vals[n_cols].type = DB1_INT;
722 db_vals[n_cols].nul = 0;
723 db_vals[n_cols].val.int_val = pres->flag;
726 db_cols[n_cols] = &str_etag_col;
727 db_vals[n_cols].type = DB1_STR;
728 db_vals[n_cols].nul = 0;
729 db_vals[n_cols].val.str_val.s = pres->etag.s;
730 db_vals[n_cols].val.str_val.len = pres->etag.len;
733 db_cols[n_cols] = &str_tuple_id_col;
734 db_vals[n_cols].type = DB1_STR;
735 db_vals[n_cols].nul = 0;
736 db_vals[n_cols].val.str_val.s = pres->tuple_id.s;
737 db_vals[n_cols].val.str_val.len = pres->tuple_id.len;
740 db_cols[n_cols] = &str_watcher_uri_col;
741 db_vals[n_cols].type = DB1_STR;
742 db_vals[n_cols].nul = 0;
743 db_vals[n_cols].val.str_val.s = "";
744 db_vals[n_cols].val.str_val.len = 0;
747 db_cols[n_cols] = &str_call_id_col;
748 db_vals[n_cols].type = DB1_STR;
749 db_vals[n_cols].nul = 0;
750 db_vals[n_cols].val.str_val.s = "";
751 db_vals[n_cols].val.str_val.len = 0;
754 db_cols[n_cols] = &str_to_tag_col;
755 db_vals[n_cols].type = DB1_STR;
756 db_vals[n_cols].nul = 0;
757 db_vals[n_cols].val.str_val.s = "";
758 db_vals[n_cols].val.str_val.len = 0;
761 db_cols[n_cols] = &str_from_tag_col;
762 db_vals[n_cols].type = DB1_STR;
763 db_vals[n_cols].nul = 0;
764 db_vals[n_cols].val.str_val.s = "";
765 db_vals[n_cols].val.str_val.len = 0;
768 db_cols[n_cols] = &str_cseq_col;
769 db_vals[n_cols].type = DB1_INT;
770 db_vals[n_cols].nul = 0;
771 db_vals[n_cols].val.int_val = 0;
774 db_cols[n_cols] = &str_record_route_col;
775 db_vals[n_cols].type = DB1_STR;
776 db_vals[n_cols].nul = 0;
777 db_vals[n_cols].val.str_val.s = "";
778 db_vals[n_cols].val.str_val.len = 0;
781 db_cols[n_cols] = &str_contact_col;
782 db_vals[n_cols].type = DB1_STR;
783 db_vals[n_cols].nul = 0;
784 db_vals[n_cols].val.str_val.s = "";
785 db_vals[n_cols].val.str_val.len = 0;
788 db_cols[n_cols] = &str_remote_contact_col;
789 db_vals[n_cols].type = DB1_STR;
790 db_vals[n_cols].nul = 0;
791 db_vals[n_cols].val.str_val.s = "";
792 db_vals[n_cols].val.str_val.len = 0;
795 db_cols[n_cols] = &str_version_col;
796 db_vals[n_cols].type = DB1_INT;
797 db_vals[n_cols].nul = 0;
798 db_vals[n_cols].val.int_val = pres->version;
801 db_cols[n_cols] = &str_extra_headers_col;
802 db_vals[n_cols].type = DB1_STR;
803 db_vals[n_cols].nul = 0;
804 if (pres->extra_headers)
806 db_vals[n_cols].val.str_val.s = pres->extra_headers->s;
807 db_vals[n_cols].val.str_val.len = pres->extra_headers->len;
811 db_vals[n_cols].val.str_val.s = "";
812 db_vals[n_cols].val.str_val.len = 0;
818 LM_ERR("null database connection\n");
822 if(pua_dbf.insert(pua_db, db_cols, db_vals, n_cols) < 0)
824 LM_ERR("DB insert failed\n");
831 /******************************************************************************/
833 ua_pres_t *get_record_puadb(str pres_id, str *etag, ua_pres_t *result, db1_res_t **dbres)
836 db_val_t q_vals[2], *values;
839 int n_query_cols = 0, nr_rows;
840 db_query_f query_fn = pua_dbf.query_lock ? pua_dbf.query_lock : pua_dbf.query;
842 q_cols[n_query_cols] = &str_pres_id_col;
843 q_vals[n_query_cols].type = DB1_STR;
844 q_vals[n_query_cols].nul = 0;
845 q_vals[n_query_cols].val.str_val = pres_id;
850 q_cols[n_query_cols] = &str_etag_col;
851 q_vals[n_query_cols].type = DB1_STR;
852 q_vals[n_query_cols].nul = 0;
853 q_vals[n_query_cols].val.str_val.s = etag->s;
854 q_vals[n_query_cols].val.str_val.len = etag->len;
860 LM_ERR("null database connection\n");
864 if (pua_dbf.use_table(pua_db, &db_table) < 0)
866 LM_ERR("error in use_table pua\n");
870 if(query_fn(pua_db, q_cols, 0, q_vals,
871 NULL,n_query_cols,0,0,&res) < 0)
873 LM_ERR("DB query error\n");
879 LM_ERR("bad result\n");
883 nr_rows = RES_ROW_N(res);
888 LM_DBG("No rows found\n");
889 pua_dbf.free_result(pua_db, res);
895 LM_ERR("Too many rows found (%d)\n", nr_rows);
896 pua_dbf.free_result(pua_db, res);
900 /* get the results and fill in return data structure */
901 rows = RES_ROWS(res);
902 values = ROW_VALUES(rows);
904 extract_row( values, result );
911 /******************************************************************************/
913 int delete_record_puadb(ua_pres_t *pres)
917 int n_query_cols = 0;
921 LM_ERR("called with NULL param\n");
925 q_cols[n_query_cols] = &str_pres_id_col;
926 q_vals[n_query_cols].type = DB1_STR;
927 q_vals[n_query_cols].nul = 0;
928 q_vals[n_query_cols].val.str_val = pres->id;
933 q_cols[n_query_cols] = &str_etag_col;
934 q_vals[n_query_cols].type = DB1_STR;
935 q_vals[n_query_cols].nul = 0;
936 q_vals[n_query_cols].val.str_val = pres->etag;
942 LM_ERR("null database connection\n");
946 if (pua_dbf.use_table(pua_db, &db_table) < 0)
948 LM_ERR("error in use_table pua\n");
952 if (pua_dbf.delete(pua_db, q_cols, 0, q_vals, n_query_cols) < 0)
954 LM_ERR("deleting record\n");
961 /******************************************************************************/
963 int update_record_puadb(ua_pres_t *pres, int expires, str *etag)
965 db_key_t q_cols[2], u_cols[3];
966 db_val_t q_vals[2], u_vals[3];
967 int n_query_cols = 0, n_update_cols = 0;
971 LM_ERR("called with NULL param\n");
975 q_cols[n_query_cols] = &str_pres_id_col;
976 q_vals[n_query_cols].type = DB1_STR;
977 q_vals[n_query_cols].nul = 0;
978 q_vals[n_query_cols].val.str_val = pres->id;
983 q_cols[n_query_cols] = &str_etag_col;
984 q_vals[n_query_cols].type = DB1_STR;
985 q_vals[n_query_cols].nul = 0;
986 q_vals[n_query_cols].val.str_val = pres->etag;
990 u_cols[n_update_cols] = &str_desired_expires_col;
991 u_vals[n_update_cols].type = DB1_INT;
992 u_vals[n_update_cols].nul = 0;
993 u_vals[n_update_cols].val.int_val = pres->desired_expires;
996 u_cols[n_update_cols] = &str_expires_col;
997 u_vals[n_update_cols].type = DB1_INT;
998 u_vals[n_update_cols].nul = 0;
999 u_vals[n_update_cols].val.int_val = expires + (int) time(NULL);
1004 u_cols[n_update_cols] = &str_etag_col;
1005 u_vals[n_update_cols].type = DB1_STR;
1006 u_vals[n_update_cols].nul = 0;
1007 u_vals[n_update_cols].val.str_val.s = etag->s;
1008 u_vals[n_update_cols].val.str_val.len = etag->len;
1014 LM_ERR("null database connection\n");
1018 if (pua_dbf.use_table(pua_db, &db_table) < 0)
1020 LM_ERR("error in use_table pua\n");
1024 if (pua_dbf.update(pua_db, q_cols, 0, q_vals, u_cols, u_vals,
1025 n_query_cols, n_update_cols) < 0)
1027 LM_ERR("updating dialog\n");
1031 if (pua_dbf.affected_rows != NULL)
1032 return pua_dbf.affected_rows(pua_db);
1037 /******************************************************************************/
1039 int insert_dialog_puadb(ua_pres_t* pres)
1042 db_key_t db_cols[18];
1043 db_val_t db_vals[18];
1048 LM_ERR("called with NULL param\n");
1052 db_cols[n_cols] = &str_pres_uri_col;
1053 db_vals[n_cols].type = DB1_STR;
1054 db_vals[n_cols].nul = 0;
1055 db_vals[n_cols].val.str_val.s = pres->pres_uri->s;
1056 db_vals[n_cols].val.str_val.len = pres->pres_uri->len;
1059 db_cols[n_cols] = &str_pres_id_col;
1060 db_vals[n_cols].type = DB1_STR;
1061 db_vals[n_cols].nul = 0;
1062 db_vals[n_cols].val.str_val.s = pres->id.s;
1063 db_vals[n_cols].val.str_val.len = pres->id.len;
1066 db_cols[n_cols] = &str_event_col;
1067 db_vals[n_cols].type = DB1_INT;
1068 db_vals[n_cols].nul = 0;
1069 db_vals[n_cols].val.int_val = pres->event;
1072 db_cols[n_cols] = &str_expires_col;
1073 db_vals[n_cols].type = DB1_INT;
1074 db_vals[n_cols].nul = 0;
1075 db_vals[n_cols].val.int_val = pres->expires;
1078 db_cols[n_cols] = &str_desired_expires_col;
1079 db_vals[n_cols].type = DB1_INT;
1080 db_vals[n_cols].nul = 0;
1081 db_vals[n_cols].val.int_val = pres->desired_expires;
1084 db_cols[n_cols] = &str_flag_col;
1085 db_vals[n_cols].type = DB1_INT;
1086 db_vals[n_cols].nul = 0;
1087 db_vals[n_cols].val.int_val = pres->flag;
1090 db_cols[n_cols] = &str_etag_col;
1091 db_vals[n_cols].type = DB1_STR;
1092 db_vals[n_cols].nul = 0;
1093 db_vals[n_cols].val.str_val.s = "";
1094 db_vals[n_cols].val.str_val.len = 0;
1097 db_cols[n_cols] = &str_tuple_id_col;
1098 db_vals[n_cols].type = DB1_STR;
1099 db_vals[n_cols].nul = 0;
1100 db_vals[n_cols].val.str_val.s = "";
1101 db_vals[n_cols].val.str_val.len = 0;
1104 db_cols[n_cols] = &str_watcher_uri_col;
1105 db_vals[n_cols].type = DB1_STR;
1106 db_vals[n_cols].nul = 0;
1107 db_vals[n_cols].val.str_val.s = pres->watcher_uri->s;
1108 db_vals[n_cols].val.str_val.len = pres->watcher_uri->len;
1111 db_cols[n_cols] = &str_call_id_col;
1112 db_vals[n_cols].type = DB1_STR;
1113 db_vals[n_cols].nul = 0;
1114 db_vals[n_cols].val.str_val.s = pres->call_id.s;
1115 db_vals[n_cols].val.str_val.len = pres->call_id.len;
1118 db_cols[n_cols] = &str_to_tag_col;
1119 db_vals[n_cols].type = DB1_STR;
1120 db_vals[n_cols].nul = 0;
1121 db_vals[n_cols].val.str_val.s = pres->to_tag.s;
1122 db_vals[n_cols].val.str_val.len = pres->to_tag.len;
1125 db_cols[n_cols] = &str_from_tag_col;
1126 db_vals[n_cols].type = DB1_STR;
1127 db_vals[n_cols].nul = 0;
1128 db_vals[n_cols].val.str_val.s = pres->from_tag.s;
1129 db_vals[n_cols].val.str_val.len = pres->from_tag.len;
1132 db_cols[n_cols] = &str_cseq_col;
1133 db_vals[n_cols].type = DB1_INT;
1134 db_vals[n_cols].nul = 0;
1135 db_vals[n_cols].val.int_val = pres->cseq;
1138 db_cols[n_cols] = &str_record_route_col;
1139 db_vals[n_cols].type = DB1_STR;
1140 db_vals[n_cols].nul = 0;
1141 db_vals[n_cols].val.str_val.s = pres->record_route.s;
1142 db_vals[n_cols].val.str_val.len = pres->record_route.len;
1145 db_cols[n_cols] = &str_contact_col;
1146 db_vals[n_cols].type = DB1_STR;
1147 db_vals[n_cols].nul = 0;
1148 db_vals[n_cols].val.str_val.s = pres->contact.s;
1149 db_vals[n_cols].val.str_val.len = pres->contact.len;
1152 db_cols[n_cols] = &str_remote_contact_col;
1153 db_vals[n_cols].type = DB1_STR;
1154 db_vals[n_cols].nul = 0;
1155 db_vals[n_cols].val.str_val.s = pres->remote_contact.s;
1156 db_vals[n_cols].val.str_val.len = pres->remote_contact.len;
1159 db_cols[n_cols] = &str_version_col;
1160 db_vals[n_cols].type = DB1_INT;
1161 db_vals[n_cols].nul = 0;
1162 db_vals[n_cols].val.int_val = pres->version;
1165 db_cols[n_cols] = &str_extra_headers_col;
1166 db_vals[n_cols].type = DB1_STR;
1167 db_vals[n_cols].nul = 0;
1168 if (pres->extra_headers)
1170 db_vals[n_cols].val.str_val.s = pres->extra_headers->s;
1171 db_vals[n_cols].val.str_val.len = pres->extra_headers->len;
1175 db_vals[n_cols].val.str_val.s = "";
1176 db_vals[n_cols].val.str_val.len = 0;
1182 LM_ERR("null database connection\n");
1186 if(pua_dbf.insert(pua_db, db_cols, db_vals, n_cols) < 0)
1188 LM_ERR("DB insert failed\n");
1195 /******************************************************************************/
1197 ua_pres_t *get_dialog_puadb(str pres_id, str *pres_uri, ua_pres_t *result, db1_res_t **dbres)
1200 db_val_t q_vals[2], *values;
1203 int n_query_cols = 0, nr_rows;
1204 db_query_f query_fn = pua_dbf.query_lock ? pua_dbf.query_lock : pua_dbf.query;
1206 if (pres_uri == NULL)
1208 LM_ERR("Attempting to search for a dialog without specifying pres_uri\n");
1212 q_cols[n_query_cols] = &str_pres_id_col;
1213 q_vals[n_query_cols].type = DB1_STR;
1214 q_vals[n_query_cols].nul = 0;
1215 q_vals[n_query_cols].val.str_val = pres_id;
1218 q_cols[n_query_cols] = &str_pres_uri_col;
1219 q_vals[n_query_cols].type = DB1_STR;
1220 q_vals[n_query_cols].nul = 0;
1221 q_vals[n_query_cols].val.str_val.s = pres_uri->s;
1222 q_vals[n_query_cols].val.str_val.len = pres_uri->len;
1227 LM_ERR("null database connection\n");
1231 if (pua_dbf.use_table(pua_db, &db_table) < 0)
1233 LM_ERR("error in use_table pua\n");
1237 if(query_fn(pua_db, q_cols, 0, q_vals,
1238 NULL,n_query_cols,0,0,&res) < 0)
1240 LM_ERR("DB query error\n");
1246 LM_ERR("bad result\n");
1250 nr_rows = RES_ROW_N(res);
1255 LM_DBG("No rows found\n");
1256 pua_dbf.free_result(pua_db, res);
1259 else if (nr_rows > 1)
1261 LM_ERR("Too many rows found (%d)... deleting\n", nr_rows);
1262 pua_dbf.free_result(pua_db, res);
1264 if (pua_dbf.delete(pua_db, q_cols, 0, q_vals, n_query_cols) < 0)
1265 LM_ERR("deleting record(s)\n");
1270 /* get the results and fill in return data structure */
1271 rows = RES_ROWS(res);
1272 values = ROW_VALUES(rows);
1274 extract_row( values, result );
1276 /*pua_dbf.free_result(pua_db, res);*/
1282 /******************************************************************************/
1284 int delete_dialog_puadb(ua_pres_t *pres)
1288 int n_query_cols = 0;
1292 LM_ERR("called with NULL param\n");
1296 q_cols[n_query_cols] = &str_call_id_col;
1297 q_vals[n_query_cols].type = DB1_STR;
1298 q_vals[n_query_cols].nul = 0;
1299 q_vals[n_query_cols].val.str_val = pres->call_id;
1302 q_cols[n_query_cols] = &str_from_tag_col;
1303 q_vals[n_query_cols].type = DB1_STR;
1304 q_vals[n_query_cols].nul = 0;
1305 q_vals[n_query_cols].val.str_val = pres->from_tag;
1308 if (pres->to_tag.len > 0 && pres->to_tag.s != NULL)
1310 q_cols[n_query_cols] = &str_to_tag_col;
1311 q_vals[n_query_cols].type = DB1_STR;
1312 q_vals[n_query_cols].nul = 0;
1313 q_vals[n_query_cols].val.str_val = pres->to_tag;
1319 LM_ERR("null database connection\n");
1323 if (pua_dbf.use_table(pua_db, &db_table) < 0)
1325 LM_ERR("error in use_table pua\n");
1329 if (pua_dbf.delete(pua_db, q_cols, 0, q_vals, n_query_cols) < 0)
1331 LM_ERR("deleting record\n");
1338 /******************************************************************************/
1340 int update_dialog_puadb(ua_pres_t *pres, int expires, str *contact)
1342 db_key_t q_cols[3], u_cols[4];
1343 db_val_t q_vals[3], u_vals[4];
1344 int n_query_cols = 0, n_update_cols = 0;
1348 LM_ERR("called with NULL param\n");
1352 q_cols[n_query_cols] = &str_call_id_col;
1353 q_vals[n_query_cols].type = DB1_STR;
1354 q_vals[n_query_cols].nul = 0;
1355 q_vals[n_query_cols].val.str_val = pres->call_id;
1358 q_cols[n_query_cols] = &str_from_tag_col;
1359 q_vals[n_query_cols].type = DB1_STR;
1360 q_vals[n_query_cols].nul = 0;
1361 q_vals[n_query_cols].val.str_val = pres->from_tag;
1364 q_cols[n_query_cols] = &str_to_tag_col;
1365 q_vals[n_query_cols].type = DB1_STR;
1366 q_vals[n_query_cols].nul = 0;
1367 q_vals[n_query_cols].val.str_val = pres->to_tag;
1370 u_cols[n_update_cols] = &str_desired_expires_col;
1371 u_vals[n_update_cols].type = DB1_INT;
1372 u_vals[n_update_cols].nul = 0;
1373 u_vals[n_update_cols].val.int_val = pres->desired_expires;
1376 u_cols[n_update_cols] = &str_expires_col;
1377 u_vals[n_update_cols].type = DB1_INT;
1378 u_vals[n_update_cols].nul = 0;
1379 u_vals[n_update_cols].val.int_val = expires + (int) time(NULL);
1382 u_cols[n_update_cols] = &str_cseq_col;
1383 u_vals[n_update_cols].type = DB1_INT;
1384 u_vals[n_update_cols].nul = 0;
1385 u_vals[n_update_cols].val.int_val = pres->cseq;
1388 u_cols[n_update_cols] = &str_remote_contact_col;
1389 u_vals[n_update_cols].type = DB1_STR;
1390 u_vals[n_update_cols].nul = 0;
1391 u_vals[n_update_cols].val.str_val.s = contact->s;
1392 u_vals[n_update_cols].val.str_val.len = contact->len;
1397 LM_ERR("null database connection\n");
1401 if (pua_dbf.use_table(pua_db, &db_table) < 0)
1403 LM_ERR("error in use_table pua\n");
1407 if (pua_dbf.update(pua_db, q_cols, 0, q_vals, u_cols, u_vals,
1408 n_query_cols, n_update_cols) < 0)
1410 LM_ERR("updating dialog\n");
1417 /******************************************************************************/
1419 int update_contact_puadb(ua_pres_t *pres, str *contact)
1422 db_key_t q_cols[3], db_cols[1];
1423 db_val_t q_vals[3], db_vals[1];
1424 int n_query_cols= 0, n_update_cols=0;
1428 LM_ERR("called with NULL param\n");
1432 /* cols and values used for search query */
1433 q_cols[n_query_cols] = &str_call_id_col;
1434 q_vals[n_query_cols].type = DB1_STR;
1435 q_vals[n_query_cols].nul = 0;
1436 q_vals[n_query_cols].val.str_val = pres->call_id;
1439 q_cols[n_query_cols] = &str_to_tag_col;
1440 q_vals[n_query_cols].type = DB1_STR;
1441 q_vals[n_query_cols].nul = 0;
1442 q_vals[n_query_cols].val.str_val = pres->to_tag;
1445 q_cols[n_query_cols] = &str_from_tag_col;
1446 q_vals[n_query_cols].type = DB1_STR;
1447 q_vals[n_query_cols].nul = 0;
1448 q_vals[n_query_cols].val.str_val = pres->from_tag;
1451 /* we overwrite contact even if not changed */
1452 db_cols[n_update_cols] = &str_remote_contact_col;
1453 db_vals[n_update_cols].type = DB1_STR;
1454 db_vals[n_update_cols].nul = 0;
1455 db_vals[n_update_cols].val.str_val.s = contact->s;
1456 db_vals[n_update_cols].val.str_val.len = contact->len;
1462 LM_ERR("null database connection\n");
1466 if (pua_dbf.use_table(pua_db, &db_table) < 0)
1468 LM_ERR("error in use_table pua\n");
1472 if(pua_dbf.update(pua_db, q_cols, 0, q_vals,
1473 db_cols,db_vals,n_query_cols,n_update_cols) < 0)
1475 LM_ERR("DB update failed\n");
1483 /******************************************************************************/
1485 int update_version_puadb(ua_pres_t *pres)
1488 db_key_t q_cols[3], db_cols[1];
1489 db_val_t q_vals[3], db_vals[1];
1490 int n_query_cols= 0, n_update_cols=0;
1494 LM_ERR("called with NULL param\n");
1498 /* cols and values used for search query */
1499 q_cols[n_query_cols] = &str_call_id_col;
1500 q_vals[n_query_cols].type = DB1_STR;
1501 q_vals[n_query_cols].nul = 0;
1502 q_vals[n_query_cols].val.str_val = pres->call_id;
1505 q_cols[n_query_cols] = &str_to_tag_col;
1506 q_vals[n_query_cols].type = DB1_STR;
1507 q_vals[n_query_cols].nul = 0;
1508 q_vals[n_query_cols].val.str_val = pres->to_tag;
1511 q_cols[n_query_cols] = &str_from_tag_col;
1512 q_vals[n_query_cols].type = DB1_STR;
1513 q_vals[n_query_cols].nul = 0;
1514 q_vals[n_query_cols].val.str_val = pres->from_tag;
1517 /* we overwrite contact even if not changed */
1518 db_cols[n_update_cols] = &str_version_col;
1519 db_vals[n_update_cols].type = DB1_INT;
1520 db_vals[n_update_cols].nul = 0;
1521 db_vals[n_update_cols].val.int_val = pres->version;
1526 LM_ERR("null database connection\n");
1530 if (pua_dbf.use_table(pua_db, &db_table) < 0)
1532 LM_ERR("error in use_table pua\n");
1536 if(pua_dbf.update(pua_db, q_cols, 0, q_vals,
1537 db_cols,db_vals,n_query_cols,n_update_cols) < 0)
1540 LM_ERR("DB update failed\n");
1547 /******************************************************************************/
1549 list_entry_t *get_subs_list_puadb(str *did)
1551 list_entry_t *list = NULL;
1552 db_key_t q_cols[1], res_cols[1];
1553 db1_res_t *res= NULL;
1555 int n_query_cols= 0, n_res_cols = 0;
1557 /* cols and values used for search query */
1558 q_cols[n_query_cols] = &str_pres_id_col;
1559 q_vals[n_query_cols].type = DB1_STR;
1560 q_vals[n_query_cols].nul = 0;
1561 q_vals[n_query_cols].val.str_val.s = did->s;
1562 q_vals[n_query_cols].val.str_val.len = did->len;
1565 res_cols[n_res_cols] = &str_pres_uri_col;
1570 LM_ERR("null database connection\n");
1574 if (pua_dbf.use_table(pua_db, &db_table) < 0)
1576 LM_ERR("error in use_table pua\n");
1580 if(db_fetch_query(&pua_dbf, pua_fetch_rows, pua_db, q_cols, 0,
1581 q_vals, res_cols, n_query_cols, n_res_cols, 0, &res) < 0)
1583 LM_ERR("DB query error\n");
1589 LM_ERR("bad result\n");
1593 if (RES_ROW_N(res) == 0)
1595 LM_INFO( "No records found\n");
1596 pua_dbf.free_result(pua_db, res);
1603 nr_rows = RES_ROW_N(res);
1604 rows = RES_ROWS(res);
1606 for (i=0; i < nr_rows; i++)
1608 str strng, *tmp_str;
1609 strng.s = (char *) VAL_STRING(ROW_VALUES(rows+i));
1610 strng.len = strlen(VAL_STRING(ROW_VALUES(rows+i)));
1612 if ((tmp_str = (str *)pkg_malloc(sizeof(str))) == NULL)
1614 LM_ERR("out of private memory\n");
1615 pua_dbf.free_result(pua_db, res);
1618 if ((tmp_str->s = (char *)pkg_malloc(sizeof(char) * strng.len + 1)) == NULL)
1621 LM_ERR("out of private memory\n");
1622 pua_dbf.free_result(pua_db, res);
1625 memcpy(tmp_str->s, strng.s, strng.len);
1626 tmp_str->len = strng.len;
1627 tmp_str->s[tmp_str->len] = '\0';
1629 list = list_insert(tmp_str, list, NULL);
1631 } while ((db_fetch_next(&pua_dbf, pua_fetch_rows, pua_db, &res)==1)
1632 && (RES_ROWS(res)>0));
1634 pua_dbf.free_result(pua_db, res);