瀏覽代碼

- Support for fetching all data to the client at once
- Implemented db_setopt and db_getopt support for "fetch_all"
command, when set to 1 (default), the client library will
fetch all data to client in one step, this behavior can
be disabled by setting the parameter to 0.

Jan Janak 17 年之前
父節點
當前提交
905f205ded
共有 4 個文件被更改,包括 99 次插入30 次删除
  1. 72 16
      modules/db_mysql/my_cmd.c
  2. 11 0
      modules/db_mysql/my_cmd.h
  3. 1 1
      modules/db_mysql/my_con.h
  4. 15 13
      modules/db_mysql/mysql_mod.c

+ 72 - 16
modules/db_mysql/my_cmd.c

@@ -57,11 +57,10 @@
 #ifdef MYSQL_FAKE_NULL
 
 #define FAKE_NULL_STRING "[~NULL~]"
-static str  FAKE_NULL_STR=STR_STATIC_INIT(FAKE_NULL_STRING);
+static str  FAKE_NULL_STR = STR_STATIC_INIT(FAKE_NULL_STRING);
 
 /* avoid warning: this decimal constant is unsigned only in ISO C90 :-) */
 #define FAKE_NULL_INT (-2147483647 - 1)
-#define STR_EQ(x,y) ((x.len == y.len) && (strncmp(x.s, y.s, x.len) == 0))
 #endif
 
 enum {
@@ -134,9 +133,9 @@ static void my_cmd_free(db_cmd_t* cmd, struct my_cmd* payload)
 }
 
 
-/**
- * Builds DELETE statement where cmd->match specify WHERE clause.
- * @param cmd SQL statement as a result of this function
+/** Builds a DELETE SQL statement.The function builds DELETE statement where
+ * cmd->match specify WHERE clause.  
+ * @param cmd SQL statement as a result of this function 
  * @param cmd input for statement creation
  */
 static int build_delete_cmd(str* sql_cmd, db_cmd_t* cmd)
@@ -702,18 +701,29 @@ static int exec_cmd_safe(db_cmd_t* cmd)
 
 		set_mysql_params(cmd);
 		err = mysql_stmt_execute(mcmd->st);
-		if (err == 0) return 0;
-		else {
-			/* Command execution failed, log a message and try to reconnect */
-			INFO("mysql: libmysql: %d, %s\n", mysql_stmt_errno(mcmd->st),
-				 mysql_stmt_error(mcmd->st));
-			INFO("mysql: Error while executing command on server, trying to reconnect\n");
-			my_con_disconnect(con);
-			if (my_con_connect(con)) {
-				INFO("mysql: Failed to reconnect server\n");
-			} else {
-				INFO("mysql: Successfully reconnected server\n");
+		if (err == 0) {
+			/* The command was executed successfully, now fetch all data
+			 * to the client if it was requested by the user */
+			if (mcmd->flags & MY_FETCH_ALL) {
+				err = mysql_stmt_store_result(mcmd->st);
+				if (err) {
+					INFO("mysql: Error while fetching data to client.\n");
+					goto error;
+				}
 			}
+			return 0;
+		}
+		
+	error:
+		/* Command execution failed, log a message and try to reconnect */
+		INFO("mysql: libmysql: %d, %s\n", mysql_stmt_errno(mcmd->st),
+			 mysql_stmt_error(mcmd->st));
+		INFO("mysql: Error while executing command on server, trying to reconnect\n");
+		my_con_disconnect(con);
+		if (my_con_connect(con)) {
+			INFO("mysql: Failed to reconnect server\n");
+		} else {
+			INFO("mysql: Successfully reconnected server\n");
 		}
 	}
 
@@ -1136,6 +1146,8 @@ int my_cmd(db_cmd_t* cmd)
 		goto error;
 	}
 	memset(res, '\0', sizeof(struct my_cmd));
+	/* Fetch all data to client at once by default */
+	res->flags |= MY_FETCH_ALL;
 	if (db_drv_init(&res->gen, my_cmd_free) < 0) goto error;
 
 	switch(cmd->type) {
@@ -1245,4 +1257,48 @@ int my_cmd_next(db_res_t* res)
 	return 0;
 }
 
