Browse code

- 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 authored on 03/02/2008 19:12:05
Showing 4 changed files
... ...
@@ -57,11 +57,10 @@
57 57
 #ifdef MYSQL_FAKE_NULL
58 58
 
59 59
 #define FAKE_NULL_STRING "[~NULL~]"
60
-static str  FAKE_NULL_STR=STR_STATIC_INIT(FAKE_NULL_STRING);
60
+static str  FAKE_NULL_STR = STR_STATIC_INIT(FAKE_NULL_STRING);
61 61
 
62 62
 /* avoid warning: this decimal constant is unsigned only in ISO C90 :-) */
63 63
 #define FAKE_NULL_INT (-2147483647 - 1)
64
-#define STR_EQ(x,y) ((x.len == y.len) && (strncmp(x.s, y.s, x.len) == 0))
65 64
 #endif
66 65
 
67 66
 enum {
... ...
@@ -134,9 +133,9 @@ static void my_cmd_free(db_cmd_t* cmd, struct my_cmd* payload)
134 133
 }
135 134
 
136 135
 
137
-/**
138
- * Builds DELETE statement where cmd->match specify WHERE clause.
139
- * @param cmd SQL statement as a result of this function
136
+/** Builds a DELETE SQL statement.The function builds DELETE statement where
137
+ * cmd->match specify WHERE clause.  
138
+ * @param cmd SQL statement as a result of this function 
140 139
  * @param cmd input for statement creation
141 140
  */
142 141
 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)
702 701
 
703 702
 		set_mysql_params(cmd);
704 703
 		err = mysql_stmt_execute(mcmd->st);
705
-		if (err == 0) return 0;
706
-		else {
707
-			/* Command execution failed, log a message and try to reconnect */
708
-			INFO("mysql: libmysql: %d, %s\n", mysql_stmt_errno(mcmd->st),
709
-				 mysql_stmt_error(mcmd->st));
710
-			INFO("mysql: Error while executing command on server, trying to reconnect\n");
711
-			my_con_disconnect(con);
712
-			if (my_con_connect(con)) {
713
-				INFO("mysql: Failed to reconnect server\n");
714
-			} else {
715
-				INFO("mysql: Successfully reconnected server\n");
704
+		if (err == 0) {
705
+			/* The command was executed successfully, now fetch all data
706
+			 * to the client if it was requested by the user */
707
+			if (mcmd->flags & MY_FETCH_ALL) {
708
+				err = mysql_stmt_store_result(mcmd->st);
709
+				if (err) {
710
+					INFO("mysql: Error while fetching data to client.\n");
711
+					goto error;
712
+				}
716 713
 			}
714
+			return 0;
715
+		}
716
+		
717
+	error:
718
+		/* Command execution failed, log a message and try to reconnect */
719
+		INFO("mysql: libmysql: %d, %s\n", mysql_stmt_errno(mcmd->st),
720
+			 mysql_stmt_error(mcmd->st));
721
+		INFO("mysql: Error while executing command on server, trying to reconnect\n");
722
+		my_con_disconnect(con);
723
+		if (my_con_connect(con)) {
724
+			INFO("mysql: Failed to reconnect server\n");
725
+		} else {
726
+			INFO("mysql: Successfully reconnected server\n");
717 727
 		}
718 728
 	}
719 729
 
... ...
@@ -1136,6 +1146,8 @@ int my_cmd(db_cmd_t* cmd)
1136 1146
 		goto error;
1137 1147
 	}
1138 1148
 	memset(res, '\0', sizeof(struct my_cmd));
1149
+	/* Fetch all data to client at once by default */
1150
+	res->flags |= MY_FETCH_ALL;
1139 1151
 	if (db_drv_init(&res->gen, my_cmd_free) < 0) goto error;
1140 1152
 
1141 1153
 	switch(cmd->type) {
... ...
@@ -1245,4 +1257,48 @@ int my_cmd_next(db_res_t* res)
1245 1257
 	return 0;
1246 1258
 }
1247 1259
 
1260
+
1261
+int my_getopt(db_cmd_t* cmd, char* optname, va_list ap)
1262
+{
1263
+	struct my_cmd* mcmd;
1264
+	int* val;
1265
+
1266
+	mcmd = (struct my_cmd*)DB_GET_PAYLOAD(cmd);
1267
+
1268
+	if (!strcasecmp("fetch_all", optname)) {
1269
+		val = va_arg(ap, int*);
1270
+		if (val == NULL) {
1271
+			BUG("mysql: NULL pointer passed to 'fetch_all' DB option\n");
1272
+			goto error;
1273
+		}
1274
+		*val = mcmd->flags;
1275
+	} else {
1276
+		return 1;
1277
+	}
1278
+	return 0;
1279
+
1280
+ error:
1281
+	return -1;
1282
+}
1283
+
1284
+
1285
+int my_setopt(db_cmd_t* cmd, char* optname, va_list ap)
1286
+{
1287
+	struct my_cmd* mcmd;
1288
+	int* val;
1289
+
1290
+	mcmd = (struct my_cmd*)DB_GET_PAYLOAD(cmd);
1291
+	if (!strcasecmp("fetch_all", optname)) {
1292
+		val = va_arg(ap, int*);
1293
+		if (val != 0) {
1294
+			mcmd->flags |= MY_FETCH_ALL;
1295
+		} else {
1296
+			mcmd->flags &= ~MY_FETCH_ALL;
1297
+		}
1298
+	} else {
1299
+		return 1;
1300
+	}
1301
+	return 0;
1302
+}
1303
+
1248 1304
 /** @} */
