Переглянути джерело

sqlops: option to start even when connecting to db fails

- new parameter connect_mode: 0 (default) - do not start if connecting
to db fails; 1 - start even if connecting to db fails
- started from GH #1706
Daniel-Constantin Mierla 6 роки тому
батько
коміт
2df43b992b

+ 28 - 4
src/modules/sqlops/sql_api.c

@@ -139,7 +139,7 @@ int pv_get_sqlrows(struct sip_msg *msg,  pv_param_t *param,
 	return pv_get_sintval(msg, param, res, con->dbf.affected_rows(con->dbh));
 }
 
-int sql_connect(void)
+int sql_connect(int mode)
 {
 	sql_con_t *sc;
 	sc = _sql_con_root;
@@ -160,15 +160,39 @@ int sql_connect(void)
 		sc->dbh = sc->dbf.init(&sc->db_url);
 		if (sc->dbh==NULL)
 		{
-			LM_ERR("failed to connect to the database [%.*s]\n",
-					sc->name.len, sc->name.s);
-			return -1;
+			if(mode) {
+				LM_ERR("failed to connect to the database [%.*s]\n",
+						sc->name.len, sc->name.s);
+				return -1;
+			} else {
+				LM_INFO("failed to connect to the database [%.*s] - trying next\n",
+						sc->name.len, sc->name.s);
+			}
 		}
 		sc = sc->next;
 	}
 	return 0;
 }
 
+int sql_reconnect(sql_con_t *sc)
+{
+	if(sc==NULL) {
+		LM_ERR("connection structure not initialized\n");
+		return -1;
+	}
+	if (sc->dbh!=NULL) {
+		/* already connected */
+		return 0;
+	}
+	sc->dbh = sc->dbf.init(&sc->db_url);
+	if (sc->dbh==NULL) {
+		LM_ERR("failed to connect to the database [%.*s]\n",
+					sc->name.len, sc->name.s);
+		return -1;
+	}
+	return 0;
+}
+
 void sql_disconnect(void)
 {
 	sql_con_t *sc;

+ 2 - 2
src/modules/sqlops/sql_api.h

@@ -25,7 +25,6 @@
  * - Module: \ref sqlops
  */
 
-		       
 #ifndef _SQL_API_H_
 #define _SQL_API_H_
 
@@ -68,7 +67,8 @@ typedef struct _sql_con
 
 int sql_parse_param(char *val);
 void sql_destroy(void);
-int sql_connect(void);
+int sql_connect(int mode);
+int sql_reconnect(sql_con_t *sc);
 
 int sql_do_query(sql_con_t *con, str *query, sql_result_t *res);
 int sql_do_query_async(sql_con_t *con, str *query);

+ 55 - 3
src/modules/sqlops/sqlops.c

@@ -58,6 +58,7 @@ MODULE_VERSION
 static int bind_sqlops(sqlops_api_t* api);
 
 /** module functions */
+static int sql_check_connection(sql_con_t*);
 static int sql_query(struct sip_msg*, char*, char*, char*);
 static int sql_query2(struct sip_msg*, char*, char*);
 static int sql_query_async(struct sip_msg*, char*, char*);
@@ -82,6 +83,8 @@ static int sql_res_param(modparam_t type, void* val);
 
 extern int sqlops_tr_buf_size;
 
+static int sqlops_connect_mode = 0;
+
 static pv_export_t mod_pvs[] = {
 	{ {"dbr", sizeof("dbr")-1}, PVT_OTHER, pv_get_dbr, 0,
 		pv_parse_dbr_name, 0, 0, 0 },
@@ -113,6 +116,7 @@ static param_export_t params[]={
 	{"sqlcon",  PARAM_STRING|USE_FUNC_PARAM, (void*)sql_con_param},
 	{"sqlres",  PARAM_STRING|USE_FUNC_PARAM, (void*)sql_res_param},
 	{"tr_buf_size",     PARAM_INT,   &sqlops_tr_buf_size},
+	{"connect_mode",    PARAM_INT,   &sqlops_connect_mode},
 	{0,0,0}
 };
 
@@ -146,9 +150,23 @@ static int mod_init(void)
 
 static int child_init(int rank)
 {
+	int ret;
 	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
 		return 0;
-	return sql_connect();
+
+	ret = sql_connect((sqlops_connect_mode == 1)?1:0);
+
+	LM_DBG("SQL result: %d \n", ret);
+
+	if (ret != 0 && sqlops_connect_mode == 1)
+	{
+		LM_INFO("SQL result: %d but start_without_db_connection enabled - proceed\n",
+				ret);
+		return 0;
+
+	} else {
+		return ret;
+	}
 }
 
 /**
@@ -201,14 +219,36 @@ error:
 	return -1;
 }
 
+static int sql_check_connection(sql_con_t *dbl)
+{
+	if (dbl->dbh != NULL) {
+		return 0;
+	}
+
+	if(sqlops_connect_mode != 1) {
+		LM_CRIT("no database handle with reconnect disabled\n");
+		return -1;
+	}
+
+    LM_DBG("try to establish SQL connection\n");
+	if(sql_reconnect(dbl)<0) {
+		LM_ERR("failed to connect to database\n");
+		return -1;
+	}
+	return 0;
+}
+
 /**
  *
  */
 static int sql_query(struct sip_msg *msg, char *dbl, char *query, char *res)
 {
 	str sq;
-	if(pv_printf_s(msg, (pv_elem_t*)query, &sq)!=0)
-	{
+	if(sql_check_connection((sql_con_t*)dbl)<0) {
+		LM_ERR("invalid connection to database");
+		return -2;
+	}
+	if(pv_printf_s(msg, (pv_elem_t*)query, &sq)!=0) {
 		LM_ERR("cannot print the sql query\n");
 		return -1;
 	}
@@ -223,6 +263,10 @@ static int sql_query2(struct sip_msg *msg, char *dbl, char *query)
 static int sql_query_async(struct sip_msg *msg, char *dbl, char *query)
 {
 	str sq;
+	if(sql_check_connection((sql_con_t*)dbl)<0) {
+		LM_ERR("invalid connection to database");
+		return -2;
+	}
 	if(pv_printf_s(msg, (pv_elem_t*)query, &sq)!=0)
 	{
 		LM_ERR("cannot print the sql query\n");
@@ -238,6 +282,10 @@ static int sql_query_async(struct sip_msg *msg, char *dbl, char *query)
  */
 static int sql_xquery(struct sip_msg *msg, char *dbl, char *query, char *res)
 {
+	if(sql_check_connection((sql_con_t*)dbl)<0) {
+		LM_ERR("invalid connection to database");
+		return -2;
+	}
 	return sql_do_xquery(msg, (sql_con_t*)dbl, (pv_elem_t*)query, (pv_elem_t*)res);
 }
 #endif
@@ -247,6 +295,10 @@ static int sql_xquery(struct sip_msg *msg, char *dbl, char *query, char *res)
  */
 static int sql_pvquery(struct sip_msg *msg, char *dbl, char *query, char *res)
 {
+	if(sql_check_connection((sql_con_t*)dbl)<0) {
+		LM_ERR("invalid connection to database");
+		return -2;
+	}
 	return sql_do_pvquery(msg, (sql_con_t*)dbl, (pv_elem_t*)query, (pvname_list_t*)res);
 }