瀏覽代碼

modules_k/pua: PUA DB-only mode performance improvements

- When the PUA DB-only mode was implemented it was designed to do
  (as close as possible) exactly what the hash-table mode did in
  the same way the hash-table mode did it.

  This means lots of hash-table lookups (which are fast) result in
  lots of DB selects (which are slow).  It also means where an entry
  is found in the hash-table and modified in place, in DB mode a
  select must be done and then an update.

  A lot of these DB transactions are not strictly necessary, and
  often fields were retrieved or updated in the DB even when they
  hadn't changed.
- This change refactors the DB-only code (in pua_db.c) and
  re-orders the functional code (in send_(publish|subscribe).c)
  to make the DB operations as simple as possible and as few as
  few as possible.
Peter Dunkley 13 年之前
父節點
當前提交
888d1d5644
共有 4 個文件被更改,包括 571 次插入782 次删除
  1. 377 505
      modules_k/pua/pua_db.c
  2. 9 7
      modules_k/pua/pua_db.h
  3. 75 82
      modules_k/pua/send_publish.c
  4. 110 188
      modules_k/pua/send_subscribe.c

+ 377 - 505
modules_k/pua/pua_db.c

@@ -35,10 +35,10 @@
 #include "../../parser/parse_from.h"
 
 #include "pua.h"
+#include "pua_db.h"
 
 /* database connection */
 extern db1_con_t *pua_db;
-extern db_func_t pua_dbf;
 extern int pua_fetch_rows;
 
 /* database colums */
@@ -79,7 +79,7 @@ void free_results_puadb( db1_res_t *res )
 
 /******************************************************************************/
 
-void extract_row( db_val_t *values, ua_pres_t *result )
+static void extract_row( db_val_t *values, ua_pres_t *result )
 
 {
 
@@ -217,30 +217,6 @@ int clean_puadb( int update_period, int min_expires )
 
 			if((p.desired_expires> p.expires + min_expires) || (p.desired_expires== 0 ))
 			{
-			/*    q_cols[0] = &str_id_col;
-				  q_vals[0].type = DB1_INT;
-				  q_vals[0].nul = 0;
-				  q_vals[0].val.int_val = id;	
-
-				  n_update_cols=0;
-				  db_cols[n_update_cols] = &str_expires_col;
-				  db_vals[n_update_cols].type = DB1_INT;
-				  db_vals[n_update_cols].nul = 0; 
-				  db_vals[n_update_cols].val.int_val = p.expires;
-				  n_update_cols++;
-
-				  db_cols[n_update_cols] = &str_desired_expires_col;
-				  db_vals[n_update_cols].type = DB1_INT;
-				  db_vals[n_update_cols].nul = 0; 
-				  db_vals[n_update_cols].val.int_val = p.desired_expires;
-				  n_update_cols++;
-
-				  if(pua_dbf.update(pua_db, q_cols, 0, q_vals,
-				  db_cols,db_vals,1,n_update_cols) < 0)
-				  {
-				  LM_ERR( "update of db FAILED\n" );
-				  }*/
-
 				if(update_pua(&p)< 0)
 				{
 					LM_ERR("update_pua failed\n");
@@ -263,7 +239,7 @@ int clean_puadb( int update_period, int min_expires )
 				}			
 			}
 
-		} /* for i */
+		}
 	} while ((db_fetch_next(&pua_dbf, pua_fetch_rows, pua_db, &res)==1)
 			&& (RES_ROWS(res)>0));
 
@@ -274,270 +250,6 @@ int clean_puadb( int update_period, int min_expires )
 
 /******************************************************************************/
 
