ソースを参照

- 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
 #ifdef MYSQL_FAKE_NULL
 
 
 #define FAKE_NULL_STRING "[~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 :-) */
 /* avoid warning: this decimal constant is unsigned only in ISO C90 :-) */
 #define FAKE_NULL_INT (-2147483647 - 1)
 #define FAKE_NULL_INT (-2147483647 - 1)
-#define STR_EQ(x,y) ((x.len == y.len) && (strncmp(x.s, y.s, x.len) == 0))
 #endif
 #endif
 
 
 enum {
 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
  * @param cmd input for statement creation
  */
  */
 static int build_delete_cmd(str* sql_cmd, db_cmd_t* cmd)
 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);
 		set_mysql_params(cmd);
 		err = mysql_stmt_execute(mcmd->st);
 		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;
 		goto error;
 	}
 	}
 	memset(res, '\0', sizeof(struct my_cmd));
 	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;
 	if (db_drv_init(&res->gen, my_cmd_free) < 0) goto error;
 
 
 	switch(cmd->type) {
 	switch(cmd->type) {
@@ -1245,4 +1257,48 @@ int my_cmd_next(db_res_t* res)
 	return 0;
 	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_drv.h"
 #include "../../db/db_cmd.h"
 #include "../../db/db_cmd.h"
 #include <mysql/mysql.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 {
 struct my_cmd {
 	db_drv_t gen;
 	db_drv_t gen;
@@ -49,6 +55,7 @@ struct my_cmd {
 	 * the connection was reconnected meanwhile.
 	 * the connection was reconnected meanwhile.
 	 */
 	 */
 	unsigned int last_reset;
 	unsigned int last_reset;
+	unsigned int flags; /**< Various flags, mainly used by setopt and getopt */
 };
 };
 
 
 int my_cmd(db_cmd_t* cmd);
 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_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 */
 #endif /* _MY_CMD_H */

+ 1 - 1
modules/db_mysql/my_con.h

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

+ 15 - 13
modules/db_mysql/mysql_mod.c

@@ -68,19 +68,21 @@ MODULE_VERSION
  * MySQL database module interface
  * MySQL database module interface
  */
  */
 static cmd_export_t cmds[] = {
 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}
 	{0, 0, 0, 0, 0}
 };
 };