donau

Donation authority for GNU Taler (experimental)
Log | Files | Refs | Submodules | README | LICENSE

commit 26ecdc2062cc366cabc17fcf961c6db87da4e5bc
parent a2c74ea0625115fa4faa6dd7af76324f551b74a8
Author: Casaburi Johannes <johannes.casaburi@students.bfh.ch>
Date:   Mon,  4 Dec 2023 22:46:20 +0100

[db] cleanup

Diffstat:
Msrc/include/donaudb_plugin.h | 11+++++------
Msrc/pq/pq_result_helper.c | 1500++++++-------------------------------------------------------------------------
2 files changed, 107 insertions(+), 1404 deletions(-)

diff --git a/src/include/donaudb_plugin.h b/src/include/donaudb_plugin.h @@ -14,19 +14,18 @@ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ /** - * @file include/taler_donaudb_plugin.h + * @file include/donaudb_plugin.h * @brief Low-level (statement-level) database access for the donau * @author Johannes Casaburi */ #ifndef DONAUDB_PLUGIN_H #define DONAUDB_PLUGIN_H -#include <jansson.h> -#include <gnunet/gnunet_util_lib.h> +//#include <jansson.h> #include <gnunet/gnunet_db_lib.h> #include "taler/taler_json_lib.h" #include "donau_signatures.h" #include "donau_util.h" -#include "taler/taler_extensions_policy.h" +//#include "taler/taler_extensions_policy.h" /** * Meta data about a donation unit key. @@ -85,12 +84,12 @@ struct DONAUDB_DonationUnitKey * The private key of the donation unit. Will be NULL if the private * key is not available. */ - // struct DONAU_DonationUnitPublicKey donation_unit_priv; + struct DONAU_DonationUnitPublicKey donation_unit_priv; /** * Decoded donation unit public key. */ - // struct DONAU_DonationUnitPublicKey donation_unit_pub; + struct DONAU_DonationUnitPublicKey donation_unit_pub; }; diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c @@ -18,1407 +18,111 @@ * @brief functions to initialize parameter arrays * @author Christian Grothoff */ -// #include "taler/platform.h" -#include <gnunet/gnunet_util_lib.h> -// #include "pq_common.h" -// #include "taler_pq_lib.h" +#include "taler/platform.h" +//#include <gnunet/gnunet_util_lib.h> +//#include "pq_common.h" +#include "taler/taler_pq_lib.h" - -// /** -// * Extract an amount from a tuple including the currency from a Postgres -// * database @a result at row @a row. -// * -// * @param cls closure; not used -// * @param result where to extract data from -// * @param row 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_YES if all results could be extracted -// * #GNUNET_NO if at least one result was NULL -// * #GNUNET_SYSERR if a result was invalid (non-existing field) -// */ -// static enum GNUNET_GenericReturnValue -// extract_amount_currency_tuple (void *cls, -// PGresult *result, -// int row, -// const char *fname, -// size_t *dst_size, -// void *dst) -// { -// struct TALER_Amount *r_amount = dst; -// int col; - -// (void) cls; -// if (sizeof (struct TALER_Amount) != *dst_size) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } - -// /* Set return value to invalid in case we don't finish */ -// memset (r_amount, -// 0, -// sizeof (struct TALER_Amount)); -// col = PQfnumber (result, -// fname); -// if (col < 0) -// { -// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -// "Field `%s' does not exist in result\n", -// fname); -// return GNUNET_SYSERR; -// } -// if (PQgetisnull (result, -// row, -// col)) -// { -// return GNUNET_NO; -// } - -// /* Parse the tuple */ -// { -// struct TALER_PQ_AmountCurrencyP ap; -// const char *in; -// size_t size; - -// size = PQgetlength (result, -// row, -// col); -// if ( (size >= sizeof (ap)) || -// (size <= sizeof (ap) - TALER_CURRENCY_LEN) ) -// { -// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -// "Incorrect size of binary field `%s' (got %zu, expected (%zu-%zu))\n", -// fname, -// size, -// sizeof (ap) - TALER_CURRENCY_LEN, -// sizeof (ap)); -// return GNUNET_SYSERR; -// } - -// in = PQgetvalue (result, -// row, -// col); -// memset (&ap.c, -// 0, -// TALER_CURRENCY_LEN); -// memcpy (&ap, -// in, -// size); -// if (3 != ntohl (ap.cnt)) -// { -// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -// "Incorrect number of elements in tuple-field `%s'\n", -// fname); -// return GNUNET_SYSERR; -// } -// /* TODO[oec]: OID-checks? */ - -// r_amount->value = GNUNET_ntohll (ap.v); -// r_amount->fraction = ntohl (ap.f); -// memcpy (r_amount->currency, -// ap.c, -// TALER_CURRENCY_LEN); -// if ('\0' != r_amount->currency[TALER_CURRENCY_LEN - 1]) -// { -// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -// "Invalid currency (not 0-terminated) in tuple field `%s'\n", -// fname); -// /* be sure nobody uses this by accident */ -// memset (r_amount, -// 0, -// sizeof (struct TALER_Amount)); -// return GNUNET_SYSERR; -// } -// } - -// if (r_amount->value >= TALER_AMOUNT_MAX_VALUE) -// { -// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -// "Value in field `%s' exceeds legal range\n", -// fname); -// return GNUNET_SYSERR; -// } -// if (r_amount->fraction >= TALER_AMOUNT_FRAC_BASE) -// { -// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -// "Fraction in field `%s' exceeds legal range\n", -// fname); -// return GNUNET_SYSERR; -// } -// return GNUNET_OK; -// } - - -// struct GNUNET_PQ_ResultSpec -// TALER_PQ_result_spec_amount_with_currency (const char *name, -// struct TALER_Amount *amount) -// { -// struct GNUNET_PQ_ResultSpec res = { -// .conv = &extract_amount_currency_tuple, -// .dst = (void *) amount, -// .dst_size = sizeof (*amount), -// .fname = name -// }; - -// return res; -// } - - -// /** -// * Extract an amount from a tuple from a Postgres database @a result at row @a row. -// * -// * @param cls closure, a `const char *` giving the currency -// * @param result where to extract data from -// * @param row 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_YES if all results could be extracted -// * #GNUNET_NO if at least one result was NULL -// * #GNUNET_SYSERR if a result was invalid (non-existing field) -// */ -// static enum GNUNET_GenericReturnValue -// extract_amount_tuple (void *cls, -// PGresult *result, -// int row, -// const char *fname, -// size_t *dst_size, -// void *dst) -// { -// struct TALER_Amount *r_amount = dst; -// const char *currency = cls; -// int col; -// size_t len; - -// if (sizeof (struct TALER_Amount) != *dst_size) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } - -// /* Set return value to invalid in case we don't finish */ -// memset (r_amount, -// 0, -// sizeof (struct TALER_Amount)); -// col = PQfnumber (result, -// fname); -// if (col < 0) -// { -// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -// "Field `%s' does not exist in result\n", -// fname); -// return GNUNET_SYSERR; -// } -// if (PQgetisnull (result, -// row, -// col)) -// { -// return GNUNET_NO; -// } - -// /* Parse the tuple */ -// { -// struct TALER_PQ_AmountP ap; -// const char *in; -// size_t size; - -// size = PQgetlength (result, -// row, -// col); -// if (sizeof(ap) != size) -// { -// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -// "Incorrect size of binary field `%s' (got %zu, expected %zu)\n", -// fname, -// size, -// sizeof(ap)); -// return GNUNET_SYSERR; -// } - -// in = PQgetvalue (result, -// row, -// col); -// memcpy (&ap, -// in, -// size); -// if (2 != ntohl (ap.cnt)) -// { -// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -// "Incorrect number of elements in tuple-field `%s'\n", -// fname); -// return GNUNET_SYSERR; -// } -// /* TODO[oec]: OID-checks? */ - -// r_amount->value = GNUNET_ntohll (ap.v); -// r_amount->fraction = ntohl (ap.f); -// } - -// if (r_amount->value >= TALER_AMOUNT_MAX_VALUE) -// { -// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -// "Value in field `%s' exceeds legal range\n", -// fname); -// return GNUNET_SYSERR; -// } -// if (r_amount->fraction >= TALER_AMOUNT_FRAC_BASE) -// { -// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -// "Fraction in field `%s' exceeds legal range\n", -// fname); -// return GNUNET_SYSERR; -// } - -// len = GNUNET_MIN (TALER_CURRENCY_LEN - 1, -// strlen (currency)); - -// GNUNET_memcpy (r_amount->currency, -// currency, -// len); -// return GNUNET_OK; -// } - - -// struct GNUNET_PQ_ResultSpec -// TALER_PQ_result_spec_amount (const char *name, -// const char *currency, -// struct TALER_Amount *amount) -// { -// struct GNUNET_PQ_ResultSpec res = { -// .conv = &extract_amount_tuple, -// .cls = (void *) currency, -// .dst = (void *) amount, -// .dst_size = sizeof (*amount), -// .fname = name -// }; - -// return res; -// } - - -// /** -// * Extract data from a Postgres database @a result at row @a row. -// * -// * @param cls closure -// * @param result where to extract data from -// * @param row 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_YES if all results could be extracted -// * #GNUNET_NO if at least one result was NULL -// * #GNUNET_SYSERR if a result was invalid (non-existing field) -// */ -// static enum GNUNET_GenericReturnValue -// extract_json (void *cls, -// PGresult *result, -// int row, -// const char *fname, -// size_t *dst_size, -// void *dst) -// { -// json_t **j_dst = dst; -// const char *res; -// int fnum; -// json_error_t json_error; -// size_t slen; - -// (void) cls; -// (void) dst_size; -// fnum = PQfnumber (result, -// fname); -// if (fnum < 0) -// { -// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -// "Field `%s' does not exist in result\n", -// fname); -// return GNUNET_SYSERR; -// } -// if (PQgetisnull (result, -// row, -// fnum)) -// return GNUNET_NO; -// slen = PQgetlength (result, -// row, -// fnum); -// res = (const char *) PQgetvalue (result, -// row, -// fnum); -// *j_dst = json_loadb (res, -// slen, -// JSON_REJECT_DUPLICATES, -// &json_error); -// if (NULL == *j_dst) -// { -// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -// "Failed to parse JSON result for field `%s': %s (%s)\n", -// fname, -// json_error.text, -// json_error.source); -// return GNUNET_SYSERR; -// } -// return GNUNET_OK; -// } - - -// /** -// * Function called to clean up memory allocated -// * by a #GNUNET_PQ_ResultConverter. -// * -// * @param cls closure -// * @param rd result data to clean up -// */ -// static void -// clean_json (void *cls, -// void *rd) -// { -// json_t **dst = rd; - -// (void) cls; -// if (NULL != *dst) -// { -// json_decref (*dst); -// *dst = NULL; -// } -// } - - -// struct GNUNET_PQ_ResultSpec -// TALER_PQ_result_spec_json (const char *name, -// json_t **jp) -// { -// struct GNUNET_PQ_ResultSpec res = { -// .conv = &extract_json, -// .cleaner = &clean_json, -// .dst = (void *) jp, -// .fname = name -// }; - -// return res; -// } - - -// /** -// * Extract data from a Postgres database @a result at row @a row. -// * -// * @param cls closure -// * @param result where to extract data from -// * @param row the 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_YES if all results could be extracted -// * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) -// */ -// static enum GNUNET_GenericReturnValue -// extract_denom_pub (void *cls, -// PGresult *result, -// int row, -// const char *fname, -// size_t *dst_size, -// void *dst) -// { -// struct TALER_DenominationPublicKey *pk = dst; -// size_t len; -// const char *res; -// int fnum; -// uint32_t be[2]; - -// (void) cls; -// (void) dst_size; -// fnum = PQfnumber (result, -// fname); -// if (fnum < 0) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// if (PQgetisnull (result, -// row, -// fnum)) -// return GNUNET_NO; - -// /* if a field is null, continue but -// * remember that we now return a different result */ -// len = PQgetlength (result, -// row, -// fnum); -// res = PQgetvalue (result, -// row, -// fnum); -// if (len < sizeof (be)) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// GNUNET_memcpy (be, -// res, -// sizeof (be)); -// res += sizeof (be); -// len -= sizeof (be); -// pk->cipher = ntohl (be[0]); -// pk->age_mask.bits = ntohl (be[1]); -// switch (pk->cipher) -// { -// case TALER_DENOMINATION_RSA: -// pk->details.rsa_public_key -// = GNUNET_CRYPTO_rsa_public_key_decode (res, -// len); -// if (NULL == pk->details.rsa_public_key) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// return GNUNET_OK; -// case TALER_DENOMINATION_CS: -// if (sizeof (pk->details.cs_public_key) != len) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// GNUNET_memcpy (&pk->details.cs_public_key, -// res, -// len); -// return GNUNET_OK; -// default: -// GNUNET_break (0); -// } -// return GNUNET_SYSERR; -// } - - -// /** -// * Function called to clean up memory allocated -// * by a #GNUNET_PQ_ResultConverter. -// * -// * @param cls closure -// * @param rd result data to clean up -// */ -// static void -// clean_denom_pub (void *cls, -// void *rd) -// { -// struct TALER_DenominationPublicKey *denom_pub = rd; - -// (void) cls; -// TALER_denom_pub_free (denom_pub); -// } - - -// struct GNUNET_PQ_ResultSpec -// TALER_PQ_result_spec_denom_pub (const char *name, -// struct TALER_DenominationPublicKey *denom_pub) -// { -// struct GNUNET_PQ_ResultSpec res = { -// .conv = &extract_denom_pub, -// .cleaner = &clean_denom_pub, -// .dst = (void *) denom_pub, -// .fname = name -// }; - -// return res; -// } - - -// /** -// * Extract data from a Postgres database @a result at row @a row. -// * -// * @param cls closure -// * @param result where to extract data from -// * @param row the 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_YES if all results could be extracted -// * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) -// */ -// static enum GNUNET_GenericReturnValue -// extract_denom_sig (void *cls, -// PGresult *result, -// int row, -// const char *fname, -// size_t *dst_size, -// void *dst) -// { -// struct TALER_DenominationSignature *sig = dst; -// size_t len; -// const char *res; -// int fnum; -// uint32_t be[2]; - -// (void) cls; -// (void) dst_size; -// fnum = PQfnumber (result, -// fname); -// if (fnum < 0) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// if (PQgetisnull (result, -// row, -// fnum)) -// return GNUNET_NO; - -// /* if a field is null, continue but -// * remember that we now return a different result */ -// len = PQgetlength (result, -// row, -// fnum); -// res = PQgetvalue (result, -// row, -// fnum); -// if (len < sizeof (be)) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// GNUNET_memcpy (&be, -// res, -// sizeof (be)); -// if (0x00 != ntohl (be[1])) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// res += sizeof (be); -// len -= sizeof (be); -// sig->cipher = ntohl (be[0]); -// switch (sig->cipher) -// { -// case TALER_DENOMINATION_RSA: -// sig->details.rsa_signature -// = GNUNET_CRYPTO_rsa_signature_decode (res, -// len); -// if (NULL == sig->details.rsa_signature) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// return GNUNET_OK; -// case TALER_DENOMINATION_CS: -// if (sizeof (sig->details.cs_signature) != len) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// GNUNET_memcpy (&sig->details.cs_signature, -// res, -// len); -// return GNUNET_OK; -// default: -// GNUNET_break (0); -// } -// return GNUNET_SYSERR; -// } - - -// /** -// * Function called to clean up memory allocated -// * by a #GNUNET_PQ_ResultConverter. -// * -// * @param cls closure -// * @param rd result data to clean up -// */ -// static void -// clean_denom_sig (void *cls, -// void *rd) -// { -// struct TALER_DenominationSignature *denom_sig = rd; - -// (void) cls; -// TALER_denom_sig_free (denom_sig); -// } - - -// struct GNUNET_PQ_ResultSpec -// TALER_PQ_result_spec_denom_sig (const char *name, -// struct TALER_DenominationSignature *denom_sig) -// { -// struct GNUNET_PQ_ResultSpec res = { -// .conv = &extract_denom_sig, -// .cleaner = &clean_denom_sig, -// .dst = (void *) denom_sig, -// .fname = name -// }; - -// return res; -// } - - -// /** -// * Extract data from a Postgres database @a result at row @a row. -// * -// * @param cls closure -// * @param result where to extract data from -// * @param row the 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_YES if all results could be extracted -// * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) -// */ -// static enum GNUNET_GenericReturnValue -// extract_blinded_denom_sig (void *cls, -// PGresult *result, -// int row, -// const char *fname, -// size_t *dst_size, -// void *dst) -// { -// struct TALER_BlindedDenominationSignature *sig = dst; -// size_t len; -// const char *res; -// int fnum; -// uint32_t be[2]; - -// (void) cls; -// (void) dst_size; -// fnum = PQfnumber (result, -// fname); -// if (fnum < 0) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// if (PQgetisnull (result, -// row, -// fnum)) -// return GNUNET_NO; - -// /* if a field is null, continue but -// * remember that we now return a different result */ -// len = PQgetlength (result, -// row, -// fnum); -// res = PQgetvalue (result, -// row, -// fnum); -// if (len < sizeof (be)) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// GNUNET_memcpy (&be, -// res, -// sizeof (be)); -// if (0x01 != ntohl (be[1])) /* magic marker: blinded */ -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// res += sizeof (be); -// len -= sizeof (be); -// sig->cipher = ntohl (be[0]); -// switch (sig->cipher) -// { -// case TALER_DENOMINATION_RSA: -// sig->details.blinded_rsa_signature -// = GNUNET_CRYPTO_rsa_signature_decode (res, -// len); -// if (NULL == sig->details.blinded_rsa_signature) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// return GNUNET_OK; -// case TALER_DENOMINATION_CS: -// if (sizeof (sig->details.blinded_cs_answer) != len) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// GNUNET_memcpy (&sig->details.blinded_cs_answer, -// res, -// len); -// return GNUNET_OK; -// default: -// GNUNET_break (0); -// } -// return GNUNET_SYSERR; -// } - - -// /** -// * Function called to clean up memory allocated -// * by a #GNUNET_PQ_ResultConverter. -// * -// * @param cls closure -// * @param rd result data to clean up -// */ -// static void -// clean_blinded_denom_sig (void *cls, -// void *rd) -// { -// struct TALER_BlindedDenominationSignature *denom_sig = rd; - -// (void) cls; -// TALER_blinded_denom_sig_free (denom_sig); -// } - - -// struct GNUNET_PQ_ResultSpec -// TALER_PQ_result_spec_blinded_denom_sig ( -// const char *name, -// struct TALER_BlindedDenominationSignature *denom_sig) -// { -// struct GNUNET_PQ_ResultSpec res = { -// .conv = &extract_blinded_denom_sig, -// .cleaner = &clean_blinded_denom_sig, -// .dst = (void *) denom_sig, -// .fname = name -// }; - -// return res; -// } - - -// /** -// * Extract data from a Postgres database @a result at row @a row. -// * -// * @param cls closure -// * @param result where to extract data from -// * @param row the 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_YES if all results could be extracted -// * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) -// */ -// static enum GNUNET_GenericReturnValue -// extract_blinded_planchet (void *cls, -// PGresult *result, -// int row, -// const char *fname, -// size_t *dst_size, -// void *dst) -// { -// struct TALER_BlindedPlanchet *bp = dst; -// size_t len; -// const char *res; -// int fnum; -// uint32_t be[2]; - -// (void) cls; -// (void) dst_size; -// fnum = PQfnumber (result, -// fname); -// if (fnum < 0) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// if (PQgetisnull (result, -// row, -// fnum)) -// return GNUNET_NO; - -// /* if a field is null, continue but -// * remember that we now return a different result */ -// len = PQgetlength (result, -// row, -// fnum); -// res = PQgetvalue (result, -// row, -// fnum); -// if (len < sizeof (be)) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// GNUNET_memcpy (&be, -// res, -// sizeof (be)); -// if (0x0100 != ntohl (be[1])) /* magic marker: blinded */ -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// res += sizeof (be); -// len -= sizeof (be); -// bp->cipher = ntohl (be[0]); -// switch (bp->cipher) -// { -// case TALER_DENOMINATION_RSA: -// bp->details.rsa_blinded_planchet.blinded_msg_size -// = len; -// bp->details.rsa_blinded_planchet.blinded_msg -// = GNUNET_memdup (res, -// len); -// return GNUNET_OK; -// case TALER_DENOMINATION_CS: -// if (sizeof (bp->details.cs_blinded_planchet) != len) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// GNUNET_memcpy (&bp->details.cs_blinded_planchet, -// res, -// len); -// return GNUNET_OK; -// default: -// GNUNET_break (0); -// } -// return GNUNET_SYSERR; -// } - - -// /** -// * Function called to clean up memory allocated -// * by a #GNUNET_PQ_ResultConverter. -// * -// * @param cls closure -// * @param rd result data to clean up -// */ -// static void -// clean_blinded_planchet (void *cls, -// void *rd) -// { -// struct TALER_BlindedPlanchet *bp = rd; - -// (void) cls; -// TALER_blinded_planchet_free (bp); -// } - - -// struct GNUNET_PQ_ResultSpec -// TALER_PQ_result_spec_blinded_planchet ( -// const char *name, -// struct TALER_BlindedPlanchet *bp) -// { -// struct GNUNET_PQ_ResultSpec res = { -// .conv = &extract_blinded_planchet, -// .cleaner = &clean_blinded_planchet, -// .dst = (void *) bp, -// .fname = name -// }; - -// return res; -// } - - -// /** -// * Extract data from a Postgres database @a result at row @a row. -// * -// * @param cls closure -// * @param result where to extract data from -// * @param row 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_YES if all results could be extracted -// * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) -// */ -// static enum GNUNET_GenericReturnValue -// extract_exchange_withdraw_values (void *cls, -// PGresult *result, -// int row, -// const char *fname, -// size_t *dst_size, -// void *dst) -// { -// struct TALER_ExchangeWithdrawValues *alg_values = dst; -// size_t len; -// const char *res; -// int fnum; -// uint32_t be[2]; - -// (void) cls; -// (void) dst_size; -// fnum = PQfnumber (result, -// fname); -// if (fnum < 0) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// if (PQgetisnull (result, -// row, -// fnum)) -// return GNUNET_NO; - -// /* if a field is null, continue but -// * remember that we now return a different result */ -// len = PQgetlength (result, -// row, -// fnum); -// res = PQgetvalue (result, -// row, -// fnum); -// if (len < sizeof (be)) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// GNUNET_memcpy (&be, -// res, -// sizeof (be)); -// if (0x010000 != ntohl (be[1])) /* magic marker: EWV */ -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// res += sizeof (be); -// len -= sizeof (be); -// alg_values->cipher = ntohl (be[0]); -// switch (alg_values->cipher) -// { -// case TALER_DENOMINATION_RSA: -// if (0 != len) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// return GNUNET_OK; -// case TALER_DENOMINATION_CS: -// if (sizeof (struct TALER_DenominationCSPublicRPairP) != len) -// { -// GNUNET_break (0); -// return GNUNET_SYSERR; -// } -// GNUNET_memcpy (&alg_values->details.cs_values, -// res, -// len); -// return GNUNET_OK; -// default: -// GNUNET_break (0); -// } -// return GNUNET_SYSERR; -// } - - -// struct GNUNET_PQ_ResultSpec -// TALER_PQ_result_spec_exchange_withdraw_values ( -// const char *name, -// struct TALER_ExchangeWithdrawValues *ewv) -// { -// struct GNUNET_PQ_ResultSpec res = { -// .conv = &extract_exchange_withdraw_values, -// .dst = (void *) ewv, -// .fname = name -// }; - -// return res; -// } - - -// /** -// * Closure for the array result specifications. Contains type information -// * for the generic parser extract_array_generic and out-pointers for the results. -// */ -// struct ArrayResultCls -// { -// /* Oid of the expected type, must match the oid in the header of the PQResult struct */ -// Oid oid; - -// /* Target type */ -// enum TALER_PQ_ArrayType typ; - -// /* If not 0, defines the expected size of each entry */ -// size_t same_size; - -// /* Out-pointer to write the number of elements in the array */ -// size_t *num; - -// /* Out-pointer. If @a typ is TALER_PQ_array_of_byte and @a same_size is 0, -// * allocate and put the array of @a num sizes here. NULL otherwise */ -// size_t **sizes; - -// /* DB_connection, needed for OID-lookup for composite types */ -// const struct GNUNET_PQ_Context *db; - -// /* Currency information for amount composites */ -// char currency[TALER_CURRENCY_LEN]; -// }; - -// /** -// * Extract data from a Postgres database @a result as array of a specific type -// * from row @a row. The type information and optionally additional -// * out-parameters are given in @a cls which is of type array_result_cls. -// * -// * @param cls closure of type array_result_cls -// * @param result where to extract data from -// * @param row 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_YES if all results could be extracted -// * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) -// */ -// static enum GNUNET_GenericReturnValue -// extract_array_generic ( -// void *cls, -// PGresult *result, -// int row, -// const char *fname, -// size_t *dst_size, -// void *dst) -// { -// const struct ArrayResultCls *info = cls; -// int data_sz; -// char *data; -// void *out = NULL; -// struct GNUNET_PQ_ArrayHeader_P header; -// int col_num; - -// GNUNET_assert (NULL != dst); -// *((void **) dst) = NULL; - -/* #define FAIL_IF(cond) \ - do { \ - if ((cond)) \ - { \ - GNUNET_break (! (cond)); \ - goto FAIL; \ - } \ - } while (0) -*/ -// col_num = PQfnumber (result, fname); -// FAIL_IF (0 > col_num); - -// data_sz = PQgetlength (result, row, col_num); -// FAIL_IF (0 > data_sz); -// FAIL_IF (sizeof(header) > (size_t) data_sz); - -// data = PQgetvalue (result, row, col_num); -// FAIL_IF (NULL == data); - -// { -// struct GNUNET_PQ_ArrayHeader_P *h = -// (struct GNUNET_PQ_ArrayHeader_P *) data; - -// header.ndim = ntohl (h->ndim); -// header.has_null = ntohl (h->has_null); -// header.oid = ntohl (h->oid); -// header.dim = ntohl (h->dim); -// header.lbound = ntohl (h->lbound); - -// FAIL_IF (1 != header.ndim); -// FAIL_IF (INT_MAX <= header.dim); -// FAIL_IF (0 != header.has_null); -// FAIL_IF (1 != header.lbound); -// FAIL_IF (info->oid != header.oid); -// } - -// if (NULL != info->num) -// *info->num = header.dim; - -// { -// char *in = data + sizeof(header); - -// switch (info->typ) -// { -// case TALER_PQ_array_of_amount: -// { -// struct TALER_Amount *amounts; -// if (NULL != dst_size) -// *dst_size = sizeof(struct TALER_Amount) * (header.dim); - -// amounts = GNUNET_new_array (header.dim, struct TALER_Amount); -// *((void **) dst) = amounts; - -// for (uint32_t i = 0; i < header.dim; i++) -// { -// struct TALER_PQ_AmountP ap; -// struct TALER_Amount *amount = &amounts[i]; -// uint32_t val; -// size_t sz; - -// GNUNET_memcpy (&val, -// in, -// sizeof(val)); -// sz = ntohl (val); -// in += sizeof(val); - -// /* total size for this array-entry */ -// FAIL_IF (sizeof(ap) > sz); - -// GNUNET_memcpy (&ap, -// in, -// sz); -// FAIL_IF (2 != ntohl (ap.cnt)); - -// amount->value = GNUNET_ntohll (ap.v); -// amount->fraction = ntohl (ap.f); -// GNUNET_memcpy (amount->currency, -// info->currency, -// TALER_CURRENCY_LEN); - -// in += sizeof(struct TALER_PQ_AmountP); -// } -// return GNUNET_OK; -// } -// case TALER_PQ_array_of_denom_hash: -// if (NULL != dst_size) -// *dst_size = sizeof(struct TALER_DenominationHashP) * (header.dim); -// out = GNUNET_new_array (header.dim, struct TALER_DenominationHashP); -// *((void **) dst) = out; -// for (uint32_t i = 0; i < header.dim; i++) -// { -// uint32_t val; -// size_t sz; - -// GNUNET_memcpy (&val, -// in, -// sizeof(val)); -// sz = ntohl (val); -// FAIL_IF (sz != sizeof(struct TALER_DenominationHashP)); -// in += sizeof(uint32_t); -// *(struct TALER_DenominationHashP *) out = -// *(struct TALER_DenominationHashP *) in; -// in += sz; -// out += sz; -// } -// return GNUNET_OK; - -// case TALER_PQ_array_of_blinded_coin_hash: -// if (NULL != dst_size) -// *dst_size = sizeof(struct TALER_BlindedCoinHashP) * (header.dim); -// out = GNUNET_new_array (header.dim, struct TALER_BlindedCoinHashP); -// *((void **) dst) = out; -// for (uint32_t i = 0; i < header.dim; i++) -// { -// uint32_t val; -// size_t sz; - -// GNUNET_memcpy (&val, -// in, -// sizeof(val)); -// sz = ntohl (val); -// FAIL_IF (sz != sizeof(struct TALER_BlindedCoinHashP)); -// in += sizeof(uint32_t); -// *(struct TALER_BlindedCoinHashP *) out = -// *(struct TALER_BlindedCoinHashP *) in; -// in += sz; -// out += sz; -// } -// return GNUNET_OK; - -// case TALER_PQ_array_of_blinded_denom_sig: -// { -// struct TALER_BlindedDenominationSignature *denom_sigs; -// if (0 == header.dim) -// { -// if (NULL != dst_size) -// *dst_size = 0; -// break; -// } - -// denom_sigs = GNUNET_new_array (header.dim, -// struct TALER_BlindedDenominationSignature); -// *((void **) dst) = denom_sigs; - -// /* copy data */ -// for (uint32_t i = 0; i < header.dim; i++) -// { -// struct TALER_BlindedDenominationSignature *denom_sig = &denom_sigs[i]; -// uint32_t be[2]; -// uint32_t val; -// size_t sz; - -// GNUNET_memcpy (&val, -// in, -// sizeof(val)); -// sz = ntohl (val); -// FAIL_IF (sizeof(be) > sz); - -// in += sizeof(val); -// GNUNET_memcpy (&be, -// in, -// sizeof(be)); -// FAIL_IF (0x01 != ntohl (be[1])); /* magic marker: blinded */ - -// in += sizeof(be); -// sz -= sizeof(be); - -// denom_sig->cipher = ntohl (be[0]); -// switch (denom_sig->cipher) -// { -// case TALER_DENOMINATION_RSA: -// denom_sig->details.blinded_rsa_signature = -// GNUNET_CRYPTO_rsa_signature_decode (in, -// sz); -// FAIL_IF (NULL == denom_sig->details.blinded_rsa_signature); -// break; - -// case TALER_DENOMINATION_CS: -// FAIL_IF (sizeof(denom_sig->details.blinded_cs_answer) != sz); -// GNUNET_memcpy (&denom_sig->details.blinded_cs_answer, -// in, -// sz); -// break; - -// default: -// FAIL_IF (true); -// } - -// in += sz; -// } -// return GNUNET_OK; -// } -// default: -// FAIL_IF (true); -// } -// } - -// FAIL: -// GNUNET_free (*(void **) dst); -// return GNUNET_SYSERR; -// #undef FAIL_IF - -// } - - -// /** -// * Cleanup of the data and closure of an array spec. -// */ -// static void -// array_cleanup (void *cls, -// void *rd) -// { - -// struct ArrayResultCls *info = cls; -// void **dst = rd; - -// if ((0 == info->same_size) && -// (NULL != info->sizes)) -// GNUNET_free (*(info->sizes)); - -// GNUNET_free (cls); -// GNUNET_free (*dst); -// *dst = NULL; -// } - - -// struct GNUNET_PQ_ResultSpec -// TALER_PQ_result_spec_array_blinded_denom_sig ( -// struct GNUNET_PQ_Context *db, -// const char *name, -// size_t *num, -// struct TALER_BlindedDenominationSignature **denom_sigs) -// { -// struct ArrayResultCls *info = GNUNET_new (struct ArrayResultCls); - -// info->num = num; -// info->typ = TALER_PQ_array_of_blinded_denom_sig; -// GNUNET_assert (GNUNET_OK == -// GNUNET_PQ_get_oid_by_name (db, -// "bytea", -// &info->oid)); - -// struct GNUNET_PQ_ResultSpec res = { -// .conv = extract_array_generic, -// .cleaner = array_cleanup, -// .dst = (void *) denom_sigs, -// .fname = name, -// .cls = info -// }; -// return res; - -// }; - -// struct GNUNET_PQ_ResultSpec -// TALER_PQ_result_spec_array_blinded_coin_hash ( -// struct GNUNET_PQ_Context *db, -// const char *name, -// size_t *num, -// struct TALER_BlindedCoinHashP **h_coin_evs) -// { -// struct ArrayResultCls *info = GNUNET_new (struct ArrayResultCls); - -// info->num = num; -// info->typ = TALER_PQ_array_of_blinded_coin_hash; -// GNUNET_assert (GNUNET_OK == -// GNUNET_PQ_get_oid_by_name (db, -// "bytea", -// &info->oid)); - -// struct GNUNET_PQ_ResultSpec res = { -// .conv = extract_array_generic, -// .cleaner = array_cleanup, -// .dst = (void *) h_coin_evs, -// .fname = name, -// .cls = info -// }; -// return res; - -// }; - -// struct GNUNET_PQ_ResultSpec -// TALER_PQ_result_spec_array_denom_hash ( -// struct GNUNET_PQ_Context *db, -// const char *name, -// size_t *num, -// struct TALER_DenominationHashP **denom_hs) -// { -// struct ArrayResultCls *info = GNUNET_new (struct ArrayResultCls); - -// info->num = num; -// info->typ = TALER_PQ_array_of_denom_hash; -// GNUNET_assert (GNUNET_OK == -// GNUNET_PQ_get_oid_by_name (db, -// "bytea", -// &info->oid)); - -// struct GNUNET_PQ_ResultSpec res = { -// .conv = extract_array_generic, -// .cleaner = array_cleanup, -// .dst = (void *) denom_hs, -// .fname = name, -// .cls = info -// }; -// return res; - -// }; - -// struct GNUNET_PQ_ResultSpec -// TALER_PQ_result_spec_array_amount ( -// struct GNUNET_PQ_Context *db, -// const char *name, -// const char *currency, -// size_t *num, -// struct TALER_Amount **amounts) -// { -// struct ArrayResultCls *info = GNUNET_new (struct ArrayResultCls); - -// info->num = num; -// info->typ = TALER_PQ_array_of_amount; -// info->db = db; -// GNUNET_assert (GNUNET_OK == -// GNUNET_PQ_get_oid_by_name (db, -// "taler_amount", -// &info->oid)); - -// { -// size_t clen = GNUNET_MIN (TALER_CURRENCY_LEN - 1, -// strlen (currency)); -// GNUNET_memcpy (&info->currency, -// currency, -// clen); -// } - -// struct GNUNET_PQ_ResultSpec res = { -// .conv = extract_array_generic, -// .cleaner = array_cleanup, -// .dst = (void *) amounts, -// .fname = name, -// .cls = info, -// }; -// return res; +/** + * Extract data from a Postgres database @a result at row @a row. + * + * @param cls closure + * @param result where to extract data from + * @param row 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_YES if all results could be extracted + * #GNUNET_NO if at least one result was NULL + * #GNUNET_SYSERR if a result was invalid (non-existing field) + */ +static enum GNUNET_GenericReturnValue +extract_json (void *cls, + PGresult *result, + int row, + const char *fname, + size_t *dst_size, + void *dst) +{ + json_t **j_dst = dst; + const char *res; + int fnum; + json_error_t json_error; + size_t slen; + + (void) cls; + (void) dst_size; + fnum = PQfnumber (result, + fname); + if (fnum < 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Field `%s' does not exist in result\n", + fname); + return GNUNET_SYSERR; + } + if (PQgetisnull (result, + row, + fnum)) + return GNUNET_NO; + slen = PQgetlength (result, + row, + fnum); + res = (const char *) PQgetvalue (result, + row, + fnum); + *j_dst = json_loadb (res, + slen, + JSON_REJECT_DUPLICATES, + &json_error); + if (NULL == *j_dst) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to parse JSON result for field `%s': %s (%s)\n", + fname, + json_error.text, + json_error.source); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} -// } +/** + * Function called to clean up memory allocated + * by a #GNUNET_PQ_ResultConverter. + * + * @param cls closure + * @param rd result data to clean up + */ +static void +clean_json (void *cls, + void *rd) +{ + json_t **dst = rd; + + (void) cls; + if (NULL != *dst) + { + json_decref (*dst); + *dst = NULL; + } +} + +struct GNUNET_PQ_ResultSpec +TALER_PQ_result_spec_json (const char *name, + json_t **jp) +{ + struct GNUNET_PQ_ResultSpec res = { + .conv = &extract_json, + .cleaner = &clean_json, + .dst = (void *) jp, + .fname = name + }; + + return res; +} /* end of pq_result_helper.c */