[sr-dev] git:master: modules_k/xcap_server: Changed the XCAP server so that existing documents are updated instead of deleted and inserted

Peter Dunkley peter.dunkley at crocodile-rcs.com
Thu Dec 8 23:08:42 CET 2011


Module: sip-router
Branch: master
Commit: 80b8e30b8a8de950354c1e8b510a03ad9ed98992
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=80b8e30b8a8de950354c1e8b510a03ad9ed98992

Author: pd <peter.dunkley at crocodile-rcs.com>
Committer: pd <peter.dunkley at crocodile-rcs.com>
Date:   Thu Dec  8 21:23:12 2011 +0000

modules_k/xcap_server: Changed the XCAP server so that existing documents are updated instead of deleted and inserted

- Affects XCAP PUT and XCAP partial DELETE
- Some RLS clients send multiple HTTP updates in very close succession.  One
  client has even been observed to upload an identical document several times
  in a row.
- I use rls_update_subs() when any resource-list related document is uploaded.
  With Kamailio being multi-process and the client re-uploading an indentical
  document several times with no time between I was frequently hitting the
  window where rls_update_subs() was called after the DB delete for the second
  upload but before the insert happened.
- Now the DB put operation checks for the presence of a document and does an
  insert only if the document does not exist.  It does an update if the
  document does exist.

---

 modules_k/xcap_server/xcap_server.c |  134 +++++++++++++++++++++-------------
 1 files changed, 83 insertions(+), 51 deletions(-)

diff --git a/modules_k/xcap_server/xcap_server.c b/modules_k/xcap_server/xcap_server.c
index 66dac1f..9580e53 100644
--- a/modules_k/xcap_server/xcap_server.c
+++ b/modules_k/xcap_server/xcap_server.c
@@ -88,6 +88,7 @@ static str xcaps_buf = {0, 8192};
 #define XCAPS_ETAG_SIZE	128
 static char xcaps_etag_buf[XCAPS_ETAG_SIZE];
 
+static str str_id_col = str_init("id");
 static str str_source_col = str_init("source");
 static str str_doc_col = str_init("doc");
 static str str_etag_col = str_init("etag");
