Просмотр исходного кода

sqlops: exported sql functions via module API structure

- new module parameter sqlres to be able to declare DB results IDs
Daniel-Constantin Mierla 15 лет назад
Родитель
Сommit
576ed7b991
3 измененных файлов с 316 добавлено и 27 удалено
  1. 182 20
      modules_k/sqlops/sql_api.c
  2. 57 2
      modules_k/sqlops/sql_api.h
  3. 77 5
      modules_k/sqlops/sqlops.c

+ 182 - 20
modules_k/sqlops/sql_api.c

@@ -194,25 +194,19 @@ void sql_reset_result(sql_result_t *res)
 	res->ncols = 0;
 }
 
-int sql_do_query(struct sip_msg *msg, sql_con_t *con, pv_elem_t *query,
-		sql_result_t *res)
+int sql_do_query(sql_con_t *con, str *query, sql_result_t *res)
 {
 	db1_res_t* db_res = NULL;
 	int i, j;
-	str sq;
+	str sv;
 
-	if(msg==NULL || query==NULL)
+	if(query==NULL)
 	{
 		LM_ERR("bad parameters\n");
 		return -1;
 	}
 	sql_reset_result(res);
-	if(pv_printf_s(msg, query, &sq)!=0)
-	{
-		LM_ERR("cannot print the sql query\n");
-		return -1;
-	}
-	if(con->dbf.raw_query(con->dbh, &sq, &db_res)!=0)
+	if(con->dbf.raw_query(con->dbh, query, &db_res)!=0)
 	{
 		LM_ERR("cannot do the query\n");
 		return -1;
@@ -276,26 +270,28 @@ int sql_do_query(struct sip_msg *msg, sql_con_t *con, pv_elem_t *query,
 				res->vals[i][j].flags = PV_VAL_NULL;
 				continue;
 			}
+			sv.s = NULL;
+			sv.len = 0;
 			switch(RES_ROWS(db_res)[i].values[j].type)
 			{
 				case DB1_STRING:
 					res->vals[i][j].flags = PV_VAL_STR;
-					sq.s=
+					sv.s=
 						(char*)RES_ROWS(db_res)[i].values[j].val.string_val;
-					sq.len=strlen(sq.s);
+					sv.len=strlen(sv.s);
 				break;
 				case DB1_STR:
 					res->vals[i][j].flags = PV_VAL_STR;
-					sq.len=
+					sv.len=
 						RES_ROWS(db_res)[i].values[j].val.str_val.len;
-					sq.s=
+					sv.s=
 						(char*)RES_ROWS(db_res)[i].values[j].val.str_val.s;
 				break;
 				case DB1_BLOB:
 					res->vals[i][j].flags = PV_VAL_STR;
-					sq.len=
+					sv.len=
 						RES_ROWS(db_res)[i].values[j].val.blob_val.len;
-					sq.s=
+					sv.s=
 						(char*)RES_ROWS(db_res)[i].values[j].val.blob_val.s;
 				break;
 				case DB1_INT:
@@ -318,20 +314,20 @@ int sql_do_query(struct sip_msg *msg, sql_con_t *con, pv_elem_t *query,
 			}
 			if(res->vals[i][j].flags == PV_VAL_STR)
 			{
-				if(sq.len==0)
+				if(sv.len==0)
 				{
 					res->vals[i][j].value.s = _sql_empty_str;
 					continue;
 				}
 				res->vals[i][j].value.s.s 
-					= (char*)pkg_malloc(sq.len*sizeof(char));
+					= (char*)pkg_malloc(sv.len*sizeof(char));
 				if(res->vals[i][j].value.s.s==NULL)
 				{
 					LM_ERR("no more memory\n");
 					goto error;
 				}
-				memcpy(res->vals[i][j].value.s.s, sq.s, sq.len);
-				res->vals[i][j].value.s.len = sq.len;
+				memcpy(res->vals[i][j].value.s.s, sv.s, sv.len);
+				res->vals[i][j].value.s.len = sv.len;
 			}
 		}
 	}
@@ -412,3 +408,169 @@ void sql_destroy(void)
 		r = r0;
 	}
 }