... ...
@@ -32,6 +32,12 @@
32 32
 #include "../../db/db_drv.h"
33 33
 #include "../../db/db_cmd.h"
34 34
 #include <mysql/mysql.h>
35
+#include <stdarg.h>
36
+
37
+typedef enum my_flags {
38
+	/** Fetch all data from the server to the client at once */
39
+	MY_FETCH_ALL = (1 << 0),
40
+} my_flags_t;
35 41
 
36 42
 struct my_cmd {
37 43
 	db_drv_t gen;
... ...
@@ -49,6 +55,7 @@ struct my_cmd {
49 55
 	 * the connection was reconnected meanwhile.
50 56
 	 */
51 57
 	unsigned int last_reset;
58
+	unsigned int flags; /**< Various flags, mainly used by setopt and getopt */
52 59
 };
53 60
 
54 61
 int my_cmd(db_cmd_t* cmd);
... ...
@@ -59,4 +66,8 @@ int my_cmd_first(db_res_t* res);
59 66
 
60 67
 int my_cmd_next(db_res_t* res);
61 68
 
69
+int my_getopt(db_cmd_t* cmd, char* optname, va_list ap);
70
+
71
+int my_setopt(db_cmd_t* cmd, char* optname, va_list ap);
72
+
62 73
 #endif /* _MY_CMD_H */
... ...
@@ -36,7 +36,7 @@
36 36
 #include <time.h>
37 37
 #include <mysql/mysql.h>
38 38
 
39
-enum my_flags {
39
+enum my_con_flags {
40 40
 	MY_CONNECTED = 1
41 41
 };
42 42
 
... ...
@@ -68,19 +68,21 @@ MODULE_VERSION
68 68
  * MySQL database module interface
69 69
  */
70 70
 static cmd_export_t cmds[] = {
71
-	{"db_ctx",   (cmd_function)NULL,  0, 0, 0},
72
-	{"db_con",   (cmd_function)my_con,  0, 0, 0},
73
-	{"db_uri",   (cmd_function)my_uri,  0, 0, 0},
74
-	{"db_cmd",   (cmd_function)my_cmd,  0, 0, 0},
75
-	{"db_put",   (cmd_function)my_cmd_exec, 0, 0, 0},
76
-	{"db_del",   (cmd_function)my_cmd_exec, 0, 0, 0},
77
-	{"db_get",   (cmd_function)my_cmd_exec, 0, 0, 0},
78
-	{"db_upd",   (cmd_function)my_cmd_exec, 0, 0, 0},
79
-	{"db_sql",   (cmd_function)my_cmd_exec, 0, 0, 0},
80
-	{"db_res",   (cmd_function)my_res,  0, 0, 0},
81
-	{"db_fld",   (cmd_function)my_fld,  0, 0, 0},
82
-	{"db_first", (cmd_function)my_cmd_first, 0, 0, 0},
83
-	{"db_next",  (cmd_function)my_cmd_next,  0, 0, 0},
71
+	{"db_ctx",    (cmd_function)NULL,         0, 0, 0},
72
+	{"db_con",    (cmd_function)my_con,       0, 0, 0},
73
+	{"db_uri",    (cmd_function)my_uri,       0, 0, 0},
74
+	{"db_cmd",    (cmd_function)my_cmd,       0, 0, 0},
75
+	{"db_put",    (cmd_function)my_cmd_exec,  0, 0, 0},
76
+	{"db_del",    (cmd_function)my_cmd_exec,  0, 0, 0},
77
+	{"db_get",    (cmd_function)my_cmd_exec,  0, 0, 0},
78
+	{"db_upd",    (cmd_function)my_cmd_exec,  0, 0, 0},
79
+	{"db_sql",    (cmd_function)my_cmd_exec,  0, 0, 0},
80
+	{"db_res",    (cmd_function)my_res,       0, 0, 0},
81
+	{"db_fld",    (cmd_function)my_fld,       0, 0, 0},
82
+	{"db_first",  (cmd_function)my_cmd_first, 0, 0, 0},
83
+	{"db_next",   (cmd_function)my_cmd_next,  0, 0, 0},
84
+	{"db_setopt", (cmd_function)my_setopt,    0, 0, 0},
85
+	{"db_getopt", (cmd_function)my_getopt,    0, 0, 0},
84 86
 	{0, 0, 0, 0, 0}
85 87
 };
86 88