[sr-dev] git:master: modules_k/sqlops: Move s.sql transformation to sqlops as sql. val and add sql.val.int, sql.val.str

Alex Hermann alex at speakup.nl
Thu Aug 18 18:44:29 CEST 2011


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

Author: Alex Hermann <alex at speakup.nl>
Committer: Alex Hermann <alex at speakup.nl>
Date:   Thu Aug 18 18:17:59 2011 +0200

modules_k/sqlops: Move s.sql transformation to sqlops as sql.val and add sql.val.int, sql.val.str

s.sql was not really a string transformation as it handled null and integers
too. Move it to sqlops as sql.val (it was not yet in a released version) and
add 2 new transformations.

Summarizing:

sql.val: returns a valid SQL value. $null as NULL, int as number, string as
         quoted and escaped string
sql.val.int: returns a non-null integer ($null becomes 0)
sql.val.str: returns a non-null quoted and escaped string. ($null becomes '')

---

 modules_k/pv/pv_trans.c      |   31 +--------
 modules_k/pv/pv_trans.h      |    2 +-
 modules_k/sqlops/sql_trans.c |  159 ++++++++++++++++++++++++++++++++++++++++++
 modules_k/sqlops/sql_trans.h |   34 +++++++++
 modules_k/sqlops/sqlops.c    |   11 +++
 5 files changed, 206 insertions(+), 31 deletions(-)

diff --git a/modules_k/pv/pv_trans.c b/modules_k/pv/pv_trans.c
index 43ff05d..a3175f6 100644
--- a/modules_k/pv/pv_trans.c
+++ b/modules_k/pv/pv_trans.c
@@ -54,7 +54,6 @@
 
 /*! transformation buffer */
 static char _tr_buffer[TR_BUFFER_SIZE];