+
+/**
+ *
+ */
+int sqlops_do_query(str *scon, str *squery, str *sres)
+{
+	sql_con_t *con = NULL;
+	sql_result_t *res = NULL;
+
+	con = sql_get_connection(scon);
+	if(con==NULL)
+	{
+		LM_ERR("invalid connection [%.*s]\n", scon->len, scon->s);
+		goto error;
+	}
+	res = sql_get_result(sres);
+	if(res==NULL)
+	{
+		LM_ERR("invalid result [%.*s]\n", sres->len, sres->s);
+		goto error;
+	}
+	if(sql_do_query(con, squery, res)<0)
+		goto error;
+
+	return 0;
+error:
+	return -1;
+}
+
+/**
+ *
+ */
+int sqlops_get_value(str *sres, int i, int j, sql_val_t *val)
+{
+	sql_result_t *res = NULL;
+
+	res = sql_get_result(sres);
+	if(res==NULL)
+	{
+		LM_ERR("invalid result [%.*s]\n", sres->len, sres->s);
+		goto error;
+	}
+	if(i>=res->nrows)
+	{
+		LM_ERR("row index out of bounds [%d/%d]\n", i, res->nrows);
+		goto error;
+	}
+	if(i>=res->ncols)
+	{
+		LM_ERR("column index out of bounds [%d/%d]\n", j, res->ncols);
+		goto error;
+	}
+	val = &res->vals[i][j];
+
+	return 0;
+error:
+	return -1;
+}
+
+/**
+ *
+ */
+int sqlops_is_null(str *sres, int i, int j)
+{
+	sql_result_t *res = NULL;
+
+	res = sql_get_result(sres);
+	if(res==NULL)
+	{
+		LM_ERR("invalid result [%.*s]\n", sres->len, sres->s);
+		goto error;
+	}
+	if(i>=res->nrows)
+	{
+		LM_ERR("row index out of bounds [%d/%d]\n", i, res->nrows);
+		goto error;
+	}
+	if(i>=res->ncols)
+	{
+		LM_ERR("column index out of bounds [%d/%d]\n", j, res->ncols);
+		goto error;
+	}
+	if(res->vals[i][j].flags&PV_VAL_NULL)
+		return 1;
+	return 0;
+error:
+	return -1;
+}
+
+/**
+ *
+ */
+int sqlops_get_column(str *sres, int i, str *col)
+{
+	sql_result_t *res = NULL;
+
+	res = sql_get_result(sres);
+	if(res==NULL)
+	{
+		LM_ERR("invalid result [%.*s]\n", sres->len, sres->s);
+		goto error;
+	}
+	if(i>=res->ncols)
+	{
+		LM_ERR("column index out of bounds [%d/%d]\n", i, res->ncols);
+		goto error;
+	}
+	col = &res->cols[i].name;
+	return 0;
+error:
+	return -1;
+}
+
+/**
+ *
+ */
+int sqlops_num_columns(str *sres)
+{
+	sql_result_t *res = NULL;
+
+	res = sql_get_result(sres);
+	if(res==NULL)
+	{
+		LM_ERR("invalid result [%.*s]\n", sres->len, sres->s);
+		goto error;
+	}
+	return res->ncols;
+error:
+	return -1;
+}
+
+/**
+ *
+ */
+int sqlops_num_rows(str *sres)
+{
+	sql_result_t *res = NULL;
+
+	res = sql_get_result(sres);
+	if(res==NULL)
+	{
+		LM_ERR("invalid result [%.*s]\n", sres->len, sres->s);
+		goto error;
+	}
+	return res->nrows;
+error:
+	return -1;
+}
+
+/**
+ *
+ */
+void sqlops_reset_result(str *sres)
+{
+	sql_result_t *res = NULL;
+
+	res = sql_get_result(sres);
+	if(res==NULL)
+	{
+		LM_ERR("invalid result [%.*s]\n", sres->len, sres->s);
+		return;
+	}
+	sql_reset_result(res);
+
+	return;
+}