-int matches_in_puadb(ua_pres_t *pres) 
-
-{
-	int nr_rows;
-	db_key_t q_cols[20];
-	db1_res_t *res= NULL;
-	db_val_t q_vals[20];
-	db_op_t  q_ops[20];
-	int n_query_cols= 0;
-	int puri_col,pid_col,flag_col,etag_col, event_col;
-	int watcher_col;
-	int remote_contact_col;	
-
-	if (pres==NULL)
-	{
-		LM_ERR("called with NULL param\n");
-		return(-1);
-	}
-
-	/* cols and values used for search query */
-	q_cols[puri_col= n_query_cols] = &str_pres_uri_col;
-	q_vals[puri_col].type = DB1_STR;
-	q_vals[puri_col].nul = 0;
-	q_vals[puri_col].val.str_val.s = pres->pres_uri->s;
-	q_vals[puri_col].val.str_val.len = pres->pres_uri->len;
-	q_ops[puri_col] = OP_EQ; 
-	n_query_cols++;
-
-	if (pres->id.s && pres->id.len)
-	{
-		q_cols[pid_col= n_query_cols] = &str_pres_id_col;	
-		q_vals[pid_col].type = DB1_STR;
-		q_vals[pid_col].nul = 0;
-		q_vals[pid_col].val.str_val.s = pres->id.s;
-		q_vals[pid_col].val.str_val.len = pres->id.len;
-		q_ops[pid_col] = OP_EQ;
-		n_query_cols++;
-	}
-
-	q_cols[flag_col= n_query_cols] = &str_flag_col;
-	q_vals[flag_col].type = DB1_INT;
-	q_vals[flag_col].nul = 0;
-	q_vals[flag_col].val.int_val = pres->flag;
-	q_ops[flag_col] = OP_BITWISE_AND;
-	n_query_cols++;
-
-	q_cols[event_col= n_query_cols] = &str_event_col;
-	q_vals[event_col].type = DB1_INT;
-	q_vals[event_col].nul = 0;
-	q_vals[event_col].val.int_val = pres->event;
-	q_ops[event_col] = OP_BITWISE_AND;
-	n_query_cols++;
-
-
-	if(pres->watcher_uri)
-	{
-		q_cols[watcher_col= n_query_cols] = &str_watcher_uri_col;
-		q_vals[watcher_col].type = DB1_STR;
-		q_vals[watcher_col].nul = 0;
-		q_vals[watcher_col].val.str_val.s = pres->watcher_uri->s;
-		q_vals[watcher_col].val.str_val.len = pres->watcher_uri->len;
-		q_ops[watcher_col] = OP_EQ;
-		n_query_cols++;
-
-		if (check_remote_contact != 0)
-		{
-			q_cols[remote_contact_col= n_query_cols] = &str_remote_contact_col;
-			q_vals[remote_contact_col].type = DB1_STR;
-			q_vals[remote_contact_col].nul = 0;
-			q_vals[remote_contact_col].val.str_val.s = pres->remote_contact.s;
-			q_vals[remote_contact_col].val.str_val.len = pres->remote_contact.len;
-			q_ops[remote_contact_col] = OP_EQ;
-			n_query_cols++;
-		}
-
-	}
-	else /* no watcher _uri */
-	{
-
-		if(pres->etag.s)
-		{
-			q_cols[etag_col= n_query_cols] = &str_etag_col;
-			q_vals[etag_col].type = DB1_STR;
-			q_vals[etag_col].nul = 0;
-			q_vals[etag_col].val.str_val.s = pres->etag.s;
-			q_vals[etag_col].val.str_val.len = pres->etag.len;
-			q_ops[etag_col] = OP_EQ;
-			n_query_cols++;						
-		}
-		else
-		{
-			LM_DBG("no etag restriction\n");
-		}
-	}
-
-
-	if(pua_db == NULL)
-	{
-		LM_ERR("null database connection\n");
-		return(-1);
-	}
-
-	if(pua_dbf.query(pua_db, q_cols, q_ops, q_vals,
-				0,n_query_cols,0,0,&res) < 0)
-	{
-		LM_ERR("DB query error\n");
-		return(-1);
-	}
-
-	nr_rows = RES_ROW_N(res);
-
-	pua_dbf.free_result(pua_db, res);
-	LM_DBG("Found %d rows\n", nr_rows);
-	return(nr_rows);
-}
-
-/******************************************************************************/
-
-ua_pres_t* search_puadb(ua_pres_t *pres, ua_pres_t *result, db1_res_t **dbres) 
-
-{
-	int nr_rows;
-	db_row_t *rows;
-	db_key_t q_cols[20];
-	db1_res_t *res= NULL;
-	db_val_t q_vals[20];
-	db_op_t  q_ops[20];
-	int n_query_cols= 0;
-	int puri_col,pid_col,flag_col,etag_col,event_col;
-	int watcher_col;
-	int remote_contact_col;	
-	db_val_t *values;
-
-	if (pres==NULL)
-	{
-		LM_ERR("called with NULL param\n");
-		return(NULL);
-	}
-
-	*dbres = NULL;
-
-	if (result==NULL) { LM_ERR( "result is NULL\n" ); return(NULL); }		
-
-	/* cols and values used for search query */ 
-	q_cols[puri_col= n_query_cols] = &str_pres_uri_col;
-	q_vals[puri_col].type = DB1_STR;
-	q_vals[puri_col].nul = 0;
-	q_vals[puri_col].val.str_val.s = pres->pres_uri->s;
-	q_vals[puri_col].val.str_val.len = pres->pres_uri->len;
-	q_ops[puri_col] = OP_EQ; 
-	n_query_cols++;
-
-	if (pres->id.s && pres->id.len)
-	{
-		q_cols[pid_col= n_query_cols] = &str_pres_id_col;	
-		q_vals[pid_col].type = DB1_STR;
-		q_vals[pid_col].nul = 0;
-		q_vals[pid_col].val.str_val.s = pres->id.s;
-		q_vals[pid_col].val.str_val.len = pres->id.len;
-		q_ops[pid_col] = OP_EQ;
-		n_query_cols++;
-	}
-
-	q_cols[flag_col= n_query_cols] = &str_flag_col;
-	q_vals[flag_col].type = DB1_INT;
-	q_vals[flag_col].nul = 0;
-	q_vals[flag_col].val.int_val = pres->flag;
-	q_ops[flag_col] = OP_BITWISE_AND;
-	n_query_cols++;
-
-	q_cols[event_col= n_query_cols] = &str_event_col;
-	q_vals[event_col].type = DB1_INT;
-	q_vals[event_col].nul = 0;
-	q_vals[event_col].val.int_val = pres->event;
-	q_ops[event_col] = OP_BITWISE_AND;
-	n_query_cols++;
-
-	if(pres->watcher_uri)
-	{
-		q_cols[watcher_col= n_query_cols] = &str_watcher_uri_col;
-		q_vals[watcher_col].type = DB1_STR;
-		q_vals[watcher_col].nul = 0;
-		q_vals[watcher_col].val.str_val.s = pres->watcher_uri->s;
-		q_vals[watcher_col].val.str_val.len = pres->watcher_uri->len;
-		q_ops[watcher_col] = OP_EQ;
-		n_query_cols++;
-
-		if (check_remote_contact != 0)
-		{
-			q_cols[remote_contact_col= n_query_cols] = &str_remote_contact_col;
-			q_vals[remote_contact_col].type = DB1_STR;
-			q_vals[remote_contact_col].nul = 0;
-			q_vals[remote_contact_col].val.str_val.s = pres->remote_contact.s;
-			q_vals[remote_contact_col].val.str_val.len = pres->remote_contact.len;
-			q_ops[remote_contact_col] = OP_EQ;
-			n_query_cols++;
-		}
-
-	}
-	else /* no watcher _uri */
-	{
-
-		if(pres->etag.s)
-		{
-			q_cols[etag_col= n_query_cols] = &str_etag_col;
-			q_vals[etag_col].type = DB1_STR;
-			q_vals[etag_col].nul = 0;
-			q_vals[etag_col].val.str_val.s = pres->etag.s;
-			q_vals[etag_col].val.str_val.len = pres->etag.len;
-			q_ops[etag_col] = OP_EQ;
-			n_query_cols++;						
-		}
-		else
-		{
-			LM_DBG("no etag restriction\n");
-		}
-	}
-
-
-	if(pua_db == NULL)
-	{
-		LM_ERR("null database connection\n");
-		return(NULL);
-	}
-
-	if(pua_dbf.query(pua_db, q_cols, q_ops, q_vals,
-				NULL,n_query_cols,0,0,&res) < 0)
-	{
-		LM_ERR("DB query error\n");
-		return(NULL);
-	}
-
-	nr_rows = RES_ROW_N(res);
-
-	if (nr_rows == 0)
-	{
-		/* no match */ 
-		LM_DBG("No rows found\n");
-		pua_dbf.free_result(pua_db, res);
-		return(NULL);
-	}
-
-	if (nr_rows != 1)
-	{
-		LM_ERR("Too many rows found (%d)\n", nr_rows);
-		pua_dbf.free_result(pua_db, res);
-		return(NULL);
-	}
-
-
-	/* get the results and fill in return data structure */
-	rows = RES_ROWS(res);
-	values = ROW_VALUES(rows);
-
-	extract_row( values, result );
-
-	/*pua_dbf.free_result(pua_db, res);*/
-	*dbres = res;
-
-	return(result);
-}
-
-/******************************************************************************/
-
 ua_pres_t* get_dialog_puadb(ua_pres_t *pres, ua_pres_t *result, db1_res_t **dbres) 
 
 {
@@ -1054,17 +766,79 @@ int convert_temporary_dialog_puadb(ua_pres_t *pres)
 
 /******************************************************************************/
 
-int delete_puadb(ua_pres_t *pres ) 
+ua_pres_t *search_record_puadb(str pres_id, str *etag, ua_pres_t *result, db1_res_t **dbres)
+{
+	db_key_t q_cols[2];
+	db_val_t q_vals[2], *values;
+	db_row_t *rows;
+	db1_res_t *res;
+	int n_query_cols = 0, nr_rows;
+
+	q_cols[n_query_cols] = &str_pres_id_col;	
+	q_vals[n_query_cols].type = DB1_STR;
+	q_vals[n_query_cols].nul = 0;
+	q_vals[n_query_cols].val.str_val = pres_id;
+	n_query_cols++;
+
+	if (etag != NULL)
+	{
+		q_cols[n_query_cols] = &str_etag_col;
+		q_vals[n_query_cols].type = DB1_STR;
+		q_vals[n_query_cols].nul = 0;
+		q_vals[n_query_cols].val.str_val.s = etag->s;
+		q_vals[n_query_cols].val.str_val.len = etag->len;
+		n_query_cols++;
+	}
+
+	if(pua_db == NULL)
+	{
+		LM_ERR("null database connection\n");
+		return(NULL);
+	}
+
+	if(pua_dbf.query(pua_db, q_cols, 0, q_vals,
+				NULL,n_query_cols,0,0,&res) < 0)
+	{
+		LM_ERR("DB query error\n");
+		return(NULL);
+	}
+
+	nr_rows = RES_ROW_N(res);
 
+	if (nr_rows == 0)
+	{
+		/* no match */ 
+		LM_DBG("No rows found\n");
+		pua_dbf.free_result(pua_db, res);
+		return(NULL);
+	}
+
+	if (nr_rows != 1)
+	{
+		LM_ERR("Too many rows found (%d)\n", nr_rows);
+		pua_dbf.free_result(pua_db, res);
+		return(NULL);
+	}
+
+	/* get the results and fill in return data structure */
+	rows = RES_ROWS(res);
+	values = ROW_VALUES(rows);
+
+	extract_row( values, result );
+
+	/*pua_dbf.free_result(pua_db, res);*/
+	*dbres = res;
+
+	return(result);
+}
+
+/******************************************************************************/
+
+int delete_record_puadb(ua_pres_t *pres)
 {
-	db_key_t q_cols[20];
-	db_val_t q_vals[20];
-	db_op_t  q_ops[20];
-	int n_query_cols= 0;
-	int puri_col,pid_col,flag_col,etag_col,event_col;
-	int watcher_col;
-	int remote_contact_col;	
-	int rval;		
+	db_key_t q_cols[2];
+	db_val_t q_vals[2];
+	int n_query_cols = 0;
 
 	if (pres==NULL)
 	{
@@ -1072,105 +846,209 @@ int delete_puadb(ua_pres_t *pres )
 		return(-1);
 	}
 
-	/* cols and values used for search query */
-	q_cols[puri_col= n_query_cols] = &str_pres_uri_col;
-	q_vals[puri_col].type = DB1_STR;
-	q_vals[puri_col].nul = 0;
-	q_vals[puri_col].val.str_val.s = pres->pres_uri->s;
-	q_vals[puri_col].val.str_val.len = pres->pres_uri->len;
-	q_ops[puri_col] = OP_EQ; 
+	q_cols[n_query_cols] = &str_pres_id_col;	
+	q_vals[n_query_cols].type = DB1_STR;
+	q_vals[n_query_cols].nul = 0;
+	q_vals[n_query_cols].val.str_val = pres->id;
 	n_query_cols++;
 
-	q_cols[pid_col= n_query_cols] = &str_pres_id_col;	
-	q_vals[pid_col].type = DB1_STR;
-	q_vals[pid_col].nul = 0;
-	q_vals[pid_col].val.str_val.s = pres->id.s;
-	q_vals[pid_col].val.str_val.len = pres->id.len;
-	q_ops[pid_col] = OP_EQ;
-	n_query_cols++;
+	if (pres->etag.s)
+	{
+		q_cols[n_query_cols] = &str_etag_col;
+		q_vals[n_query_cols].type = DB1_STR;
+		q_vals[n_query_cols].nul = 0;
+		q_vals[n_query_cols].val.str_val = pres->etag;
+		n_query_cols++;
+	}
 
-	q_cols[flag_col= n_query_cols] = &str_flag_col;
-	q_vals[flag_col].type = DB1_INT;
-	q_vals[flag_col].nul = 0;
-	q_vals[flag_col].val.int_val = pres->flag;
-	q_ops[flag_col] = OP_BITWISE_AND;
-	n_query_cols++;
+	if(pua_db == NULL)
+	{
+		LM_ERR("null database connection\n");
+		return(-1);
+	}
 
-	q_cols[event_col= n_query_cols] = &str_event_col;
-	q_vals[event_col].type = DB1_INT;
-	q_vals[event_col].nul = 0;
-	q_vals[event_col].val.int_val = pres->event;
-	q_ops[event_col] = OP_BITWISE_AND;
-	n_query_cols++;
+	if (pua_dbf.delete(pua_db, q_cols, 0, q_vals, n_query_cols) < 0) 
+	{
+		LM_ERR("deleting record\n");
+		return -1;
+	}
+
+	if (pua_dbf.affected_rows == NULL)
+		return 1;
+
+	switch(pua_dbf.affected_rows(pua_db))
+	{
+	case 0:
+		LM_ERR("no rows deleted\n");
+		return -1;
+	case 1:
+		return 1;
+	default:
+		LM_ERR("too many rows deleted\n");
+		return -1;
+	}
+}
+
+/******************************************************************************/
 
+int update_record_puadb(ua_pres_t *pres, int expires, str *etag)
+{
+	db_key_t q_cols[2], u_cols[3];
+	db_val_t q_vals[2], u_vals[3];
+	int n_query_cols = 0, n_update_cols = 0;
 
-	if(pres->watcher_uri)
+	if (pres==NULL)
 	{
-		q_cols[watcher_col= n_query_cols] = &str_watcher_uri_col;
-		q_vals[watcher_col].type = DB1_STR;
-		q_vals[watcher_col].nul = 0;
-		q_vals[watcher_col].val.str_val.s = pres->watcher_uri->s;
-		q_vals[watcher_col].val.str_val.len = pres->watcher_uri->len;
-		q_ops[watcher_col] = OP_EQ;
+		LM_ERR("called with NULL param\n");
+		return(-1);
+	}
+
+	q_cols[n_query_cols] = &str_pres_id_col;	
+	q_vals[n_query_cols].type = DB1_STR;
+	q_vals[n_query_cols].nul = 0;
+	q_vals[n_query_cols].val.str_val = pres->id;
+	n_query_cols++;
+
+	if (pres->etag.s)
+	{
+		q_cols[n_query_cols] = &str_etag_col;
+		q_vals[n_query_cols].type = DB1_STR;
+		q_vals[n_query_cols].nul = 0;
+		q_vals[n_query_cols].val.str_val = pres->etag;
 		n_query_cols++;
+	}
 
-		if (check_remote_contact != 0)
-		{
-			q_cols[remote_contact_col= n_query_cols] = &str_remote_contact_col;
-			q_vals[remote_contact_col].type = DB1_STR;
-			q_vals[remote_contact_col].nul = 0;
-			q_vals[remote_contact_col].val.str_val.s = pres->remote_contact.s;
-			q_vals[remote_contact_col].val.str_val.len = pres->remote_contact.len;
-			q_ops[remote_contact_col] = OP_EQ;
-			n_query_cols++;
-		}
+	u_cols[n_update_cols] = &str_desired_expires_col;
+	u_vals[n_update_cols].type = DB1_INT;
+	u_vals[n_update_cols].nul = 0;
+	u_vals[n_update_cols].val.int_val = pres->desired_expires;
+	n_update_cols++;
 
+	u_cols[n_update_cols] = &str_expires_col;
+	u_vals[n_update_cols].type = DB1_INT;
+	u_vals[n_update_cols].nul = 0;
+	u_vals[n_update_cols].val.int_val = expires;
+	n_update_cols++;
+
+	if (etag)
+	{
+		u_cols[n_update_cols] = &str_etag_col;
+		u_vals[n_update_cols].type = DB1_STR;
+		u_vals[n_update_cols].nul = 0;
+		u_vals[n_update_cols].val.str_val.s = etag->s;
+		u_vals[n_update_cols].val.str_val.len = etag->len;
+		n_update_cols++;
+	}
+
+	if(pua_db == NULL)
+	{
+		LM_ERR("null database connection\n");
+		return(-1);
 	}
-	else /* no watcher _uri */
+
+	if (pua_dbf.update(pua_db, q_cols, 0, q_vals, u_cols, u_vals,
+			n_query_cols, n_update_cols) < 0)
 	{
+		LM_ERR("updating dialog\n");
+		return -1;
+	}
 
-		if(pres->etag.s)
-		{
-			q_cols[etag_col= n_query_cols] = &str_etag_col;
-			q_vals[etag_col].type = DB1_STR;
-			q_vals[etag_col].nul = 0;
-			q_vals[etag_col].val.str_val.s = pres->etag.s;
-			q_vals[etag_col].val.str_val.len = pres->etag.len;
-			q_ops[etag_col] = OP_EQ;
-			n_query_cols++;						
-		}
+	if (pua_dbf.affected_rows == NULL)
+	{
+		return 0;
+	}
 
+	switch(pua_dbf.affected_rows(pua_db))
+	{
+	case 0:
+		LM_INFO("no rows updated\n");
+		return -1;
+	case 1:
+		return 1;
+	default:
+		LM_ERR("too many rows updated\n");
+		return -1;
 	}
+}
 
+/******************************************************************************/
+
+ua_pres_t *search_dialog_puadb(str pres_id, str *pres_uri, ua_pres_t *result, db1_res_t **dbres)
+{
+	db_key_t q_cols[2];
+	db_val_t q_vals[2], *values;
+	db_row_t *rows;
+	db1_res_t *res;
+	int n_query_cols = 0, nr_rows;
+
+	if (pres_uri == NULL)
+	{
+		LM_ERR("Attempting to search for a dialog without specifying pres_uri\n");
+		return(NULL);
+	}
+
+	q_cols[n_query_cols] = &str_pres_id_col;	
+	q_vals[n_query_cols].type = DB1_STR;
+	q_vals[n_query_cols].nul = 0;
+	q_vals[n_query_cols].val.str_val = pres_id;
+	n_query_cols++;
+
+	q_cols[n_query_cols] = &str_pres_uri_col;
+	q_vals[n_query_cols].type = DB1_STR;
+	q_vals[n_query_cols].nul = 0;
+	q_vals[n_query_cols].val.str_val.s = pres_uri->s;
+	q_vals[n_query_cols].val.str_val.len = pres_uri->len;
+	n_query_cols++;
 
 	if(pua_db == NULL)
 	{
 		LM_ERR("null database connection\n");
-		return(-1);
+		return(NULL);
 	}
 
-	rval = pua_dbf.delete(pua_db, q_cols, q_ops, q_vals, n_query_cols);
+	if(pua_dbf.query(pua_db, q_cols, 0, q_vals,
+				NULL,n_query_cols,0,0,&res) < 0)
+	{
+		LM_ERR("DB query error\n");
+		return(NULL);
+	}
+
+	nr_rows = RES_ROW_N(res);
 
-	if ( rval < 0 ) 
+	if (nr_rows == 0)
 	{
-		LM_WARN("No dialog found and deleted\n");
+		/* no match */ 
+		LM_DBG("No rows found\n");
+		pua_dbf.free_result(pua_db, res);
+		return(NULL);
 	}
-	else
+
+	if (nr_rows != 1)
 	{
-		LM_DBG("Dialog found and deleted\n");
+		LM_ERR("Too many rows found (%d)\n", nr_rows);
+		pua_dbf.free_result(pua_db, res);
+		return(NULL);
 	}
 
-	return(rval);
+	/* get the results and fill in return data structure */
+	rows = RES_ROWS(res);
+	values = ROW_VALUES(rows);
+
+	extract_row( values, result );
+
+	/*pua_dbf.free_result(pua_db, res);*/
+	*dbres = res;
+
+	return(result);
 }
 
 /******************************************************************************/
 
-int update_contact_puadb(ua_pres_t *pres, str *contact) 
-
+int delete_dialog_puadb(ua_pres_t *pres)
 {
-	db_key_t q_cols[3], db_cols[1];
-	db_val_t q_vals[3], db_vals[1];
-	int n_query_cols= 0, n_update_cols=0;
+	db_key_t q_cols[3];
+	db_val_t q_vals[3];
+	int n_query_cols = 0;
 
 	if (pres==NULL)
 	{
@@ -1178,17 +1056,73 @@ int update_contact_puadb(ua_pres_t *pres, str *contact)
 		return(-1);
 	}
 
-	/* cols and values used for search query */
 	q_cols[n_query_cols] = &str_call_id_col;	
 	q_vals[n_query_cols].type = DB1_STR;
 	q_vals[n_query_cols].nul = 0;
 	q_vals[n_query_cols].val.str_val = pres->call_id;
 	n_query_cols++;
 
-	q_cols[n_query_cols] = &str_to_tag_col;	
+	q_cols[n_query_cols] = &str_from_tag_col;	
 	q_vals[n_query_cols].type = DB1_STR;
 	q_vals[n_query_cols].nul = 0;
-	q_vals[n_query_cols].val.str_val = pres->to_tag;
+	q_vals[n_query_cols].val.str_val = pres->from_tag;
+	n_query_cols++;
+
+	if (pres->to_tag.len > 0 && pres->to_tag.s != NULL)
+	{
+		q_cols[n_query_cols] = &str_to_tag_col;	
+		q_vals[n_query_cols].type = DB1_STR;
+		q_vals[n_query_cols].nul = 0;
+		q_vals[n_query_cols].val.str_val = pres->to_tag;
+		n_query_cols++;
+	}
+	
+	if(pua_db == NULL)
+	{
+		LM_ERR("null database connection\n");
+		return(-1);
+	}
+
+	if (pua_dbf.delete(pua_db, q_cols, 0, q_vals, n_query_cols) < 0) 
+	{
+		LM_ERR("deleting record\n");
+		return -1;
+	}
+
+	if (pua_dbf.affected_rows == NULL)
+		return 1;
+
+	switch(pua_dbf.affected_rows(pua_db))
+	{
+	case 0:
+		LM_ERR("no rows deleted\n");
+		return -1;
+	case 1:
+		return 1;
+	default:
+		LM_ERR("too many rows deleted\n");
+		return -1;
+	}
+}
+
+/******************************************************************************/
+
+int update_dialog_puadb(ua_pres_t *pres, int expires, str *contact)
+{
+	db_key_t q_cols[3], u_cols[3];
+	db_val_t q_vals[3], u_vals[3];
+	int n_query_cols = 0, n_update_cols = 0;
+
+	if (pres==NULL)
+	{
+		LM_ERR("called with NULL param\n");
+		return(-1);
+	}
+
+	q_cols[n_query_cols] = &str_call_id_col;	
+	q_vals[n_query_cols].type = DB1_STR;
+	q_vals[n_query_cols].nul = 0;
+	q_vals[n_query_cols].val.str_val = pres->call_id;
 	n_query_cols++;
 
 	q_cols[n_query_cols] = &str_from_tag_col;	
@@ -1197,14 +1131,30 @@ int update_contact_puadb(ua_pres_t *pres, str *contact)
 	q_vals[n_query_cols].val.str_val = pres->from_tag;
 	n_query_cols++;
 
-	/* we overwrite contact even if not changed */
-	db_cols[n_update_cols] = &str_contact_col; /* had remote here, think was a bug */
-	db_vals[n_update_cols].type = DB1_STR;
-	db_vals[n_update_cols].nul = 0; 
-	db_vals[n_update_cols].val.str_val.s = contact->s;
-	db_vals[n_update_cols].val.str_val.len = contact->len;
+	q_cols[n_query_cols] = &str_to_tag_col;	
+	q_vals[n_query_cols].type = DB1_STR;
+	q_vals[n_query_cols].nul = 0;
+	q_vals[n_query_cols].val.str_val = pres->to_tag;
+	n_query_cols++;
+
+	u_cols[n_update_cols] = &str_desired_expires_col;
+	u_vals[n_update_cols].type = DB1_INT;
+	u_vals[n_update_cols].nul = 0;
+	u_vals[n_update_cols].val.int_val = pres->desired_expires;
+	n_update_cols++;
+
+	u_cols[n_update_cols] = &str_expires_col;
+	u_vals[n_update_cols].type = DB1_INT;
+	u_vals[n_update_cols].nul = 0;
+	u_vals[n_update_cols].val.int_val = expires;
 	n_update_cols++;
 
+	u_cols[n_update_cols] = &str_remote_contact_col;
+	u_vals[n_update_cols].type = DB1_STR;
+	u_vals[n_update_cols].nul = 0;
+	u_vals[n_update_cols].val.str_val.s = contact->s;
+	u_vals[n_update_cols].val.str_val.len = contact->len;
+	n_update_cols++;
 
 	if(pua_db == NULL)
 	{
@@ -1212,20 +1162,32 @@ int update_contact_puadb(ua_pres_t *pres, str *contact)
 		return(-1);
 	}
 
-	if(pua_dbf.update(pua_db, q_cols, 0, q_vals,
-				db_cols,db_vals,n_query_cols,n_update_cols) < 0)
+	if (pua_dbf.update(pua_db, q_cols, 0, q_vals, u_cols, u_vals,
+			n_query_cols, n_update_cols) < 0)
 	{
-		LM_ERR("DB update failed\n");
-		return(-1);
+		LM_ERR("updating dialog\n");
+		return -1;
 	}
 
-	return(0);
-}
+	if (pua_dbf.affected_rows == NULL)
+		return 1;
 
+	switch(pua_dbf.affected_rows(pua_db))
+	{
+	case 0:
+		LM_ERR("no rows updated\n");
+		return -1;
+	case 1:
+		return 1;
+	default:
+		LM_ERR("too many rows updated\n");
+		return -1;
+	}
+}
 
 /******************************************************************************/
 