-static str _tr_null = { "NULL", 4 };
 
 
 /*!
@@ -74,7 +73,7 @@ int tr_eval_string(struct sip_msg *msg, tr_param_t *tp, int subtype,
 	pv_value_t v, w;
 	time_t t;
 
-	if(val==NULL || (val->flags&PV_VAL_NULL && subtype != TR_S_SQL))
+	if(val==NULL || val->flags&PV_VAL_NULL)
 		return -1;
 
 	switch(subtype)
@@ -594,31 +593,6 @@ int tr_eval_string(struct sip_msg *msg, tr_param_t *tp, int subtype,
 			val->rs.s = _tr_buffer;
 			break;
 
-		case TR_S_SQL:
-			if (val->flags&PV_VAL_NULL) {
-				val->flags = PV_VAL_STR;
-				val->rs = _tr_null;
-				break;
-			}
-			if(val->flags&PV_TYPE_INT || !(val->flags&PV_VAL_STR)) {
-				val->rs.s = int2str(val->ri, &val->rs.len);
-				val->flags = PV_VAL_STR;
-				break;
-			}
-			if(val->rs.len>TR_BUFFER_SIZE/2-1) {
-				LM_ERR("escape buffer to short");
-				return -1;
-			}
-			_tr_buffer[0] = '\'';
-			i = escape_common(_tr_buffer+1, val->rs.s, val->rs.len);
-			_tr_buffer[++i] = '\'';
-			_tr_buffer[++i] = '\0';
-			memset(val, 0, sizeof(pv_value_t));
-			val->flags = PV_VAL_STR;
-			val->rs.s = _tr_buffer;
-			val->rs.len = i;
-			break;
-
 		default:
 			LM_ERR("unknown subtype %d\n",
 					subtype);
@@ -1379,9 +1353,6 @@ char* tr_parse_string(str* in, trans_t *t)
 	} else if(name.len==3 && strncasecmp(name.s, "md5", 3)==0) {
 		t->subtype = TR_S_MD5;
 		goto done;
-	} else if(name.len==3 && strncasecmp(name.s, "sql", 3)==0) {
-		t->subtype = TR_S_SQL;
-		goto done;
 	} else if(name.len==7 && strncasecmp(name.s, "tolower", 7)==0) {
 		t->subtype = TR_S_TOLOWER;
 		goto done;
diff --git a/modules_k/pv/pv_trans.h b/modules_k/pv/pv_trans.h
index 2cd2fd0..0938ddc 100644
--- a/modules_k/pv/pv_trans.h
+++ b/modules_k/pv/pv_trans.h
@@ -40,7 +40,7 @@ enum _tr_s_subtype {
 	TR_S_ESCAPECOMMON, TR_S_UNESCAPECOMMON, TR_S_ESCAPEUSER, TR_S_UNESCAPEUSER,
 	TR_S_ESCAPEPARAM, TR_S_UNESCAPEPARAM, TR_S_TOLOWER, TR_S_TOUPPER,
 	TR_S_STRIP, TR_S_STRIPTAIL, TR_S_PREFIXES, TR_S_PREFIXES_QUOT, TR_S_REPLACE,
-	TR_S_TIMEFORMAT, TR_S_SQL
+	TR_S_TIMEFORMAT
 };
 enum _tr_uri_subtype {
 	TR_URI_NONE=0, TR_URI_USER, TR_URI_HOST, TR_URI_PASSWD, TR_URI_PORT,
diff --git a/modules_k/sqlops/sql_trans.c b/modules_k/sqlops/sql_trans.c
new file mode 100644
index 0000000..50ecc06
--- /dev/null
+++ b/modules_k/sqlops/sql_trans.c
@@ -0,0 +1,159 @@
+/**
+ * $Id$
+ *
+ * Copyright (C) 2011 SpeakUp B.V. (alex at speakup.nl)
+ *
+ * This file is part of kamailio, a free SIP server.
+ *
+ * openser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * openser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "../../mem/mem.h"
+#include "../../dprint.h"
+#include "../../trim.h"
+#include "../../lib/kcore/strcommon.h"
+
+#include "sql_trans.h"
+
+#define is_in_str(p, in) (p<in->s+in->len && *p)
+
+#define TR_BUFFER_SIZE 2048
+
+
+static int _tr_eval_sql_val(pv_value_t *val)
+{
+	int i;
+	static char _tr_buffer[TR_BUFFER_SIZE];
+
+	if(val->flags&PV_TYPE_INT || !(val->flags&PV_VAL_STR)) {
+		val->rs.s = int2str(val->ri, &val->rs.len);
+		val->flags = PV_VAL_STR;
+		return 0;
+	}
+	if(val->rs.len>TR_BUFFER_SIZE/2-1) {
+		LM_ERR("escape buffer to short");
+		return -1;
+	}
+	_tr_buffer[0] = '\'';
+	i = escape_common(_tr_buffer+1, val->rs.s, val->rs.len);
+	_tr_buffer[++i] = '\'';
+	_tr_buffer[++i] = '\0';
+	memset(val, 0, sizeof(pv_value_t));
+	val->flags = PV_VAL_STR;
+	val->rs.s = _tr_buffer;
+	val->rs.len = i;
+	return 0;
+}
+
+
+int tr_eval_sql(struct sip_msg *msg, tr_param_t *tp, int subtype,
+		pv_value_t *val)
+{
+	static str _sql_null = { "NULL", 4 };
+	static str _sql_zero = { "0", 1 };
+	static str _sql_empty = { "''", 2 };
+
+	if(val==NULL)
+		return -1;
+	
+	switch(subtype) {
+		case TR_SQL_VAL:
+			if (val->flags&PV_VAL_NULL) {
+				val->flags = PV_VAL_STR;
+				val->rs = _sql_null;
+				return 0;
+			} else {
+				return _tr_eval_sql_val(val);
+			}
+			break;
+
+		case TR_SQL_VAL_INT:
+			if (val->flags&PV_VAL_NULL) {
+				val->flags = PV_VAL_STR;
+				val->rs = _sql_zero;
+				return 0;
+			} else {
+				return _tr_eval_sql_val(val);
+			}
+			break;
+
+		case TR_SQL_VAL_STR:
+			if (val->flags&PV_VAL_NULL) {
+				val->flags = PV_VAL_STR;
+				val->rs = _sql_empty;
+				return 0;
+			} else {
+				return _tr_eval_sql_val(val);
+			}
+			break;
+
+		default:
+			LM_ERR("unknown subtype %d\n",
+					subtype);
+			return -1;
+	}
+	return 0;
+}
+
+
+char* tr_parse_sql(str *in, trans_t *t)
+{
+	char *p;
+	str name;
+
+
+	if(in==NULL || t==NULL)
+		return NULL;
+
+	p = in->s;
+	name.s = in->s;
+	t->type = TR_SQL;
+	t->trf = tr_eval_sql;
+
+	/* find next token */
+	while(is_in_str(p, in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
+	if(*p=='\0') {
+		LM_ERR("unable to find transformation start: %.*s\n", in->len, in->s);
+		return NULL;
+	}
+	name.len = p - name.s;
+	trim(&name);
+
+	if(name.len==3 && strncasecmp(name.s, "val", 3)==0) {
+		t->subtype = TR_SQL_VAL;
+		goto done;
+	}
+	if(name.len==7 && strncasecmp(name.s, "val.int", 7)==0) {
+		t->subtype = TR_SQL_VAL_INT;
+		goto done;
+	}
+	if(name.len==7 && strncasecmp(name.s, "val.str", 7)==0) {
+		t->subtype = TR_SQL_VAL_STR;
+		goto done;
+	}
+
+	LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
+			name.len, name.s, name.len);
+	return NULL;
+done:
+	t->name = name;
+	return p;
+}
+
diff --git a/modules_k/sqlops/sql_trans.h b/modules_k/sqlops/sql_trans.h
new file mode 100644
index 0000000..ec96ded
--- /dev/null
+++ b/modules_k/sqlops/sql_trans.h
@@ -0,0 +1,34 @@
+/**
+ * $Id$
+ *
+ * Copyright (C) 2011 SpeakUp B.V. (alex at speakup.nl)
+ *
+ * This file is part of kamailio, a free SIP server.
+ *
+ * openser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * openser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+       
+#ifndef _SQL_TRANS_H_
+#define _SQL_TRANS_H_
+
+#include "../../pvar.h"
+
+enum _tr_sql_type { TR_SQL_NONE=0, TR_SQL };
+enum _tr_sql_subtype { 
+	TR_SQL_ST_NONE=0, TR_SQL_VAL, TR_SQL_VAL_INT, TR_SQL_VAL_STR };
+
+char* tr_parse_sql(str *in, trans_t *tr);
+
+#endif
diff --git a/modules_k/sqlops/sqlops.c b/modules_k/sqlops/sqlops.c
index 5bb4b2f..0a4526c 100644
--- a/modules_k/sqlops/sqlops.c
+++ b/modules_k/sqlops/sqlops.c
@@ -52,6 +52,7 @@
 #include "../../pvar.h"
 #include "sql_api.h"
 #include "sql_var.h"
+#include "sql_trans.h"
 
 
 MODULE_VERSION
@@ -110,6 +111,11 @@ static param_export_t params[]={
 	{0,0,0}
 };
 
+static tr_export_t mod_trans[] = {
+	{ {"sql", sizeof("sql")-1}, tr_parse_sql },
+	{ { 0, 0 }, 0 }
+};
+
 
 /** module exports */
 struct module_exports exports= {
@@ -127,6 +133,11 @@ struct module_exports exports= {
 	child_init  /* per-child init function */
 };
 
+int mod_register(char *path, int *dlflags, void *p1, void *p2)
+{
+	return register_trans_mod(path, mod_trans);
+}
+
 static int child_init(int rank)
 {
 	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)




More information about the sr-dev mailing list