+ 57 - 2
modules_k/sqlops/sql_api.h

@@ -31,6 +31,7 @@
 #ifndef _SQL_API_H_
 #define _SQL_API_H_
 
+#include "../../sr_module.h"
 #include "../../lib/srdb1/db.h"
 #include "../../pvar.h"
 
@@ -70,11 +71,65 @@ typedef struct _sql_con
 int sql_parse_param(char *val);
 void sql_destroy(void);
 int sql_connect(void);
-int sql_do_query(struct sip_msg *msg, sql_con_t *con, pv_elem_t *query,
-		sql_result_t *res);
+
+int sql_do_query(sql_con_t *con, str *query, sql_result_t *res);
 sql_con_t* sql_get_connection(str *name);
 sql_result_t* sql_get_result(str *name);
 
 void sql_reset_result(sql_result_t *res);
 
+typedef int (*sqlops_do_query_f)(str *scon, str *squery, str *sres);
+int sqlops_do_query(str *scon, str *squery, str *sres);
+
+typedef int (*sqlops_get_value_f)(str *sres, int i, int j, sql_val_t *val);
+int sqlops_get_value(str *sres, int i, int j, sql_val_t *val);
+
+typedef int (*sqlops_is_null_f)(str *sres, int i, int j);
+int sqlops_is_null(str *res, int i, int j);
+
+typedef int (*sqlops_get_column_f)(str *sres, int i, str *col);
+int sqlops_get_column(str *sres, int i, str *name);
+
+typedef int (*sqlops_num_columns_f)(str *sres);
+int sqlops_num_columns(str *sres);
+
+typedef int (*sqlops_num_rows_f)(str *sres);
+int sqlops_num_rows(str *sres);
+
+typedef void (*sqlops_reset_result_f)(str *sres);
+void sqlops_reset_result(str *sres);
+
+typedef struct sqlops_api {
+	sqlops_do_query_f query;
+	sqlops_get_value_f value;
+	sqlops_is_null_f is_null;
+	sqlops_get_column_f column;
+	sqlops_reset_result_f reset;
+	sqlops_num_rows_f nrows;
+	sqlops_num_columns_f ncols;
+} sqlops_api_t;
+
+typedef int (*bind_sqlops_f)(sqlops_api_t* api);
+
+/**
+ * @brief Load the SQLOps API
+ */
+static inline int sqlops_load_api(sqlops_api_t *sqb)
+{
+	bind_sqlops_f bindsqlops;
+
+	bindsqlops = (bind_sqlops_f)find_export("bind_sqlops", 0, 0);
+	if ( bindsqlops == 0) {
+		LM_ERR("cannot find bind_sqlops\n");
+		return -1;
+	}
+	if (bindsqlops(sqb)==-1)
+	{
+		LM_ERR("cannot bind sqlops api\n");
+		return -1;
+	}
+	return 0;
+}
+
+
 #endif

+ 77 - 5
modules_k/sqlops/sqlops.c

@@ -56,6 +56,8 @@
 
 MODULE_VERSION
 
+static int bind_sqlops(sqlops_api_t* api);
+
 /** module functions */
 static int sql_query(struct sip_msg*, char*, char*, char*);
 static int sql_rfree(struct sip_msg*, char*, char*);
@@ -65,7 +67,8 @@ static void destroy(void);
 static int fixup_sql_query(void** param, int param_no);
 static int fixup_sql_rfree(void** param, int param_no);
 
