Module: sip-router Branch: 3.2 Commit: 938854019b05f63d91243e0c0ca8bed2c007d635 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=93885401...
Author: pd peter.dunkley@crocodile-rcs.com Committer: pd peter.dunkley@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. (cherry picked from commit 80b8e30b8a8de950354c1e8b510a03ad9ed98992)
---
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");