merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit 6fd464170627c9bf76ae25573006418eacdf445f
parent ca62ed41b3bdca9368cdf28e8c79ff0faf5995ec
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sat, 21 Jun 2025 19:02:37 +0200

combine two SQL statements into one using (LEFT) JOIN

Diffstat:
Msrc/backenddb/pg_lookup_instances.c | 297++++++++++++++++++++++++++++++++++---------------------------------------------
1 file changed, 129 insertions(+), 168 deletions(-)

diff --git a/src/backenddb/pg_lookup_instances.c b/src/backenddb/pg_lookup_instances.c @@ -46,108 +46,14 @@ struct LookupInstancesContext struct PostgresClosure *pg; /** - * Instance settings, valid only during find_instances_cb(). - */ - struct TALER_MERCHANTDB_InstanceSettings is; - - /** - * Instance authentication settings, valid only during find_instances_cb(). - */ - struct TALER_MERCHANTDB_InstanceAuthSettings ias; - - /** - * Instance serial number, valid only during find_instances_cb(). - */ - uint64_t instance_serial; - - /** - * Public key of the current instance, valid only during find_instances_cb(). - */ - struct TALER_MerchantPublicKeyP merchant_pub; - - /** * Set to the return value on errors. */ enum GNUNET_DB_QueryStatus qs; - /** - * true if we only are interested in instances for which we have the private key. - */ - bool active_only; }; /** - * Helper function to run PREPARE() macro. - * - * @param pg closure to pass - * @return status of the preparation - */ -static enum GNUNET_DB_QueryStatus -prepare (struct PostgresClosure *pg) -{ - // FIXME: use a LEFT JOIN here! - PREPARE (pg, - "lookup_instance_private_key", - "SELECT" - " merchant_priv" - " FROM merchant_keys" - " WHERE merchant_serial=$1"); - return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; -} - - -/** - * We are processing an instances lookup and have the @a accounts. - * Find the private key if possible, and invoke the callback. - * - * @param lic context we are handling - */ -static void -call_cb (struct LookupInstancesContext *lic) -{ - struct PostgresClosure *pg = lic->pg; - enum GNUNET_DB_QueryStatus qs; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&lic->instance_serial), - GNUNET_PQ_query_param_end - }; - struct TALER_MerchantPrivateKeyP merchant_priv; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_auto_from_type ("merchant_priv", - &merchant_priv), - GNUNET_PQ_result_spec_end - }; - - qs = prepare (pg); - if (qs < 0) - { - GNUNET_break (0); - lic->qs = GNUNET_DB_STATUS_HARD_ERROR; - return; - } - qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "lookup_instance_private_key", - params, - rs); - if (qs < 0) - { - GNUNET_break (0); - lic->qs = GNUNET_DB_STATUS_HARD_ERROR; - return; - } - if ( (0 == qs) && - (lic->active_only) ) - return; /* skip, not interesting */ - lic->cb (lic->cb_cls, - &lic->merchant_pub, - (0 == qs) ? NULL : &merchant_priv, - &lic->is, - &lic->ias); -} - - -/** * Function to be called with the results of a SELECT statement * that has returned @a num_results results about instances. * @@ -161,68 +67,70 @@ lookup_instances_cb (void *cls, unsigned int num_results) { struct LookupInstancesContext *lic = cls; - struct PostgresClosure *pg = lic->pg; - - lic->qs = prepare (pg); - if (lic->qs < 0) - { - GNUNET_break (0); - return; - } for (unsigned int i = 0; i < num_results; i++) { + struct TALER_MERCHANTDB_InstanceSettings is; + struct TALER_MERCHANTDB_InstanceAuthSettings ias; + uint64_t instance_serial; + struct TALER_MerchantPublicKeyP merchant_pub; + struct TALER_MerchantPrivateKeyP merchant_priv; bool no_auth; bool no_salt; + bool no_priv; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_uint64 ("merchant_serial", - &lic->instance_serial), + &instance_serial), GNUNET_PQ_result_spec_auto_from_type ("merchant_pub", - &lic->merchant_pub), + &merchant_pub), GNUNET_PQ_result_spec_allow_null ( GNUNET_PQ_result_spec_auto_from_type ("auth_hash", - &lic->ias.auth_hash), + &ias.auth_hash), &no_auth), GNUNET_PQ_result_spec_allow_null ( GNUNET_PQ_result_spec_auto_from_type ("auth_salt", - &lic->ias.auth_salt), + &ias.auth_salt), &no_salt), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_auto_from_type ("merchant_priv", + &merchant_priv), + &no_priv), GNUNET_PQ_result_spec_string ("merchant_id", - &lic->is.id), + &is.id), GNUNET_PQ_result_spec_string ("merchant_name", - &lic->is.name), + &is.name), TALER_PQ_result_spec_json ("address", - &lic->is.address), + &is.address), TALER_PQ_result_spec_json ("jurisdiction", - &lic->is.jurisdiction), + &is.jurisdiction), GNUNET_PQ_result_spec_bool ("use_stefan", - &lic->is.use_stefan), - GNUNET_PQ_result_spec_relative_time ("default_wire_transfer_delay", - &lic->is.default_wire_transfer_delay) - , + &is.use_stefan), + GNUNET_PQ_result_spec_relative_time ( + "default_wire_transfer_delay", + &is.default_wire_transfer_delay), GNUNET_PQ_result_spec_relative_time ("default_pay_delay", - &lic->is.default_pay_delay), + &is.default_pay_delay), GNUNET_PQ_result_spec_allow_null ( GNUNET_PQ_result_spec_string ("website", - &lic->is.website), + &is.website), NULL), GNUNET_PQ_result_spec_allow_null ( GNUNET_PQ_result_spec_string ("email", - &lic->is.email), + &is.email), NULL), GNUNET_PQ_result_spec_allow_null ( GNUNET_PQ_result_spec_string ("logo", - &lic->is.logo), + &is.logo), NULL), GNUNET_PQ_result_spec_end }; - memset (&lic->ias.auth_salt, + memset (&ias.auth_salt, 0, - sizeof (lic->ias.auth_salt)); - memset (&lic->ias.auth_hash, + sizeof (ias.auth_salt)); + memset (&ias.auth_hash, 0, - sizeof (lic->ias.auth_hash)); + sizeof (ias.auth_hash)); if (GNUNET_OK != GNUNET_PQ_extract_result (result, rs, @@ -232,10 +140,12 @@ lookup_instances_cb (void *cls, lic->qs = GNUNET_DB_STATUS_HARD_ERROR; return; } - call_cb (lic); + lic->cb (lic->cb_cls, + &merchant_pub, + (no_priv) ? NULL : &merchant_priv, + &is, + &ias); GNUNET_PQ_cleanup_result (rs); - if (0 > lic->qs) - break; } } @@ -250,7 +160,6 @@ TMH_PG_lookup_instances (void *cls, struct LookupInstancesContext lic = { .cb = cb, .cb_cls = cb_cls, - .active_only = active_only, .pg = pg }; struct GNUNET_PQ_QueryParam params[] = { @@ -262,26 +171,51 @@ TMH_PG_lookup_instances (void *cls, PREPARE (pg, "lookup_instances", "SELECT" - " merchant_serial" - ",merchant_pub" - ",auth_hash" - ",auth_salt" - ",merchant_id" - ",merchant_name" - ",address" - ",jurisdiction" - ",use_stefan" - ",default_wire_transfer_delay" - ",default_pay_delay" - ",website" - ",email" - ",logo" - " FROM merchant_instances"); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - "lookup_instances", - params, - &lookup_instances_cb, - &lic); + " mi.merchant_serial" + ",mi.merchant_pub" + ",mi.auth_hash" + ",mi.auth_salt" + ",mi.merchant_id" + ",mi.merchant_name" + ",mi.address" + ",mi.jurisdiction" + ",mi.use_stefan" + ",mi.default_wire_transfer_delay" + ",mi.default_pay_delay" + ",mi.website" + ",mi.email" + ",mi.logo" + " FROM merchant_instances mi" + " LEFT JOIN merchant_keys mk" + " USING (merchant_serial)"); + PREPARE (pg, + "lookup_active_instances", + "SELECT " + " mi.merchant_serial" + ",mi.merchant_pub" + ",mi.auth_hash" + ",mi.auth_salt" + ",mi.merchant_id" + ",mi.merchant_name" + ",mi.address" + ",mi.jurisdiction" + ",mi.use_stefan" + ",mi.default_wire_transfer_delay" + ",mi.default_pay_delay" + ",mi.website" + ",mi.email" + ",mi.logo" + " FROM merchant_instances mi" + " JOIN merchant_keys mk" + " USING (merchant_serial)"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->conn, + active_only + ? "lookup_active_instances" + : "lookup_instances", + params, + &lookup_instances_cb, + &lic); if (0 > lic.qs) return lic.qs; return qs; @@ -299,7 +233,6 @@ TMH_PG_lookup_instance (void *cls, struct LookupInstancesContext lic = { .cb = cb, .cb_cls = cb_cls, - .active_only = active_only, .pg = pg }; struct GNUNET_PQ_QueryParam params[] = { @@ -312,28 +245,56 @@ TMH_PG_lookup_instance (void *cls, PREPARE (pg, "lookup_instance", "SELECT" - " merchant_serial" - ",merchant_pub" - ",auth_hash" - ",auth_salt" - ",merchant_id" - ",merchant_name" - ",user_type" - ",address" - ",jurisdiction" - ",use_stefan" - ",default_wire_transfer_delay" - ",default_pay_delay" - ",website" - ",email" - ",logo" - " FROM merchant_instances" + " mi.merchant_serial" + ",mi.merchant_pub" + ",mi.auth_hash" + ",mi.auth_salt" + ",mi.merchant_id" + ",mi.merchant_name" + ",mi.address" + ",mi.jurisdiction" + ",mi.use_stefan" + ",mi.default_wire_transfer_delay" + ",mi.default_pay_delay" + ",mi.website" + ",mi.email" + ",mi.logo" + ",mk.merchant_priv" + " FROM merchant_instances mi" + " LEFT JOIN merchant_keys mk" + " USING (merchant_serial)" + " WHERE merchant_id=$1"); + PREPARE (pg, + "lookup_active_instance", + "SELECT" + " mi.merchant_serial" + ",mi.merchant_pub" + ",mi.auth_hash" + ",mi.auth_salt" + ",mi.merchant_id" + ",mi.merchant_name" + ",mi.user_type" + ",mi.address" + ",mi.jurisdiction" + ",mi.use_stefan" + ",mi.default_wire_transfer_delay" + ",mi.default_pay_delay" + ",mi.website" + ",mi.email" + ",mi.logo" + ",mk.merchant_priv" + " FROM merchant_instances mi" + " JOIN merchant_keys mk" + " USING (merchant_serial)" " WHERE merchant_id=$1"); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - "lookup_instance", - params, - &lookup_instances_cb, - &lic); + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->conn, + active_only + ? "lookup_active_instance" + : "lookup_instance", + params, + &lookup_instances_cb, + &lic); if (0 > lic.qs) return lic.qs; return qs;