-static int sql_param(modparam_t type, void* val);
+static int sql_con_param(modparam_t type, void* val);
+static int sql_res_param(modparam_t type, void* val);
 
 static pv_export_t mod_pvs[] = {
 	{ {"dbr", sizeof("dbr")-1}, PVT_OTHER, pv_get_dbr, 0,
@@ -80,11 +83,13 @@ static cmd_export_t cmds[]={
 	{"sql_result_free",  (cmd_function)sql_rfree,  1, fixup_sql_rfree, 0, 
 		REQUEST_ROUTE | FAILURE_ROUTE |
 		ONREPLY_ROUTE | BRANCH_ROUTE | LOCAL_ROUTE},
+	{"bind_sqlops", (cmd_function)bind_sqlops, 0, 0, 0, 0},
 	{0,0,0,0,0,0}
 };
 
 static param_export_t params[]={
-	{"sqlcon",  STR_PARAM|USE_FUNC_PARAM, (void*)sql_param},
+	{"sqlcon",  STR_PARAM|USE_FUNC_PARAM, (void*)sql_con_param},
+	{"sqlres",  STR_PARAM|USE_FUNC_PARAM, (void*)sql_res_param},
 	{0,0,0}
 };
 
@@ -120,7 +125,10 @@ static void destroy(void)
 	sql_destroy();
 }
 
-int sql_param(modparam_t type, void *val)
+/**
+ * parse sqlcon module parameter
+ */
+int sql_con_param(modparam_t type, void *val)
 {
 	if(val==NULL)
 		goto error;
@@ -131,18 +139,60 @@ error:
 
 }
 
+/**
+ * parse sqlres module parameter
+ */
+int sql_res_param(modparam_t type, void *val)
+{
+	sql_result_t *res = NULL;
+	str s;
+
+	if(val==NULL)
+	{
+		LM_ERR("invalid parameter");
+		goto error;
+	}
+
+	s.s = (char*)val;
+	s.len = strlen(s.s);
+
+	res = sql_get_result(&s);
+	if(res==NULL)
+	{
+		LM_ERR("invalid result [%s]\n", s.s);
+		goto error;
+	}
+	return 0;
+error:
+	return -1;
+}
+
+/**
+ *
+ */
 static int sql_query(struct sip_msg *msg, char *dbl, char *query, char *res)
 {
-	return sql_do_query(msg, (sql_con_t*)dbl, (pv_elem_t*)query,
-			(sql_result_t*)res);
+	str sq;
+	if(pv_printf_s(msg, (pv_elem_t*)query, &sq)!=0)
+	{
+		LM_ERR("cannot print the sql query\n");
+		return -1;
+	}
+	return sql_do_query((sql_con_t*)dbl, &sq, (sql_result_t*)res);
 }
 
+/**
+ *
+ */
 static int sql_rfree(struct sip_msg *msg, char *res, char *s2)
 {
 	sql_reset_result((sql_result_t*)res);
 	return 1;
 }
 
+/**
+ *
+ */
 static int fixup_sql_query(void** param, int param_no)
 {
 	sql_con_t *con = NULL;
@@ -180,6 +230,9 @@ static int fixup_sql_query(void** param, int param_no)
 	return 0;
 }
 
+/**
+ *
+ */
 static int fixup_sql_rfree(void** param, int param_no)
 {
 	sql_result_t *res = NULL;
@@ -200,3 +253,22 @@ static int fixup_sql_rfree(void** param, int param_no)
 	return 0;
 }
 
+/**
+ * @brief bind functions to SQLOPS API structure
+ */
+static int bind_sqlops(sqlops_api_t* api)
+{
+	if (!api) {
+		ERR("Invalid parameter value\n");
+		return -1;
+	}
+	api->query = sqlops_do_query;
+	api->value = sqlops_get_value;
+	api->is_null = sqlops_is_null;
+	api->column  = sqlops_get_column;
+	api->reset   = sqlops_reset_result;
+	api->nrows   = sqlops_num_rows;
+	api->ncols   = sqlops_num_columns;
+
+	return 0;
+}