-int update_version_puadb(ua_pres_t *pres, int version ) 
+int update_contact_puadb(ua_pres_t *pres, str *contact) 
 
 {
 	db_key_t q_cols[3], db_cols[1];
@@ -1258,10 +1220,11 @@ int update_version_puadb(ua_pres_t *pres, int version )
 	n_query_cols++;
 
 	/* we overwrite contact even if not changed */
-	db_cols[n_update_cols] = &str_version_col;
-	db_vals[n_update_cols].type = DB1_INT;
-	db_vals[n_update_cols].nul = 0;
-	db_vals[n_update_cols].val.int_val = version;
+	db_cols[n_update_cols] = &str_contact_col; /* had remote here, think was a bug */
+	db_vals[n_update_cols].type = DB1_STR;
+	db_vals[n_update_cols].nul = 0; 
+	db_vals[n_update_cols].val.str_val.s = contact->s;
+	db_vals[n_update_cols].val.str_val.len = contact->len;
 	n_update_cols++;
 
 
@@ -1273,7 +1236,6 @@ int update_version_puadb(ua_pres_t *pres, int version )
 
 	if(pua_dbf.update(pua_db, q_cols, 0, q_vals,
 				db_cols,db_vals,n_query_cols,n_update_cols) < 0)
-
 	{
 		LM_ERR("DB update failed\n");
 		return(-1);
@@ -1285,153 +1247,63 @@ int update_version_puadb(ua_pres_t *pres, int version )
 
 /******************************************************************************/
 
-void update_puadb(ua_pres_t* pres, time_t desired_expires, 
-		int expires, str* etag, str *contact)
+int update_version_puadb(ua_pres_t *pres) 
 
 {
-	db_key_t q_cols[20];
-	db_key_t db_cols[5];
-	db_val_t q_vals[20], db_vals[5];
-	db_op_t  q_ops[20];
-	int n_query_cols= 0;
-	int n_update_cols= 0;
-	int puri_col,pid_col,flag_col,etag_col,event_col;
-	int watcher_col;
-	int remote_contact_col;	
+	db_key_t q_cols[3], db_cols[1];
+	db_val_t q_vals[3], db_vals[1];
+	int n_query_cols= 0, n_update_cols=0;
 
 	if (pres==NULL)
 	{
 		LM_ERR("called with NULL param\n");
-		return;
+		return(-1);
 	}
 
 	/* cols and values used for search query */
-	q_cols[puri_col= n_query_cols] = &str_pres_uri_col;
-	q_vals[puri_col].type = DB1_STR;
-	q_vals[puri_col].nul = 0;
-	q_vals[puri_col].val.str_val.s = pres->pres_uri->s;
-	q_vals[puri_col].val.str_val.len = pres->pres_uri->len;
-	q_ops[puri_col] = OP_EQ; 
-	n_query_cols++;
-
-	q_cols[pid_col= n_query_cols] = &str_pres_id_col;	
-	q_vals[pid_col].type = DB1_STR;
-	q_vals[pid_col].nul = 0;
-	q_vals[pid_col].val.str_val.s = pres->id.s;
-	q_vals[pid_col].val.str_val.len = pres->id.len;
-	q_ops[pid_col] = OP_EQ;
+	q_cols[n_query_cols] = &str_call_id_col;	
+	q_vals[n_query_cols].type = DB1_STR;
+	q_vals[n_query_cols].nul = 0;
+	q_vals[n_query_cols].val.str_val = pres->call_id;
 	n_query_cols++;
 
-	q_cols[flag_col= n_query_cols] = &str_flag_col;
-	q_vals[flag_col].type = DB1_INT;
-	q_vals[flag_col].nul = 0;
-	q_vals[flag_col].val.int_val = pres->flag;
-	q_ops[flag_col] = OP_BITWISE_AND;
+	q_cols[n_query_cols] = &str_to_tag_col;	
+	q_vals[n_query_cols].type = DB1_STR;
+	q_vals[n_query_cols].nul = 0;
+	q_vals[n_query_cols].val.str_val = pres->to_tag;
 	n_query_cols++;
 
-	q_cols[event_col= n_query_cols] = &str_event_col;
-	q_vals[event_col].type = DB1_INT;
-	q_vals[event_col].nul = 0;
-	q_vals[event_col].val.int_val = pres->event;
-	q_ops[event_col] = OP_BITWISE_AND;
+	q_cols[n_query_cols] = &str_from_tag_col;	
+	q_vals[n_query_cols].type = DB1_STR;
+	q_vals[n_query_cols].nul = 0;
+	q_vals[n_query_cols].val.str_val = pres->from_tag;
 	n_query_cols++;
 
-
-	if(pres->watcher_uri)
-	{
-		q_cols[watcher_col= n_query_cols] = &str_watcher_uri_col;
-		q_vals[watcher_col].type = DB1_STR;
-		q_vals[watcher_col].nul = 0;
-		q_vals[watcher_col].val.str_val.s = pres->watcher_uri->s;
-		q_vals[watcher_col].val.str_val.len = pres->watcher_uri->len;
-		q_ops[watcher_col] = OP_EQ;
-		n_query_cols++;
-
-		if (check_remote_contact != 0)
-		{
-			q_cols[remote_contact_col= n_query_cols] = &str_remote_contact_col;
-			q_vals[remote_contact_col].type = DB1_STR;
-			q_vals[remote_contact_col].nul = 0;
-			q_vals[remote_contact_col].val.str_val.s = pres->remote_contact.s;
-			q_vals[remote_contact_col].val.str_val.len = pres->remote_contact.len;
-			q_ops[remote_contact_col] = OP_EQ;
-			n_query_cols++;
-		}
-
-	}
-	else /* no watcher _uri */
-	{
-
-		if(pres->etag.s)
-		{
-			q_cols[etag_col= n_query_cols] = &str_etag_col;
-			q_vals[etag_col].type = DB1_STR;
-			q_vals[etag_col].nul = 0;
-			q_vals[etag_col].val.str_val.s = pres->etag.s;
-			q_vals[etag_col].val.str_val.len = pres->etag.len;
-			q_ops[etag_col] = OP_EQ;
-			n_query_cols++;						
-		}
-
-	}
-
-	db_cols[n_update_cols] = &str_expires_col;
-	db_vals[n_update_cols].type = DB1_INT;
-	db_vals[n_update_cols].nul = 0; 
-	db_vals[n_update_cols].val.int_val = expires + (int)time(NULL);
-	n_update_cols++;
-
-	db_cols[n_update_cols] = &str_desired_expires_col;
+	/* we overwrite contact even if not changed */
+	db_cols[n_update_cols] = &str_version_col;
 	db_vals[n_update_cols].type = DB1_INT;
-	db_vals[n_update_cols].nul = 0; 
-	db_vals[n_update_cols].val.int_val = desired_expires;
+	db_vals[n_update_cols].nul = 0;
+	db_vals[n_update_cols].val.int_val = pres->version;
 	n_update_cols++;
 
-	if(pres->watcher_uri)
-	{
-		db_cols[n_update_cols] = &str_cseq_col;
-		db_vals[n_update_cols].type = DB1_INT;
-		db_vals[n_update_cols].nul = 0; 
-		db_vals[n_update_cols].val.int_val = pres->cseq+1;
-		n_update_cols++;
-	}
-
-	if(etag)
-	{	
-		db_cols[n_update_cols] = &str_etag_col;
-		db_vals[n_update_cols].type = DB1_STR;
-		db_vals[n_update_cols].nul = 0; 
-		db_vals[n_update_cols].val.str_val.s = etag->s;
-		db_vals[n_update_cols].val.str_val.len = etag->len;
-		n_update_cols++;
-	}
-
-	if (contact)
-	{
-		/* we overwrite contact even if not changed,
-		   saves retrieving record to check, when the 
-		   record has gotta be updated anyway! */
-		db_cols[n_update_cols] = &str_contact_col; /* had remote here think was a bug */
-		db_vals[n_update_cols].type = DB1_STR;
-		db_vals[n_update_cols].nul = 0; 
-		db_vals[n_update_cols].val.str_val.s = contact->s;
-		db_vals[n_update_cols].val.str_val.len = contact->len;
-		n_update_cols++;
-	}
-
 	if(pua_db == NULL)
 	{
 		LM_ERR("null database connection\n");
-		return;
+		return(-1);
 	}
 
-	if(pua_dbf.update(pua_db, q_cols, q_ops, q_vals,
+	if(pua_dbf.update(pua_db, q_cols, 0, q_vals,
 				db_cols,db_vals,n_query_cols,n_update_cols) < 0)
+
 	{
 		LM_ERR("DB update failed\n");
+		return(-1);
 	}
+
+	return(0);
 }
 
+
 /******************************************************************************/
 
 int insert_puadb(ua_pres_t* pres)

+ 9 - 7
modules_k/pua/pua_db.h

@@ -47,20 +47,22 @@
 #define PUA_VERSION (1<<16)
 #define PUA_EXTRA_HEADERS (1<<17)
 
+extern db_func_t pua_dbf;
+
 void free_results_puadb( db1_res_t *res );
-int matches_in_puadb(ua_pres_t *pres);
-ua_pres_t* search_puadb(ua_pres_t *pres, ua_pres_t *result, db1_res_t **res );
 ua_pres_t* get_dialog_puadb(ua_pres_t *pres, ua_pres_t *result, db1_res_t **res);
 int is_dialog_puadb(ua_pres_t *pres);
 int get_record_id_puadb(ua_pres_t *pres, str **rec_id );
 int convert_temporary_dialog_puadb(ua_pres_t *pres);
-int delete_puadb(ua_pres_t *pres );
-int update_version_puadb(ua_pres_t *pres, int version );
+ua_pres_t *search_dialog_puadb(str pres_id, str *pres_uri, ua_pres_t *result, db1_res_t **res);
+int delete_dialog_puadb(ua_pres_t *pres);
+int update_dialog_puadb(ua_pres_t *pres, int expires, str *contact);
+ua_pres_t *search_record_puadb(str pres_id, str *etag, ua_pres_t *result, db1_res_t **res);
+int delete_record_puadb(ua_pres_t *pres);
+int update_record_puadb(ua_pres_t *pres, int expires, str *contact);
+int update_version_puadb(ua_pres_t *pres);
 int update_contact_puadb(ua_pres_t *pres, str *contact);
-void update_puadb(ua_pres_t* pres, time_t desired_expires, 
-                       int expires, str* etag, str *contact);
 int insert_puadb(ua_pres_t* pres);
 list_entry_t *get_subs_list_puadb(str *did);
 
-
 #endif

+ 75 - 82
modules_k/pua/send_publish.c

@@ -49,7 +49,6 @@
 #include "event_list.h"
 #include "pua_db.h"
 
-
 str* publ_build_hdr(int expires, pua_event_t* ev, str* content_type, str* etag,
 		str* extra_headers, int is_body)
 {
@@ -146,6 +145,53 @@ str* publ_build_hdr(int expires, pua_event_t* ev, str* content_type, str* etag,
 
 }
 
+static void find_and_delete_record(ua_pres_t *dialog, int hash_code)
+{
+	ua_pres_t *presentity;
+
+	if (dbmode == PUA_DB_ONLY)
+	{
+		delete_record_puadb(dialog);
+	}
+	else
+	{
+		lock_get(&HashT->p_records[hash_code].lock);
+		presentity = search_htable(dialog, hash_code);
+		if (presentity == NULL)
+		{
+			LM_DBG("Record found in table and deleted\n");
+			lock_release(&HashT->p_records[hash_code].lock);
+			return;
+		}
+		delete_htable(presentity, hash_code);
+		lock_release(&HashT->p_records[hash_code].lock);
+	}
+}
+
+static int find_and_update_record(ua_pres_t *dialog, int hash_code, int lexpire, str *etag)
+{
+	ua_pres_t *presentity;
+
+	if(dbmode==PUA_DB_ONLY)
+	{
+		return update_record_puadb(dialog, lexpire, etag);
+	}
+	else
+	{
+		lock_get(&HashT->p_records[hash_code].lock);
+		presentity = search_htable(dialog, hash_code);
+		if (presentity == NULL)
+		{
+			LM_DBG("Record found in table and deleted\n");
+			lock_release(&HashT->p_records[hash_code].lock);
+			return 0;
+		}
+		update_htable(presentity, dialog->desired_expires, lexpire, etag, hash_code, NULL);
+		lock_release(&HashT->p_records[hash_code].lock);
+		return 1;
+	}
+}
+
 void publ_cback_func(struct cell *t, int type, struct tmcb_params *ps)
 {
 	struct hdr_field* hdr= NULL;
@@ -188,30 +234,11 @@ void publ_cback_func(struct cell *t, int type, struct tmcb_params *ps)
 		goto done;
 	}
 
+	hash_code= core_hash(hentity->pres_uri, NULL, HASH_SIZE);
+
 	if( ps->code>= 300 )
 	{
-
-		if(dbmode==PUA_DB_ONLY)
-		{
-			delete_puadb(hentity);
-		}
-		else
-		{
-			hash_code= core_hash(hentity->pres_uri, NULL,HASH_SIZE);
-			lock_get(&HashT->p_records[hash_code].lock);
-			presentity= search_htable( hentity, hash_code);
-			if(presentity)
-			{
-				LM_DBG("Record found in table and deleted\n");
-				delete_htable(presentity, hash_code);
-			}
-			else
-			{
-				LM_DBG("Record not found in table\n");
-			}
-
-			lock_release(&HashT->p_records[hash_code].lock);
-		}
+		find_and_delete_record(hentity, hash_code);
 
 		if(ps->code== 412 && hentity->body && hentity->flag!= MI_PUBLISH
 				&& hentity->flag!= MI_ASYN_PUBLISH)
@@ -287,58 +314,26 @@ void publ_cback_func(struct cell *t, int type, struct tmcb_params *ps)
 	LM_DBG("completed with status %d [contact:%.*s]\n",
 			ps->code, hentity->pres_uri->len, hentity->pres_uri->s);
 
-	if (dbmode==PUA_DB_ONLY)
+	if (lexpire == 0)
 	{
-		db_presentity = search_puadb(hentity,&dbpres, &res);
-		/* this needs the columns used in update_db only */
+		find_and_delete_record(hentity, hash_code);
+		goto done;
+	}
 
-		if(db_presentity)
-		{
-			LM_DBG("update DB record\n");
-			if(lexpire == 0)
-			{
-				LM_DBG("expires= 0- delete from htable\n"); 
-				delete_puadb(hentity);
-				goto done;
-			}
-			
-			update_puadb( db_presentity, hentity->desired_expires, lexpire, &etag, NULL );
+	if (pua_dbf.affected_rows != NULL || dbmode != PUA_DB_ONLY)
+	{
+		if (find_and_update_record(hentity, hash_code, lexpire, &etag) > 0)
 			goto done;
-		}
-
 	}
 	else
 	{
-		hash_code= core_hash(hentity->pres_uri, NULL, HASH_SIZE);
-		lock_get(&HashT->p_records[hash_code].lock);
-		presentity= search_htable(hentity, hash_code);
-
-		if(presentity)
+		if ((db_presentity = search_record_puadb(hentity->id, &hentity->etag, &dbpres, &res)) != NULL)
 		{
-			LM_DBG("update hash record\n");
-
-			if(lexpire == 0)
-			{
-				LM_DBG("expires= 0- delete from htable\n"); 
-				delete_htable(presentity, hash_code);
-				lock_release(&HashT->p_records[hash_code].lock);
-				goto done;
-			}
-			
-			update_htable(presentity, hentity->desired_expires,
-					lexpire, &etag, hash_code, NULL);
-			lock_release(&HashT->p_records[hash_code].lock);
+			update_record_puadb(hentity, lexpire, &etag);
 			goto done;
 		}
-
-		lock_release(&HashT->p_records[hash_code].lock);
 	}
 
-	if(lexpire== 0)
-	{
-		LM_DBG("expires= 0: no not insert\n");
-		goto done;
-	}
 	size= sizeof(ua_pres_t)+ sizeof(str)+ 
 		(hentity->pres_uri->len+ hentity->tuple_id.len + 
 		 hentity->id.len)* sizeof(char);
@@ -426,7 +421,7 @@ done:
 		shm_free(presentity);
 	}
 
-	free_results_puadb(res);
+	if (res) free_results_puadb(res);
 	return;
 
 error:
@@ -435,10 +430,9 @@ error:
 		shm_free(*ps->param);
 		*ps->param= NULL;
 	}
-	if(presentity)
-		shm_free(presentity);
+	if(presentity) shm_free(presentity);
 
-	free_results_puadb(res);
+	if (res) free_results_puadb(res);
 	return;
 }	
 
@@ -449,7 +443,7 @@ int send_publish( publ_info_t* publ )
 	ua_pres_t* presentity= NULL;
 	str* body= NULL;
 	str* tuple_id= NULL;
-	ua_pres_t* cb_param= NULL, pres;
+	ua_pres_t* cb_param= NULL;
 	unsigned int hash_code=0;
 	str etag= {0, 0};
 	int ver= 0;
@@ -472,29 +466,28 @@ int send_publish( publ_info_t* publ )
 		goto error;
 	}	
 
-	memset(&pres, 0, sizeof(ua_pres_t));
-	pres.pres_uri= publ->pres_uri;
-	pres.flag= publ->source_flag;
-	pres.id= publ->id;
-	pres.event= publ->event;
-	if(publ->etag)
-		pres.etag= *publ->etag;
-
 	if (dbmode==PUA_DB_ONLY)
 	{
-		/* do db specific stuff-pjp */
 		memset(&dbpres, 0, sizeof(dbpres));
 		dbpres.pres_uri = &pres_uri;
 		dbpres.watcher_uri = &watcher_uri;
 		dbpres.extra_headers = &extra_headers;
-		presentity = search_puadb(&pres, &dbpres, &res);
+		presentity = search_record_puadb(publ->id, publ->etag, &dbpres, &res);
 	}
 	else
 	{
-		hash_code= core_hash(publ->pres_uri, NULL, HASH_SIZE);
+		ua_pres_t pres;
+
+		memset(&pres, 0, sizeof(ua_pres_t));
+		pres.pres_uri = publ->pres_uri;
+		pres.flag = publ->source_flag;
+		pres.id = publ->id;
+		pres.event = publ->event;
+		if(publ->etag)
+			pres.etag = *publ->etag;
 
+		hash_code= core_hash(publ->pres_uri, NULL, HASH_SIZE);
 		lock_get(&HashT->p_records[hash_code].lock);
-	
 		presentity= search_htable(&pres, hash_code);
 	}
 
@@ -590,7 +583,7 @@ insert:
 
 		if (dbmode==PUA_DB_ONLY)
 		{ 
-			update_version_puadb(&pres,ver);
+			update_version_puadb(presentity);
 		}
 		else
 		{

+ 110 - 188
modules_k/pua/send_subscribe.c

@@ -228,43 +228,51 @@ static int pua_free_tm_dlg(dlg_t *td)
 static void find_and_delete_dialog(ua_pres_t *dialog, int hash_code)
 {
 	ua_pres_t *presentity;
- 	ua_pres_t dbpres;
-	str pres_uri={0,0}, watcher_uri={0,0}, extra_headers={0,0};
-	db1_res_t *res=NULL;
-
-	memset(&dbpres, 0, sizeof(dbpres));
-	dbpres.pres_uri = &pres_uri;
-	dbpres.watcher_uri = &watcher_uri;
-	dbpres.extra_headers = &extra_headers;
 
-	if (dbmode==PUA_DB_ONLY)
+	if (dbmode == PUA_DB_ONLY)
 	{
-		presentity = get_dialog_puadb(dialog, &dbpres, &res);
+		delete_dialog_puadb(dialog);
 	}
 	else
-	{		
+	{
 		lock_get(&HashT->p_records[hash_code].lock);
  		presentity= get_dialog(dialog, hash_code);
 		if (presentity == NULL)
+		{
 			presentity = get_temporary_dialog(dialog, hash_code);
-	}
+			if(presentity== NULL)
+			{
+				LM_ERR("no record found\n");
+				lock_release(&HashT->p_records[hash_code].lock);
+				return;
+			}
+		}
 
-	if(presentity== NULL)
-	{
-		LM_ERR("no record found\n");
-		if (dbmode!=PUA_DB_ONLY)
-			lock_release(&HashT->p_records[hash_code].lock);
-		return;
+		delete_htable(presentity, hash_code);
+		lock_release(&HashT->p_records[hash_code].lock);
 	}
+}
 
-	if (dbmode==PUA_DB_ONLY)
+static void find_and_update_dialog(ua_pres_t *dialog, int hash_code, int lexpire, str *contact)
+{
+	ua_pres_t *presentity;
+
+	if (dbmode == PUA_DB_ONLY)
 	{
-		delete_puadb(presentity);
-		free_results_puadb(res);
+		update_dialog_puadb(dialog, lexpire, contact);
 	}
 	else
 	{
-		delete_htable(presentity, hash_code);
+		lock_get(&HashT->p_records[hash_code].lock);
+  		presentity= get_dialog(dialog, hash_code);
+		if (presentity == NULL)
+		{
+			LM_ERR("no record found\n");
+			lock_release(&HashT->p_records[hash_code].lock);
+			return;
+		}
+
+		update_htable(presentity, dialog->desired_expires, lexpire, NULL, hash_code, contact);
 		lock_release(&HashT->p_records[hash_code].lock);
 	}
 }
@@ -283,14 +291,6 @@ void subs_cback_func(struct cell *t, int cb_type, struct tmcb_params *ps)
 	int rt;
 	str contact;
 	int initial_request = 0;
-	db1_res_t *res=NULL;
- 	ua_pres_t dbpres;
-	str pres_uri={0,0}, watcher_uri={0,0}, extra_headers={0,0};
-
-	memset(&dbpres, 0, sizeof(dbpres));
-	dbpres.pres_uri = &pres_uri;
-	dbpres.watcher_uri = &watcher_uri;
-	dbpres.extra_headers = &extra_headers;
 
 	if( ps->param== NULL || *ps->param== NULL )
 	{
@@ -362,8 +362,18 @@ faked_error:
 		goto done;
 	}
 
-	/*if initial request */
+	if(ps->rpl->expires && msg->expires->body.len > 0)
+	{
+		if (!msg->expires->parsed && (parse_expires(msg->expires) < 0))
+		{
+			LM_ERR("cannot parse Expires header\n");
+			goto done;
+		}
+		lexpire = ((exp_body_t*)msg->expires->parsed)->val;
+		LM_DBG("lexpire= %d\n", lexpire);
+	}
 
+	/*if initial request */
 	if(hentity->call_id.s== NULL)
 	{
 		initial_request = 1;
@@ -393,7 +403,20 @@ faked_error:
 		{
 			LM_ERR("no from tag value present\n");
 			goto done;
-		}		
+		}
+
+		hentity->call_id=  msg->callid->body;
+		hentity->from_tag= pfrom->tag_value;
+
+		if(ps->code >= 300 || lexpire == 0)
+		{
+			/* Initial request so dialog is temporary */
+			hentity->to_tag.s = NULL;
+			hentity->to_tag.len = 0;
+			find_and_delete_dialog(hentity, hash_code);
+			goto done;
+		}
+
 		if( msg->to==NULL || msg->to->body.s==NULL)
 		{
 			LM_ERR("cannot parse TO header\n");
@@ -420,183 +443,82 @@ faked_error:
 			LM_ERR("no to tag value present\n");
 			goto done;
 		}
-		hentity->call_id=  msg->callid->body;
 		hentity->to_tag= pto->tag_value;
-		hentity->from_tag= pfrom->tag_value;
-
-		if(ps->code >= 300)
-		{
-			find_and_delete_dialog(hentity, hash_code);
-			goto done;
-		}
-	}
-
-	/* extract the other necesary information for inserting a new record */		
-	if(ps->rpl->expires && msg->expires->body.len > 0)
-	{
-		if (!msg->expires->parsed && (parse_expires(msg->expires) < 0))
-		{
-			LM_ERR("cannot parse Expires header\n");
-			goto done;
-		}
-		lexpire = ((exp_body_t*)msg->expires->parsed)->val;
-		LM_DBG("lexpire= %d\n", lexpire);
-	}		
-
-	if (dbmode==PUA_DB_ONLY)
-	{
-		presentity = get_dialog_puadb(hentity, &dbpres, &res);
-	}
-	else
-	{
-		lock_get(&HashT->p_records[hash_code].lock);
-		presentity= get_dialog(hentity, hash_code);
-		if (presentity == NULL)
-			presentity = get_temporary_dialog(hentity, hash_code);
 	}
 
 	if(ps->code >= 300 )
 	{	/* if an error code and a stored dialog delete it and try to send 
 		   a subscription with type= INSERT_TYPE, else return*/	
 		
-		if(presentity)
-		{
-			subs_info_t subs;
-			hentity->event= presentity->event;
+		subs_info_t subs;
 
-			if (dbmode==PUA_DB_ONLY)
-			{
-				delete_puadb(presentity);
-			}
-			else
-			{
-				delete_htable(presentity, hash_code);
-				lock_release(&HashT->p_records[hash_code].lock);
-			}
+		find_and_delete_dialog(hentity, hash_code);
 
-			/* Redirect if the response 3XX */
-			memset(&subs, 0, sizeof(subs_info_t));
-			subs.pres_uri= hentity->pres_uri; 
-			subs.watcher_uri= hentity->watcher_uri;
-			subs.contact= &hentity->contact;
+		/* Redirect if the response 3XX */
+		memset(&subs, 0, sizeof(subs_info_t));
+		subs.pres_uri= hentity->pres_uri; 
+		subs.watcher_uri= hentity->watcher_uri;
+		subs.contact= &hentity->contact;
 
-			if(hentity->remote_contact.s)
-				subs.remote_target= &hentity->remote_contact;
+		if(hentity->remote_contact.s)
+			subs.remote_target= &hentity->remote_contact;
 
-			if(hentity->desired_expires== 0)
-				subs.expires= -1;
-			else
-			if(hentity->desired_expires< (int)time(NULL))
-				subs.expires= 0;
-			else
-				subs.expires= hentity->desired_expires- (int)time(NULL)+ 3;
-
-			subs.flag= INSERT_TYPE;
-			subs.source_flag= flag;
-			subs.event= hentity->event;
-			subs.id= hentity->id;
-			subs.outbound_proxy= hentity->outbound_proxy;
-			subs.extra_headers= hentity->extra_headers;
-			subs.cb_param= hentity->cb_param;
-		
-			if(send_subscribe(&subs)< 0)
-			{
-				LM_ERR("when trying to send SUBSCRIBE\n");
-				goto done;
-			}
-		}
-		else 
+		if(hentity->desired_expires== 0)
+			subs.expires= -1;
+		else
+		if(hentity->desired_expires< (int)time(NULL))
+			subs.expires= 0;
+		else
+			subs.expires= hentity->desired_expires- (int)time(NULL)+ 3;
+
+		subs.flag= INSERT_TYPE;
+		subs.source_flag= flag;
+		subs.event= hentity->event;
+		subs.id= hentity->id;
+		subs.outbound_proxy= hentity->outbound_proxy;
+		subs.extra_headers= hentity->extra_headers;
+		subs.cb_param= hentity->cb_param;
+	
+		if(send_subscribe(&subs)< 0)
 		{
-			LM_ERR("No dialog found\n");			
-			if (dbmode!=PUA_DB_ONLY)
-				lock_release(&HashT->p_records[hash_code].lock);
+			LM_ERR("when trying to send SUBSCRIBE\n");
+			goto done;
 		}
 		goto done;
 	}
-	/*if a 2XX reply handle the two cases- an existing dialog and a new one*/
-	
+
+	if(lexpire== 0 )
+	{
+		LM_DBG("lexpire= 0 Delete from hash table");
+		find_and_delete_dialog(hentity, hash_code);
+		goto done;
+	}
+
 	/* extract the contact */
 	if(msg->contact== NULL || msg->contact->body.s== NULL)
 	{
 		LM_ERR("no contact header found");
-		if (dbmode!=PUA_DB_ONLY)
-			lock_release(&HashT->p_records[hash_code].lock);
 		goto error;
 	}
 	if( parse_contact(msg->contact) <0 )
 	{
 		LM_ERR(" cannot parse contact header\n");
-		if (dbmode!=PUA_DB_ONLY)
-			lock_release(&HashT->p_records[hash_code].lock);
 		goto error;
 	}
-
 	if(msg->contact->parsed == NULL)
 	{
 		LM_ERR("cannot parse contact header\n");
-		if (dbmode!=PUA_DB_ONLY)
-			lock_release(&HashT->p_records[hash_code].lock);
 		goto error;
 	}
 	contact = ((contact_body_t* )msg->contact->parsed)->contacts->uri;
 
 	if(initial_request == 0)
 	{
-		if(presentity)
-		{
-			if(lexpire== 0 )
-			{
-				LM_DBG("lexpire= 0 Delete from hash table");
-				if (dbmode==PUA_DB_ONLY)
-				{
-					delete_puadb(presentity);
-				}
-				else
-				{
-					delete_htable(presentity, hash_code);
-					lock_release(&HashT->p_records[hash_code].lock);
-				}
-				goto done;
-			}
-			LM_DBG("*** Update expires\n");
-			if (dbmode==PUA_DB_ONLY)
-			{
-				update_puadb( presentity, hentity->desired_expires, lexpire, NULL, &contact );
-			}
-			else
-			{
-				update_htable(presentity, hentity->desired_expires, lexpire, NULL,
-					hash_code, &contact);
-				lock_release(&HashT->p_records[hash_code].lock);
-			}
-			goto done;
-		}
-
-		LM_ERR("Not initial request and no record found\n");
-		if (dbmode!=PUA_DB_ONLY)
-			lock_release(&HashT->p_records[hash_code].lock);
-		goto error;
-	}
-
-	/* if a new dialog -> insert */
-	if(lexpire== 0)
-	{	
-		LM_WARN("expires= 0: no not insert\n");
-		if (dbmode==PUA_DB_ONLY)
-		{
-			delete_puadb(presentity);
-		}
-		else
-		{
-			delete_htable(presentity, hash_code);
-			lock_release(&HashT->p_records[hash_code].lock);
-		}
+		LM_DBG("*** Update expires\n");
+		find_and_update_dialog(hentity, hash_code, lexpire, &contact);
 		goto done;
 	}
 
-	if (dbmode!=PUA_DB_ONLY)
-		lock_release(&HashT->p_records[hash_code].lock);
-
 	if( msg->cseq==NULL || msg->cseq->body.s==NULL)
 	{
 		LM_ERR("cannot parse cseq header\n");
@@ -682,7 +604,6 @@ faked_error:
 		pkg_free(record_route.s);
 	}
 
-	
 	presentity->contact.s= (char*)presentity + size;
 	memcpy(presentity->contact.s, hentity->contact.s, hentity->contact.len);
 	presentity->contact.len= hentity->contact.len;
@@ -696,7 +617,7 @@ faked_error:
 		presentity->id.len= hentity->id.len; 
 		size+= presentity->id.len;
 	}
-	
+
 	if(hentity->extra_headers)
 	{
 		presentity->extra_headers= (str*)((char*)presentity+ size);
@@ -772,7 +693,6 @@ end:
 	}
 
 	free_to_params(&TO);
-	free_results_puadb(res);
 	return;
 }
 
@@ -972,7 +892,7 @@ int send_subscribe(subs_info_t* subs)
 	str* str_hdr= NULL;
 	int ret= 0;
 	unsigned int hash_code=0;
-	ua_pres_t* hentity= NULL, pres;
+	ua_pres_t* hentity= NULL;
 	int expires;
 	int flag;
 	int result;
@@ -1009,21 +929,23 @@ int send_subscribe(subs_info_t* subs)
 
 	/* generation of hash and getting lock moved from here to further down */
 
-	memset(&pres, 0, sizeof(ua_pres_t));
-	pres.pres_uri= subs->pres_uri;
-	pres.watcher_uri= subs->watcher_uri;
-	pres.flag= subs->source_flag;
-	pres.id= subs->id;
-	pres.event= subs->event;
-	if(subs->remote_target)
-		pres.remote_contact= *subs->remote_target;
-
 	if (dbmode==PUA_DB_ONLY)
 	{
-		presentity = search_puadb(&pres, &dbpres, &res);
+		presentity = search_dialog_puadb(subs->id, subs->pres_uri, &dbpres, &res);
 	}
 	else
 	{
+		ua_pres_t pres;
+
+		memset(&pres, 0, sizeof(ua_pres_t));
+		pres.pres_uri = subs->pres_uri;
+		pres.watcher_uri = subs->watcher_uri;
+		pres.flag = subs->source_flag;
+		pres.id = subs->id;
+		pres.event = subs->event;
+		if (subs->remote_target)
+			pres.remote_contact = *subs->remote_target;
+
 		hash_code=core_hash(subs->pres_uri, subs->watcher_uri, HASH_SIZE);
 		lock_get(&HashT->p_records[hash_code].lock);
 		presentity= search_htable(&pres, hash_code);
@@ -1135,8 +1057,8 @@ insert:
 		presentity->id.len = subs->id.len;
 		size += subs->id.len;
 
-		presentity->event = pres.event;
-		presentity->flag = pres.flag;
+		presentity->event = subs->event;
+		presentity->flag = subs->source_flag;
 
 		/* Set the temporary record expiry for 2 * 64T1 seconds from now */
 		presentity->expires= (int)time(NULL) + 64;
@@ -1180,7 +1102,7 @@ insert:
 			{
 				LM_WARN("attempting to un-SUBSCRIBE to temporary (non-established) dialog - skipping and deleting dialog\n");
 				if (dbmode==PUA_DB_ONLY)
-					delete_puadb(presentity);
+					delete_dialog_puadb(presentity);
 				else
 					delete_htable(presentity, hash_code);
 			}