From 52aa7299f2c3a9f9e80b366ca9068a6edf3b9bab Mon Sep 17 00:00:00 2001 From: Christophe Genevey Metat Date: Tue, 24 May 2016 16:16:01 +0000 Subject: [PATCH] fix result and query helper --- src/include/gnunet_my_lib.h | 86 ++++++++++++ src/my/Makefile.am | 18 ++- src/my/my.c | 4 +- src/my/my_result_helper.c | 263 ++++++++++++++++++++++++++++-------- 4 files changed, 314 insertions(+), 57 deletions(-) diff --git a/src/include/gnunet_my_lib.h b/src/include/gnunet_my_lib.h index 2a7df1ed6..6931ddcbd 100644 --- a/src/include/gnunet_my_lib.h +++ b/src/include/gnunet_my_lib.h @@ -299,10 +299,96 @@ GNUNET_MY_query_param_uint64 (const uint64_t *x); */ #define GNUNET_MY_result_spec_auto_from_type(dst) GNUNET_MY_result_spec_fixed_size ((dst), sizeof (*(dst))) + /** * FIXME. * */ + + /** + * Variable-size result expected + * + * @param[out] dst where to store the result, allocated + * @param[out] sptr where to store the size of @a dst + * @return array entru for the result specification to use + */ +struct GNUNET_MY_ResultSpec +GNUNET_MY_result_spec_variable_size (void **dst, + size_t *ptr_size); +/** + * RSA public key expected + * + * @param name name of the field in the table + * @param[out] rsa where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_MY_ResultSpec +GNUNET_MY_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa); + +/** + * RSA signature expected. + * + * @param[out] sig where to store the result; + * @return array entry for the result specification to use + */ +struct GNUNET_MY_ResultSpec +GNUNET_MY_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig); + +/** + * 0- terminated string exprected. + * + * @param[out] dst where to store the result, allocated + * @return array entry for the result specification to use + */ +struct GNUNET_MY_ResultSpec +GNUNET_MY_result_spec_string (char **dst); + +/** + * Absolute time expected + * + * @param name name of the field in the table + * @param[out] at where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_MY_ResultSpec +GNUNET_MY_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at); + +/** + * Absolute time in network byte order expected + * + * @param[out] at where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_MY_ResultSpec +GNUNET_MY_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at); + +/** + * uint16_t expected + * + * @param[out] u16 where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_MY_ResultSpec +GNUNET_MY_result_spec_uint16 (uint16_t *u16); + +/** + * uint32_t expected + * + * @param[out] u32 where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_MY_ResultSpec +GNUNET_MY_result_spec_uint32 (uint32_t *u32); + +/** + * uint64_t expected. + * + * @param[out] u64 where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_MY_ResultSpec +GNUNET_MY_result_spec_uint64 (uint64_t *u64); + int GNUNET_MY_extract_result (MYSQL_BIND * result, struct GNUNET_MY_QueryParam *qp, diff --git a/src/my/Makefile.am b/src/my/Makefile.am index 54e6d5563..7c0bc404e 100644 --- a/src/my/Makefile.am +++ b/src/my/Makefile.am @@ -15,10 +15,26 @@ endif libgnunetmy_la_SOURCES = \ my.c \ - my_query_helper.c + my_query_helper.c \ + my_result_helper.c + libgnunetmy_la_LIBADD = $(MYSQL_LDFLAGS) -lmysqlclient \ $(top_builddir)/src/mysql/libgnunetmysql.la \ $(top_builddir)/src/util/libgnunetutil.la libgnunetmy_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ -version-info 0:0:0 + +TESTS = \ + test_my + +check_PROGRAMS= \ + test_my + +test_my_SOURCES = \ + test_my.c +test_my_LDADD = \ + libgnunetmy.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + -lmysqlclient $(XLIB) + diff --git a/src/my/my.c b/src/my/my.c index 09d00163e..cc4f21cb1 100644 --- a/src/my/my.c +++ b/src/my/my.c @@ -34,8 +34,10 @@ * @param mc mysql context * @param sh handle to SELECT statment * @param params parameters to the statement - * @return + * @return mysql result */ + + /***** FIXE THIS FUNCTION *****/ int GNUNET_MY_exec_prepared (struct GNUNET_MYSQL_Context *mc, struct GNUNET_MYSQL_StatementHandle *sh, diff --git a/src/my/my_result_helper.c b/src/my/my_result_helper.c index 009fe2f11..f58c8e150 100644 --- a/src/my/my_result_helper.c +++ b/src/my/my_result_helper.c @@ -18,28 +18,7 @@ #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet_pq_lib.h" - -/** - * Function called to clean up memory allocated - * by a #GNUNET_MY_ResultConverter. - * - * @param cls closure - * @param rd result data to clean up - */ -static void -clean_varsize_blob (void *cls, - void *rs) -{ - void **dst = rd; - - if (NULL != *dst) - { - GNUNET_free (*dst); - *dst = NULL; - } -} - +#include "gnunet_my_lib.h" /** * extract data from a Mysql database @a result at row @a row @@ -66,15 +45,15 @@ extract_varsize_blob (void *cls, void *idst; size_t len; - MYSQL_ROW * rows; - MYSQL_FIELD * field; + MYSQL_ROW rows; + MYSQL_FIELD *field; rows = mysql_fetch_row (result); field = mysql_fetch_field (result); //If it's the correct field - if (field != fname) + if (field->name != fname) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Field '%s' does not exist in result", @@ -122,7 +101,7 @@ GNUNET_MY_result_spec_variable_size (void **dst, (void *)(dst), 0, ptr_size - } + }; return res; } @@ -142,7 +121,7 @@ GNUNET_MY_result_spec_variable_size (void **dst, * */ static int -extracted_fixed_blob (void *cls, +extract_fixed_blob (void *cls, MYSQL_RES * result, int row, const char * fname, @@ -152,7 +131,7 @@ extracted_fixed_blob (void *cls, size_t len; const char *res; - MYSQL_ROW * rows; + MYSQL_ROW rows; MYSQL_FIELD * field; rows = mysql_fetch_row (result); @@ -160,7 +139,7 @@ extracted_fixed_blob (void *cls, field = mysql_fetch_field (result); //If it's the correct field - if (field != fname) + if (field->name != fname) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Field '%s' does not exist in result", @@ -235,7 +214,7 @@ GNUNET_MY_result_spec_fixed_size (void *ptr, static int extract_rsa_public_key (void *cls, MYSQL_RES *result, - int rown, + int row, const char *fname, size_t *dst_size, void *dst) @@ -244,7 +223,7 @@ extract_rsa_public_key (void *cls, size_t len; const char *res; - MYSQL_ROW * rows; + MYSQL_ROW rows; MYSQL_FIELD * field; *pk = NULL; @@ -254,7 +233,7 @@ extract_rsa_public_key (void *cls, field = mysql_fetch_field (result); //If it's the correct field - if (field != fname) + if (field->name != fname) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Field '%s' does not exist in result", @@ -285,26 +264,6 @@ extract_rsa_public_key (void *cls, return GNUNET_OK; } -/** - * Function called to clean up memory allocated - * by a #GNUNET_MY_ResultConverter - * - * @param cls closure - * @param rd result data to clean up - */ -static void -clean_rsa_public_key (void *cls, - void *rd) -{ - struct GNUNET_CRYPTO_RsaPublicKey **pk = rd; - if (NULL != *pk) - { - GNUNET_CRYPTO_rsa_public_key_free (*pk); - *pk = NULL; - } -} - - /** * RSA public key expected * @@ -351,7 +310,7 @@ extract_rsa_signature (void *cls, const char *res; - MYSQL_ROW * rows; + MYSQL_ROW rows; MYSQL_FIELD * field; *sig = NULL; @@ -361,7 +320,7 @@ extract_rsa_signature (void *cls, field = mysql_fetch_field (result); //If it's the correct field - if (field == fname) + if (field->name == fname) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Field '%s' does not exist in result", @@ -437,7 +396,7 @@ extract_string (void * cls, size_t len; const char *res; - MYSQL_ROW * rows; + MYSQL_ROW rows; MYSQL_FIELD * field; *str = NULL; @@ -544,6 +503,43 @@ extract_uint16 (void *cls, void *dst) { //TO COMPLETE + uint16_t *udst = dst; + const uint16_t *res; + + MYSQL_ROW rows; + MYSQL_FIELD * field; + + rows = mysql_fetch_row (result); + + field = mysql_fetch_field (result); + + //If it's the correct field + if (field->name == fname) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Field '%s' does not exist in result", + fname); + return GNUNET_SYSERR; + } + + + if (rows[row] == NULL) + { + return GNUNET_SYSERR; + } + + GNUNET_assert (NULL != dst); + + if (sizeof (uint16_t) != *dst_size) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + + res = (uint16_t) rows[row]; + *udst = ntohs (*res); + + return GNUNET_OK; } /** @@ -566,4 +562,161 @@ GNUNET_MY_result_spec_uint16 (uint16_t *u16) } /** + * Extrac data from a MYSQL database @a result at row @a row + * + * @param cls closure + * @param result where to extract data from + * @param int row to extract data from + * @param fname name (or prefix) of the fields to extract from + * @param[in, out] dst_size where to store size of result, may be NULL + * @param[out] dst where to store the result + * @return + * #GNUNET_OK if all results could be extracted + * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) + */ +static int +extract_uint32 (void *cls, + MYSQL_RES * result, + int row, + const char *fname, + size_t *dst_size, + void *dst) +{ + uint32_t *udst = dst; + const uint32_t *res; + + MYSQL_ROW rows; + MYSQL_FIELD * field; + + rows = mysql_fetch_row (result); + + field = mysql_fetch_field (result); + + //If it's the correct field + if (field->name == fname) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Field '%s' does not exist in result", + fname); + return GNUNET_SYSERR; + } + + + if (rows[row] == NULL) + { + return GNUNET_SYSERR; + } + + GNUNET_assert (NULL != dst); + + if (sizeof (uint32_t) != *dst_size) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + + res = (uint32_t) rows[row]; + + *udst = ntohl (*res); + return GNUNET_OK; +} + +/** + * uint32_t expected + * + * @param[out] u32 where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_MY_ResultSpec +GNUNET_MY_result_spec_uint32 (uint32_t *u32) +{ + struct GNUNET_MY_ResultSpec res = { + &extract_uint32, + NULL, + (void *) u32, + sizeof (*u32), + NULL + }; + return res; +} + +/** + * Extract data from a MYSQL database @a result at row @a row + * + * @param cls closure + * @param result where to extract data from + * @param int row to extract data from + * @param fname name (or prefix) of the fields to extract from + * @param[in, out] dst_size where to store size of result, may be null + * @param[out] dst where to store the result + * @return + * #GNUNET_OK if all results could be extracted + * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) + */ +static int +extract_uint64 (void *cls, + MYSQL_RES * result, + int row, + const char *fname, + size_t *dst_size, + void *dst) +{ + uint64_t *udst = dst; + const uint64_t *res; + + MYSQL_ROW rows; + MYSQL_FIELD * field; + + rows = mysql_fetch_row (result); + + field = mysql_fetch_field (result); + + //If it's the correct field + if (field->name == fname) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Field '%s' does not exist in result", + fname); + return GNUNET_SYSERR; + } + + + if (rows[row] == NULL) + { + return GNUNET_SYSERR; + } + + GNUNET_assert (NULL != dst); + if (sizeof (uint64_t) != *dst_size) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + + res = (uint64_t) rows[row]; + *udst = GNUNET_ntohll (*res); + + return GNUNET_OK; +} + + +/** + * uint64_t expected. + * + * @param[out] u64 where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_MY_ResultSpec +GNUNET_MY_result_spec_uint64 (uint64_t *u64) +{ + struct GNUNET_MY_ResultSpec res = { + &extract_uint64, + NULL, + (void *) u64, + sizeof (*u64), + NULL + }; + return res; +} + /* end of pq_result_helper.c */ \ No newline at end of file -- 2.25.1