+
+int my_getopt(db_cmd_t* cmd, char* optname, va_list ap)
+{
+	struct my_cmd* mcmd;
+	int* val;
+
+	mcmd = (struct my_cmd*)DB_GET_PAYLOAD(cmd);
+
+	if (!strcasecmp("fetch_all", optname)) {
+		val = va_arg(ap, int*);
+		if (val == NULL) {
+			BUG("mysql: NULL pointer passed to 'fetch_all' DB option\n");
+			goto error;
+		}
+		*val = mcmd->flags;
+	} else {
+		return 1;
+	}
+	return 0;
+
+ error:
+	return -1;
+}
+
+
+int my_setopt(db_cmd_t* cmd, char* optname, va_list ap)
+{
+	struct my_cmd* mcmd;
+	int* val;
+
+	mcmd = (struct my_cmd*)DB_GET_PAYLOAD(cmd);
+	if (!strcasecmp("fetch_all", optname)) {
+		val = va_arg(ap, int*);
+		if (val != 0) {
+			mcmd->flags |= MY_FETCH_ALL;
+		} else {
+			mcmd->flags &= ~MY_FETCH_ALL;
+		}
+	} else {
+		return 1;
+	}
+	return 0;
+}
+
 /** @} */

+ 11 - 0
modules/db_mysql/my_cmd.h

@@ -32,6 +32,12 @@
 #include "../../db/db_drv.h"
 #include "../../db/db_cmd.h"
 #include <mysql/mysql.h>
+#include <stdarg.h>
+
+typedef enum my_flags {
+	/** Fetch all data from the server to the client at once */
+	MY_FETCH_ALL = (1 << 0),
+} my_flags_t;
 
 struct my_cmd {
 	db_drv_t gen;
@@ -49,6 +55,7 @@ struct my_cmd {
 	 * the connection was reconnected meanwhile.
 	 */
 	unsigned int last_reset;
+	unsigned int flags; /**< Various flags, mainly used by setopt and getopt */
 };
 
 int my_cmd(db_cmd_t* cmd);
@@ -59,4 +66,8 @@ int my_cmd_first(db_res_t* res);
 
 int my_cmd_next(db_res_t* res);
 
+int my_getopt(db_cmd_t* cmd, char* optname, va_list ap);
+
+int my_setopt(db_cmd_t* cmd, char* optname, va_list ap);
+
 #endif /* _MY_CMD_H */

+ 1 - 1
modules/db_mysql/my_con.h

@@ -36,7 +36,7 @@
 #include <time.h>
 #include <mysql/mysql.h>
 
-enum my_flags {
+enum my_con_flags {
 	MY_CONNECTED = 1
 };
 

+ 15 - 13
modules/db_mysql/mysql_mod.c

@@ -68,19 +68,21 @@ MODULE_VERSION
  * MySQL database module interface
  */
 static cmd_export_t cmds[] = {
-	{"db_ctx",   (cmd_function)NULL,  0, 0, 0},
-	{"db_con",   (cmd_function)my_con,  0, 0, 0},
-	{"db_uri",   (cmd_function)my_uri,  0, 0, 0},
-	{"db_cmd",   (cmd_function)my_cmd,  0, 0, 0},
-	{"db_put",   (cmd_function)my_cmd_exec, 0, 0, 0},
-	{"db_del",   (cmd_function)my_cmd_exec, 0, 0, 0},
-	{"db_get",   (cmd_function)my_cmd_exec, 0, 0, 0},
-	{"db_upd",   (cmd_function)my_cmd_exec, 0, 0, 0},
-	{"db_sql",   (cmd_function)my_cmd_exec, 0, 0, 0},
-	{"db_res",   (cmd_function)my_res,  0, 0, 0},
-	{"db_fld",   (cmd_function)my_fld,  0, 0, 0},
-	{"db_first", (cmd_function)my_cmd_first, 0, 0, 0},
-	{"db_next",  (cmd_function)my_cmd_next,  0, 0, 0},
+	{"db_ctx",    (cmd_function)NULL,         0, 0, 0},
+	{"db_con",    (cmd_function)my_con,       0, 0, 0},
+	{"db_uri",    (cmd_function)my_uri,       0, 0, 0},
+	{"db_cmd",    (cmd_function)my_cmd,       0, 0, 0},
+	{"db_put",    (cmd_function)my_cmd_exec,  0, 0, 0},
+	{"db_del",    (cmd_function)my_cmd_exec,  0, 0, 0},
+	{"db_get",    (cmd_function)my_cmd_exec,  0, 0, 0},
+	{"db_upd",    (cmd_function)my_cmd_exec,  0, 0, 0},
+	{"db_sql",    (cmd_function)my_cmd_exec,  0, 0, 0},
+	{"db_res",    (cmd_function)my_res,       0, 0, 0},
+	{"db_fld",    (cmd_function)my_fld,       0, 0, 0},
+	{"db_first",  (cmd_function)my_cmd_first, 0, 0, 0},
+	{"db_next",   (cmd_function)my_cmd_next,  0, 0, 0},
+	{"db_setopt", (cmd_function)my_setopt,    0, 0, 0},
+	{"db_getopt", (cmd_function)my_getopt,    0, 0, 0},
 	{0, 0, 0, 0, 0}
 };