... | ... |
@@ -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 */ |
... | ... |
@@ -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 |
|