diff options
Diffstat (limited to 'src/backenddb/plugin_merchantdb_postgres.c')
-rw-r--r-- | src/backenddb/plugin_merchantdb_postgres.c | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c index 979b7eaa..11ee8db6 100644 --- a/src/backenddb/plugin_merchantdb_postgres.c +++ b/src/backenddb/plugin_merchantdb_postgres.c @@ -6816,7 +6816,263 @@ postgres_insert_pickup_blind_signature ( +/** + * Delete information about a template. + * + * @param cls closure + * @param instance_id instance to delete product of + * @param template_id template to delete + * @return DB status code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS + * if template unknow. + */ +static enum GNUNET_DB_QueryStatus +postgres_delete_template (void *cls, + const char *instance_id, + const char *template_id) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_string (template_id), + GNUNET_PQ_query_param_end + }; + + check_connection (pg); + return GNUNET_PQ_eval_prepared_non_select (pg->conn, + "delete_template", + params); +} + +/** + * Insert details about a particular template. + * + * @param cls closure + * @param instance_id instance to insert template for + * @param template_id template identifier of template to insert + * @param pd the template details to insert + * @return database result code + */ +static enum GNUNET_DB_QueryStatus +postgres_insert_template (void *cls, + const char *instance_id, + const char *template_id, + const struct TALER_MERCHANTDB_TemplateDetails *pd) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_string (template_id), + GNUNET_PQ_query_param_string (pd->template_description), + GNUNET_PQ_query_param_string (pd->image), + GNUNET_PQ_query_param_json_t (pd->template_contract), + GNUNET_PQ_query_param_end + + }; + + check_connection (pg); + return GNUNET_PQ_eval_prepared_non_select (pg->conn, + "insert_template", + params); +} + +/** + * Update details about a particular template. + * + * @param cls closure + * @param instance_id instance to update template for + * @param template_id template to update + * @param pd update to the template details on success, can be NULL + * (in that case we only want to check if the template exists) + * @return database result code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if the template + * does not yet exist. + */ +static enum GNUNET_DB_QueryStatus +postgres_update_template (void *cls, + const char *instance_id, + const char *template_id, + const struct TALER_MERCHANTDB_TemplateDetails *pd) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_string (template_id), + GNUNET_PQ_query_param_string (pd->template_description), + GNUNET_PQ_query_param_string (pd->image), + GNUNET_PQ_query_param_json_t (pd->template_contract), + GNUNET_PQ_query_param_end + }; + + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + check_connection (pg); + return GNUNET_PQ_eval_prepared_non_select (pg->conn, + "update_template", + params); +} + + + + +/** + * Context used for postgres_lookup_template(). + */ +struct LookupTemplateContext +{ + /** + * Function to call with the results. + */ + TALER_MERCHANTDB_TemplateCallback cb; + + /** + * Closure for @a cb. + */ + void *cb_cls; + + /** + * Did database result extraction fail? + */ + bool extract_failed; +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results about template. + * + * @param[in,out] cls of type `struct LookupTemplateContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lookup_templates_cb (void *cls, + PGresult *result, + unsigned int num_results) +{ + struct LookupTemplateContext *tlc = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + char *template_id; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_string ("template_id", + &template_id), + GNUNET_PQ_result_spec_string ("template_description", + &template_description), + GNUNET_PQ_result_spec_end + }; + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + tlc->extract_failed = true; + return; + } + tlc->cb (tlc->cb_cls, + template_id); + GNUNET_PQ_cleanup_result (rs); + } +} + + +/** + * Lookup all of the templates the given instance has configured. + * + * @param cls closure + * @param instance_id instance to lookup template for + * @param cb function to call on all template found + * @param cb_cls closure for @a cb + * @return database result code + */ +static enum GNUNET_DB_QueryStatus +postgres_lookup_templates (void *cls, + const char *instance_id, + TALER_MERCHANTDB_TemplateCallback cb, + void *cb_cls) +{ + struct PostgresClosure *pg = cls; + struct LookupTemplateContext tlc = { + .cb = cb, + .cb_cls = cb_cls, + /* Can be overwritten by the lookup_template_cb */ + .extract_failed = false, + }; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + check_connection (pg); + qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, + "lookup_templates", + params, + &lookup_templates_cb, + &tlc); + /* If there was an error inside lookup_template_cb, return a hard error. */ + if (tlc.extract_failed) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} + +/** + * Lookup details about a particular template. + * + * @param cls closure + * @param instance_id instance to lookup template for + * @param template_id template to lookup + * @param[out] pd set to the template details on success, can be NULL + * (in that case we only want to check if the template exists) + * @return database result code + */ +static enum GNUNET_DB_QueryStatus +postgres_lookup_template (void *cls, + const char *instance_id, + const char *template_id, + struct TALER_MERCHANTDB_TemplateDetails *pd) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_string (template_id), + GNUNET_PQ_query_param_end + }; + + if (NULL == pd) + { + struct GNUNET_PQ_ResultSpec rs_null[] = { + GNUNET_PQ_result_spec_end + }; + + check_connection (pg); + return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, + "lookup_template", + params, + rs_null); + } + else + { + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_string ("template_description", + &pd->template_description), + GNUNET_PQ_result_spec_string ("image", + &pd->image), + GNUNET_PQ_result_spec_json_t ("template_contract", + &pd->template_contract), + GNUNET_PQ_result_spec_end + }; + + check_connection (pg); + return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, + "lookup_template", + params, + rs); + } +} @@ -9267,6 +9523,59 @@ postgres_connect (void *cls) " pickup_serial, $2, $3" " FROM merchant_tip_pickups" " WHERE pickup_id=$1"), + /* for postgres_lookup_templates() */ + GNUNET_PQ_make_prepare ("lookup_templates", + "SELECT" + " template_id" + ",template_description" + " FROM merchant_template" + " JOIN merchant_instances" + " USING (merchant_serial)" + " WHERE merchant_instances.merchant_id=$1"), + /* for postgres_lookup_template() */ + GNUNET_PQ_make_prepare ("lookup_template", + "SELECT" + " template_description" + ",image" + ",template_contract" + " FROM merchant_template" + " JOIN merchant_instances" + " USING (merchant_serial)" + " WHERE merchant_instances.merchant_id=$1" + " AND merchant_template.template_id=$2"), + /* for postgres_delete_template() */ + GNUNET_PQ_make_prepare ("delete_template", + "DELETE" + " FROM merchant_template" + " WHERE merchant_template.merchant_serial=" + " (SELECT merchant_serial " + " FROM merchant_instances" + " WHERE merchant_id=$1)" + " AND merchant_template.template_id=$2" + /* for postgres_insert_template() */ + GNUNET_PQ_make_prepare ("insert_template", + "INSERT INTO merchant_template" + "(merchant_serial" + ",template_id" + ",template_description" + ",image" + ",template_contract" + ")" + " SELECT merchant_serial," + " $2, $3, $4, $5" + " FROM merchant_instances" + " WHERE merchant_id=$1"), + /* for postgres_update_template() */ + GNUNET_PQ_make_prepare ("update_template", + "UPDATE merchant_template SET" + " template_description=$3" + ",image=$4" + ",template_contract=$5" + " WHERE merchant_serial=" + " (SELECT merchant_serial" + " FROM merchant_instances" + " WHERE merchant_id=$1)" + " AND template_id=$2" GNUNET_PQ_PREPARED_STATEMENT_END }; struct GNUNET_PQ_ExecuteStatement es[] = { @@ -9416,6 +9725,11 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) plugin->insert_pickup = &postgres_insert_pickup; plugin->insert_pickup_blind_signature = &postgres_insert_pickup_blind_signature; + plugin->lookup_templates = &postgres_lookup_templates; + plugin->lookup_template = &postgres_lookup_template; + plugin->delete_template = &postgres_delete_template; + plugin->insert_template = &postgres_insert_template; + plugin->update_template = &postgres_update_template; return plugin; } |