@@ -331,9 +332,10 @@ int xcaps_xpath_hack(str *buf, int type)
 static int xcaps_put_db(str* user, str *domain, xcap_uri_t *xuri, str *etag,
 		str* doc)
 {
-	db_key_t qcols[9];
-	db_val_t qvals[9];
-	int ncols = 0;
+	db_key_t qcols[9], rcols[2], ucols[5];
+	db_val_t qvals[9], uvals[5];
+	db1_res_t *res = NULL;
+	int ncols = 0, num_ucols = 0, nrows = 0;
 
 	if(xcaps_check_doc_validity(doc)<0)
 	{
@@ -341,7 +343,6 @@ static int xcaps_put_db(str* user, str *domain, xcap_uri_t *xuri, str *etag,
 		goto error;
 	}
 
-	/* insert in xcap table*/
 	qcols[ncols] = &str_username_col;
 	qvals[ncols].type = DB1_STR;
 	qvals[ncols].nul = 0;
@@ -360,35 +361,13 @@ static int xcaps_put_db(str* user, str *domain, xcap_uri_t *xuri, str *etag,
 	qvals[ncols].val.int_val= xuri->type;
 	ncols++;
 
-	qcols[ncols] = &str_doc_col;
-	qvals[ncols].type = DB1_BLOB;
-	qvals[ncols].nul = 0;
-	qvals[ncols].val.str_val= *doc;
-	ncols++;
-
-	qcols[ncols] = &str_etag_col;
-	qvals[ncols].type = DB1_STR;
-	qvals[ncols].nul = 0;
-	qvals[ncols].val.str_val= *etag;
-	ncols++;
-
-	qcols[ncols] = &str_source_col;
-	qvals[ncols].type = DB1_INT;
-	qvals[ncols].nul = 0;
-	qvals[ncols].val.int_val = 0;
-	ncols++;
-
 	qcols[ncols] = &str_doc_uri_col;
 	qvals[ncols].type = DB1_STR;
 	qvals[ncols].nul = 0;
 	qvals[ncols].val.str_val= xuri->adoc;
 	ncols++;
 
-	qcols[ncols] = &str_port_col;
-	qvals[ncols].type = DB1_INT;
-	qvals[ncols].nul = 0;
-	qvals[ncols].val.int_val= 0;
-	ncols++;
+	rcols[0] = &str_id_col;
 
 	if (xcaps_dbf.use_table(xcaps_db, &xcaps_db_table) < 0) 
 	{
@@ -396,10 +375,83 @@ static int xcaps_put_db(str* user, str *domain, xcap_uri_t *xuri, str *etag,
 				xcaps_db_table.s);
 		goto error;
 	}
-	
-	if(xcaps_dbf.insert(xcaps_db, qcols, qvals, ncols)< 0)
+
+	if (xcaps_dbf.query(xcaps_db, qcols, 0, qvals, rcols, ncols, 1, 0, &res) < 0)
+	{
+		LM_ERR("in sql query\n");
+		goto error;
+	}
+
+	nrows = RES_ROW_N(res);
+	xcaps_dbf.free_result(xcaps_db, res);
+
+	if (nrows == 0)
+	{
+		qcols[ncols] = &str_doc_col;
+		qvals[ncols].type = DB1_BLOB;
+		qvals[ncols].nul = 0;
+		qvals[ncols].val.str_val= *doc;
+		ncols++;
+
+		qcols[ncols] = &str_etag_col;
+		qvals[ncols].type = DB1_STR;
+		qvals[ncols].nul = 0;
+		qvals[ncols].val.str_val= *etag;
+		ncols++;
+
+		qcols[ncols] = &str_source_col;
+		qvals[ncols].type = DB1_INT;
+		qvals[ncols].nul = 0;
+		qvals[ncols].val.int_val = 0;
+		ncols++;
+
+		qcols[ncols] = &str_port_col;
+		qvals[ncols].type = DB1_INT;
+		qvals[ncols].nul = 0;
+		qvals[ncols].val.int_val = 0;
+		ncols++;
+
+		if(xcaps_dbf.insert(xcaps_db, qcols, qvals, ncols)< 0)
+		{
+			LM_ERR("in sql insert\n");
+			goto error;
+		}
+	}
+	else if (nrows == 1)
+	{
+		ucols[num_ucols] = &str_doc_col;
+		uvals[num_ucols].type = DB1_BLOB;
+		uvals[num_ucols].nul = 0;
+		uvals[num_ucols].val.str_val= *doc;
+		num_ucols++;
+
+		ucols[num_ucols] = &str_etag_col;
+		uvals[num_ucols].type = DB1_STR;
+		uvals[num_ucols].nul = 0;
+		uvals[num_ucols].val.str_val= *etag;
+		num_ucols++;
+
+		ucols[num_ucols] = &str_source_col;
+		uvals[num_ucols].type = DB1_INT;
+		uvals[num_ucols].nul = 0;
+		uvals[num_ucols].val.int_val = 0;
+		num_ucols++;
+
+		ucols[num_ucols] = &str_port_col;
+		uvals[num_ucols].type = DB1_INT;
+		uvals[num_ucols].nul = 0;
+		uvals[num_ucols].val.int_val = 0;
+		num_ucols++;
+
+		if (xcaps_dbf.update(xcaps_db, qcols, 0, qvals, ucols, uvals, ncols, num_ucols) < 0)
+		{
+			LM_ERR("in sql update\n");
+			goto error;
+		}
+	}
+	else
 	{
-		LM_ERR("in sql insert\n");
+		LM_ERR("found %d copies of the same document in XCAP Server\n", nrows);
 		goto error;
 	}
 
@@ -518,18 +570,8 @@ static int w_xcaps_put(sip_msg_t* msg, char* puri, char* ppath,
 		return -2;
 	}
 
-	if(xuri.nss==NULL || xuri.node.len<=0)
+	if(xuri.nss!=NULL && xuri.node.len>0)
 	{
-		/* full document upload
-		 *   - fetch and then delete is too expensive if record in db
-		 *   - just try to delete
-		 */
-		if(xcaps_del_db(&turi.user, &turi.host, &xuri)<0)
-		{
-			LM_ERR("could not delete document\n");
-			goto error;
-		}
-	} else {
 		/* partial document upload
 		 *   - fetch, update, delete and store
 		 */
@@ -560,11 +602,6 @@ static int w_xcaps_put(sip_msg_t* msg, char* puri, char* ppath,
 			LM_ERR("could not hack xcap document\n");
 			goto error;
 		}
-		if(xcaps_del_db(&turi.user, &turi.host, &xuri)<0)
-		{
-			LM_ERR("could not delete document\n");
-			goto error;
-		}
 	}
 
 	if(xcaps_generate_etag_hdr(&etag_hdr)<0)
@@ -1077,11 +1114,6 @@ static int w_xcaps_del(sip_msg_t* msg, char* puri, char* ppath)
 			LM_ERR("could not hack xcap document\n");
 			goto error;
 		}
-		if(xcaps_del_db(&turi.user, &turi.host, &xuri)<0)
-		{
-			LM_ERR("could not delete document\n");
-			goto error;
-		}
 		if(xcaps_generate_etag_hdr(&etag_hdr)<0)
 		{
 			LM_ERR("could not generate etag\n");




More information about the sr-dev mailing list