diff --git a/include/cgimap/api06/changeset_close_handler.hpp b/include/cgimap/api06/changeset_close_handler.hpp index 3e34f827..52e5cf3c 100644 --- a/include/cgimap/api06/changeset_close_handler.hpp +++ b/include/cgimap/api06/changeset_close_handler.hpp @@ -16,6 +16,8 @@ #include "cgimap/handler.hpp" #include "cgimap/request.hpp" +struct RequestContext; + namespace api06 { class changeset_close_responder : public text_responder { @@ -24,7 +26,7 @@ class changeset_close_responder : public text_responder { data_update &, osm_changeset_id_t, const std::string &, - std::optional); + const RequestContext& req_ctx); }; class changeset_close_handler : public payload_enabled_handler { @@ -36,7 +38,7 @@ class changeset_close_handler : public payload_enabled_handler { responder_ptr_t responder(data_update &, const std::string &payload, - std::optional user_id) const override; + const RequestContext& req_ctx) const override; bool requires_selection_after_update() const override; private: diff --git a/include/cgimap/api06/changeset_create_handler.hpp b/include/cgimap/api06/changeset_create_handler.hpp index 9488a111..5d7a2288 100644 --- a/include/cgimap/api06/changeset_create_handler.hpp +++ b/include/cgimap/api06/changeset_create_handler.hpp @@ -23,7 +23,7 @@ class changeset_create_responder : public text_responder { changeset_create_responder(mime::type, data_update &, const std::string &, - std::optional); + const RequestContext& req_ctx); }; class changeset_create_handler : public payload_enabled_handler { @@ -35,7 +35,7 @@ class changeset_create_handler : public payload_enabled_handler { responder_ptr_t responder(data_update &, const std::string &payload, - std::optional user_id) const override; + const RequestContext& req_ctx) const override; bool requires_selection_after_update() const override; }; diff --git a/include/cgimap/api06/changeset_update_handler.hpp b/include/cgimap/api06/changeset_update_handler.hpp index bd845a67..acfe3342 100644 --- a/include/cgimap/api06/changeset_update_handler.hpp +++ b/include/cgimap/api06/changeset_update_handler.hpp @@ -25,7 +25,7 @@ class changeset_update_responder : public text_responder { data_update &, osm_changeset_id_t id_, const std::string & payload, - std::optional user_id); + const RequestContext& req_ctx); }; class changeset_update_sel_responder : public osm_current_responder { @@ -46,7 +46,7 @@ class changeset_update_handler : public payload_enabled_handler { responder_ptr_t responder(data_update &, const std::string &payload, - std::optional user_id) const override; + const RequestContext& req_ctx) const override; bool requires_selection_after_update() const override; private: diff --git a/include/cgimap/api06/changeset_upload_handler.hpp b/include/cgimap/api06/changeset_upload_handler.hpp index 0d7e58df..1b7fa4e4 100644 --- a/include/cgimap/api06/changeset_upload_handler.hpp +++ b/include/cgimap/api06/changeset_upload_handler.hpp @@ -16,13 +16,15 @@ #include "cgimap/osm_diffresult_responder.hpp" #include "cgimap/request.hpp" +struct RequestContext; + namespace api06 { class changeset_upload_responder : public osm_diffresult_responder { public: changeset_upload_responder(mime::type, data_update &, osm_changeset_id_t, const std::string &, - std::optional); + const RequestContext& req_ctx); }; class changeset_upload_handler : public payload_enabled_handler { @@ -34,7 +36,7 @@ class changeset_upload_handler : public payload_enabled_handler { responder_ptr_t responder(data_update &, const std::string &payload, - std::optional user_id) const override; + const RequestContext& req_ctx) const override; bool requires_selection_after_update() const override; private: diff --git a/include/cgimap/backend/apidb/changeset_upload/changeset_updater.hpp b/include/cgimap/backend/apidb/changeset_upload/changeset_updater.hpp index 6eb1129c..9ff86968 100644 --- a/include/cgimap/backend/apidb/changeset_upload/changeset_updater.hpp +++ b/include/cgimap/backend/apidb/changeset_upload/changeset_updater.hpp @@ -17,12 +17,14 @@ #include "cgimap/api06/changeset_upload/osmchange_tracking.hpp" #include "cgimap/backend/apidb/transaction_manager.hpp" +struct RequestContext; + class ApiDB_Changeset_Updater : public api06::Changeset_Updater { public: ApiDB_Changeset_Updater(Transaction_Manager &_m, - osm_changeset_id_t _changeset, - osm_user_id_t _uid); + const RequestContext& _req_ctx, + osm_changeset_id_t _changeset); ~ApiDB_Changeset_Updater() override = default; @@ -46,9 +48,9 @@ class ApiDB_Changeset_Updater : public api06::Changeset_Updater { void changeset_insert_cs (); Transaction_Manager &m; + const RequestContext& req_ctx; uint32_t cs_num_changes{0}; osm_changeset_id_t changeset; - osm_user_id_t uid; bbox_t cs_bbox{}; }; diff --git a/include/cgimap/backend/apidb/changeset_upload/node_updater.hpp b/include/cgimap/backend/apidb/changeset_upload/node_updater.hpp index fbe41997..d251cf5b 100644 --- a/include/cgimap/backend/apidb/changeset_upload/node_updater.hpp +++ b/include/cgimap/backend/apidb/changeset_upload/node_updater.hpp @@ -20,11 +20,14 @@ #include #include +struct RequestContext; + class ApiDB_Node_Updater : public api06::Node_Updater { public: ApiDB_Node_Updater(Transaction_Manager &_m, + const RequestContext& req_ctx, api06::OSMChange_Tracking &ct); ~ApiDB_Node_Updater() override = default; @@ -108,6 +111,7 @@ class ApiDB_Node_Updater : public api06::Node_Updater { void delete_current_node_tags(const std::vector &ids); Transaction_Manager &m; + const RequestContext& req_ctx; api06::OSMChange_Tracking &ct; std::vector create_nodes; diff --git a/include/cgimap/backend/apidb/changeset_upload/relation_updater.hpp b/include/cgimap/backend/apidb/changeset_upload/relation_updater.hpp index ea3fe079..afb46755 100644 --- a/include/cgimap/backend/apidb/changeset_upload/relation_updater.hpp +++ b/include/cgimap/backend/apidb/changeset_upload/relation_updater.hpp @@ -21,6 +21,8 @@ #include #include +struct RequestContext; + using RelationMemberList = std::vector; using TagList = std::map; @@ -28,6 +30,7 @@ class ApiDB_Relation_Updater : public api06::Relation_Updater { public: ApiDB_Relation_Updater(Transaction_Manager &_m, + const RequestContext& _req_ctx, api06::OSMChange_Tracking &ct); ~ApiDB_Relation_Updater() override = default; @@ -175,6 +178,7 @@ class ApiDB_Relation_Updater : public api06::Relation_Updater { const std::set &direct_relation_ids); Transaction_Manager &m; + const RequestContext& req_ctx; api06::OSMChange_Tracking &ct; std::vector create_relations; diff --git a/include/cgimap/backend/apidb/changeset_upload/way_updater.hpp b/include/cgimap/backend/apidb/changeset_upload/way_updater.hpp index 687adef1..af9e63ce 100644 --- a/include/cgimap/backend/apidb/changeset_upload/way_updater.hpp +++ b/include/cgimap/backend/apidb/changeset_upload/way_updater.hpp @@ -21,6 +21,8 @@ #include #include +struct RequestContext; + /* Way operations * */ @@ -29,6 +31,7 @@ class ApiDB_Way_Updater : public api06::Way_Updater { public: ApiDB_Way_Updater(Transaction_Manager &_m, + const RequestContext& _req_ctx, api06::OSMChange_Tracking &ct); ~ApiDB_Way_Updater() override = default; @@ -130,6 +133,7 @@ class ApiDB_Way_Updater : public api06::Way_Updater { void delete_current_way_nodes(std::vector ids); Transaction_Manager &m; + const RequestContext& req_ctx; api06::OSMChange_Tracking &ct; std::vector create_ways; diff --git a/include/cgimap/backend/apidb/pgsql_update.hpp b/include/cgimap/backend/apidb/pgsql_update.hpp index 8ecd1fc5..d1a9cf39 100644 --- a/include/cgimap/backend/apidb/pgsql_update.hpp +++ b/include/cgimap/backend/apidb/pgsql_update.hpp @@ -18,6 +18,8 @@ #include #include +struct RequestContext; + class pgsql_update : public data_update { public: @@ -26,16 +28,16 @@ class pgsql_update : public data_update { ~pgsql_update() override = default; std::unique_ptr - get_changeset_updater(osm_changeset_id_t _changeset, osm_user_id_t _uid) override; + get_changeset_updater(const RequestContext& ctx, osm_changeset_id_t _changeset) override; std::unique_ptr - get_node_updater(api06::OSMChange_Tracking &ct) override; + get_node_updater(const RequestContext& ctx, api06::OSMChange_Tracking &ct) override; std::unique_ptr - get_way_updater(api06::OSMChange_Tracking &ct) override; + get_way_updater(const RequestContext& ctx, api06::OSMChange_Tracking &ct) override; std::unique_ptr - get_relation_updater(api06::OSMChange_Tracking &ct) override; + get_relation_updater(const RequestContext& ctx, api06::OSMChange_Tracking &ct) override; void commit() override; diff --git a/include/cgimap/data_update.hpp b/include/cgimap/data_update.hpp index 71586598..0d3841e0 100644 --- a/include/cgimap/data_update.hpp +++ b/include/cgimap/data_update.hpp @@ -24,6 +24,8 @@ #include #include +struct RequestContext; + class data_update { public: data_update() = default; @@ -37,16 +39,16 @@ class data_update { data_update& operator=(data_update&&) = delete; virtual std::unique_ptr - get_changeset_updater(osm_changeset_id_t _changeset, osm_user_id_t _uid) = 0; + get_changeset_updater(const RequestContext& ctx, osm_changeset_id_t _changeset) = 0; virtual std::unique_ptr - get_node_updater(api06::OSMChange_Tracking &ct) = 0; + get_node_updater(const RequestContext& ctx, api06::OSMChange_Tracking &ct) = 0; virtual std::unique_ptr - get_way_updater(api06::OSMChange_Tracking &ct) = 0; + get_way_updater(const RequestContext& ctx, api06::OSMChange_Tracking &ct) = 0; virtual std::unique_ptr - get_relation_updater(api06::OSMChange_Tracking &ct) = 0; + get_relation_updater(const RequestContext& ctx, api06::OSMChange_Tracking &ct) = 0; virtual void commit() = 0; diff --git a/include/cgimap/handler.hpp b/include/cgimap/handler.hpp index 873e9309..3cb94983 100644 --- a/include/cgimap/handler.hpp +++ b/include/cgimap/handler.hpp @@ -96,7 +96,7 @@ class payload_enabled_handler : public handler { // Responder used to update the database virtual responder_ptr_t responder(data_update &, const std::string & payload, - std::optional user_id) const = 0; + const RequestContext& req_ctx) const = 0; // Optional responder to return XML response back to caller of the API method responder_ptr_t responder(data_selection &) const override = 0; diff --git a/include/cgimap/request_context.hpp b/include/cgimap/request_context.hpp new file mode 100644 index 00000000..f3e35051 --- /dev/null +++ b/include/cgimap/request_context.hpp @@ -0,0 +1,38 @@ +/** + * SPDX-License-Identifier: GPL-2.0-only + * + * This file is part of openstreetmap-cgimap (https://github.com/zerebubuth/openstreetmap-cgimap/). + * + * Copyright (C) 2009-2024 by the CGImap developer community. + * For a full list of authors see the git log. + */ + +#ifndef REQUEST_CONTEXT_HPP +#define REQUEST_CONTEXT_HPP + +#include "cgimap/types.hpp" +// #include "cgimap/request.hpp" + +#include +#include +#include + +struct request; + +struct UserInfo +{ + osm_user_id_t id = {}; + std::set user_roles = {}; + bool allow_api_write = false; + + bool has_role(osm_user_role_t role) const { return user_roles.count(role) > 0; } +}; + +struct RequestContext +{ + request* req = nullptr; + std::chrono::system_clock::time_point start_time = {}; + std::optional user = {}; +}; + +#endif /* REQUEST_CONTEXT_HPP */ diff --git a/include/cgimap/request_helpers.hpp b/include/cgimap/request_helpers.hpp index 83e3c4cd..e4ef6987 100644 --- a/include/cgimap/request_helpers.hpp +++ b/include/cgimap/request_helpers.hpp @@ -10,9 +10,10 @@ #ifndef REQUEST_HELPERS_HPP #define REQUEST_HELPERS_HPP -#include #include "cgimap/request.hpp" #include "cgimap/http.hpp" + +#include #include /** diff --git a/src/api06/changeset_close_handler.cpp b/src/api06/changeset_close_handler.cpp index 80ce9cad..e6d65547 100644 --- a/src/api06/changeset_close_handler.cpp +++ b/src/api06/changeset_close_handler.cpp @@ -29,10 +29,10 @@ changeset_close_responder::changeset_close_responder(mime::type mt, data_update & upd, osm_changeset_id_t changeset, const std::string &, - std::optional user_id) + const RequestContext& req_ctx) : text_responder(mt) { - auto changeset_updater = upd.get_changeset_updater(changeset, *user_id); + auto changeset_updater = upd.get_changeset_updater(req_ctx, changeset); changeset_updater->api_close_changeset(); upd.commit(); } @@ -55,8 +55,8 @@ responder_ptr_t changeset_close_handler::responder(data_selection &) const { responder_ptr_t changeset_close_handler::responder(data_update & upd, const std::string &payload, - std::optional user_id) const { - return std::make_unique(mime_type, upd, id, payload, user_id); + const RequestContext& req_ctx) const { + return std::make_unique(mime_type, upd, id, payload, req_ctx); } bool changeset_close_handler::requires_selection_after_update() const { diff --git a/src/api06/changeset_create_handler.cpp b/src/api06/changeset_create_handler.cpp index 38d582c8..b22cb773 100644 --- a/src/api06/changeset_create_handler.cpp +++ b/src/api06/changeset_create_handler.cpp @@ -28,12 +28,12 @@ namespace api06 { changeset_create_responder::changeset_create_responder(mime::type mt, data_update & upd, const std::string &payload, - std::optional user_id) + const RequestContext& req_ctx) : text_responder(mt) { osm_changeset_id_t changeset = 0; - auto changeset_updater = upd.get_changeset_updater(changeset, *user_id); + auto changeset_updater = upd.get_changeset_updater(req_ctx, changeset); auto tags = ChangesetXMLParser().process_message(payload); changeset = changeset_updater->api_create_changeset(tags); @@ -56,8 +56,8 @@ changeset_create_handler::responder(data_selection &) const { responder_ptr_t changeset_create_handler::responder(data_update & upd, const std::string &payload, - std::optional user_id) const { - return std::make_unique(mime_type, upd, payload, user_id); + const RequestContext& req_ctx) const { + return std::make_unique(mime_type, upd, payload, req_ctx); } bool changeset_create_handler::requires_selection_after_update() const { diff --git a/src/api06/changeset_update_handler.cpp b/src/api06/changeset_update_handler.cpp index b29c0048..a99375c7 100644 --- a/src/api06/changeset_update_handler.cpp +++ b/src/api06/changeset_update_handler.cpp @@ -30,10 +30,10 @@ changeset_update_responder::changeset_update_responder( data_update &upd, osm_changeset_id_t changeset_id, const std::string &payload, - std::optional user_id) + const RequestContext& req_ctx) : text_responder(mt){ - auto changeset_updater = upd.get_changeset_updater(changeset_id, *user_id); + auto changeset_updater = upd.get_changeset_updater(req_ctx, changeset_id); auto tags = ChangesetXMLParser().process_message(payload); @@ -69,8 +69,8 @@ changeset_update_handler::responder(data_selection &sel) const { responder_ptr_t changeset_update_handler::responder(data_update & upd, const std::string &payload, - std::optional user_id) const { - return std::make_unique(mime_type, upd, id, payload, user_id); + const RequestContext& req_ctx) const { + return std::make_unique(mime_type, upd, id, payload, req_ctx); } bool changeset_update_handler::requires_selection_after_update() const { diff --git a/src/api06/changeset_upload_handler.cpp b/src/api06/changeset_upload_handler.cpp index b892d171..40695e16 100644 --- a/src/api06/changeset_upload_handler.cpp +++ b/src/api06/changeset_upload_handler.cpp @@ -10,6 +10,7 @@ #include "cgimap/http.hpp" #include "cgimap/logger.hpp" #include "cgimap/request_helpers.hpp" +#include "cgimap/request_context.hpp" #include "cgimap/api06/changeset_upload/osmchange_handler.hpp" #include "cgimap/api06/changeset_upload/osmchange_input_format.hpp" @@ -24,6 +25,8 @@ #include "cgimap/types.hpp" #include "cgimap/util.hpp" +#include + #include namespace api06 { @@ -32,15 +35,20 @@ changeset_upload_responder::changeset_upload_responder(mime::type mt, data_update& upd, osm_changeset_id_t changeset, const std::string &payload, - std::optional user_id) + const RequestContext& req_ctx) : osm_diffresult_responder(mt) { + + if (!req_ctx.user.has_value()) + { + throw http::server_error("Cannot upload to changeset - no user id"); + } OSMChange_Tracking change_tracking{}; - auto changeset_updater = upd.get_changeset_updater(changeset, *user_id); - auto node_updater = upd.get_node_updater(change_tracking); - auto way_updater = upd.get_way_updater(change_tracking); - auto relation_updater = upd.get_relation_updater(change_tracking); + auto changeset_updater = upd.get_changeset_updater(req_ctx, changeset); + auto node_updater = upd.get_node_updater(req_ctx, change_tracking); + auto way_updater = upd.get_way_updater(req_ctx, change_tracking); + auto relation_updater = upd.get_relation_updater(req_ctx, change_tracking); changeset_updater->lock_current_changeset(true); @@ -57,13 +65,13 @@ changeset_upload_responder::changeset_upload_responder(mime::type mt, if (global_settings::get_ratelimiter_upload()) { - auto max_changes = upd.get_rate_limit(*user_id); + auto max_changes = upd.get_rate_limit((*req_ctx.user).id); if (new_changes > max_changes) { logger::message( fmt::format( "Upload of {} changes by user {} in changeset {} blocked due to rate limiting, max. {} changes allowed", - new_changes, *user_id, changeset, max_changes)); + new_changes, (*req_ctx.user).id, changeset, max_changes)); throw http::too_many_requests("Upload has been blocked due to rate limiting. Please try again later."); } } @@ -90,8 +98,8 @@ responder_ptr_t changeset_upload_handler::responder(data_selection &) const { responder_ptr_t changeset_upload_handler::responder(data_update & upd, const std::string &payload, - std::optional user_id) const { - return std::make_unique(mime_type, upd, id, payload, user_id); + const RequestContext& req_ctx) const { + return std::make_unique(mime_type, upd, id, payload, req_ctx); } bool changeset_upload_handler::requires_selection_after_update() const { diff --git a/src/backend/apidb/changeset_upload/changeset_updater.cpp b/src/backend/apidb/changeset_upload/changeset_updater.cpp index 0caf45a1..e7e9b9d5 100644 --- a/src/backend/apidb/changeset_upload/changeset_updater.cpp +++ b/src/backend/apidb/changeset_upload/changeset_updater.cpp @@ -12,6 +12,7 @@ #include "cgimap/http.hpp" #include "cgimap/logger.hpp" #include "cgimap/options.hpp" +#include "cgimap/request_context.hpp" #include #include @@ -20,12 +21,17 @@ ApiDB_Changeset_Updater::ApiDB_Changeset_Updater(Transaction_Manager &_m, - osm_changeset_id_t _changeset, - osm_user_id_t _uid) + const RequestContext& _req_ctx, + osm_changeset_id_t _changeset) : m(_m), - changeset(_changeset), - uid(_uid) -{} + req_ctx(_req_ctx), + changeset(_changeset) +{ + if (!req_ctx.user.has_value()) + { + throw http::server_error("Cannot create changeset - no user id"); + } +} void ApiDB_Changeset_Updater::lock_current_changeset(bool check_max_elements_limit) { @@ -146,7 +152,7 @@ ApiDB_Changeset_Updater::changeset_update_users_cs_count () SET "changesets_count" = COALESCE("changesets_count", 0) + 1 WHERE "id" = $1 )"); - pqxx::result r = m.exec_prepared ("update_users", uid); + pqxx::result r = m.exec_prepared ("update_users", (*req_ctx.user).id); if (r.affected_rows () != 1) throw http::server_error ( "Cannot create changeset - update changesets_count"); @@ -186,7 +192,7 @@ void ApiDB_Changeset_Updater::api_close_changeset() SET closed_at = now() at time zone 'utc' WHERE id = $1 AND user_id = $2 )"); - auto r = m.exec_prepared("changeset_close", changeset, uid); + auto r = m.exec_prepared("changeset_close", changeset, (*req_ctx.user).id); if (r.affected_rows() != 1) throw http::server_error("Cannot close changeset"); @@ -213,7 +219,7 @@ void ApiDB_Changeset_Updater::lock_cs(bool& is_closed, std::string& closed_at, s FOR UPDATE )"); - auto r = m.exec_prepared("changeset_current_lock", changeset, uid); + auto r = m.exec_prepared("changeset_current_lock", changeset, (*req_ctx.user).id); if (r.affected_rows () != 1) throw http::conflict ("The user doesn't own that changeset"); @@ -244,7 +250,7 @@ void ApiDB_Changeset_Updater::check_user_owns_changeset() if (r.affected_rows () != 1) throw http::not_found (""); - if (r[0]["user_id"].as () != uid) + if (r[0]["user_id"].as () != (*req_ctx.user).id) throw http::conflict ("The user doesn't own that changeset"); } @@ -259,7 +265,7 @@ void ApiDB_Changeset_Updater::changeset_insert_subscriber () INSERT INTO "changesets_subscribers" ("subscriber_id", "changeset_id") VALUES ($1, $2) )"); - pqxx::result r = m.exec_prepared ("insert_changeset_subscribers", uid, + pqxx::result r = m.exec_prepared ("insert_changeset_subscribers", (*req_ctx.user).id, changeset); if (r.affected_rows () != 1) throw http::server_error ( @@ -337,7 +343,7 @@ void ApiDB_Changeset_Updater::changeset_insert_cs () RETURNING id )"); - pqxx::result r = m.exec_prepared ("create_changeset", uid, global_settings::get_changeset_timeout_idle()); + pqxx::result r = m.exec_prepared ("create_changeset", (*req_ctx.user).id, global_settings::get_changeset_timeout_idle()); if (r.affected_rows () != 1) throw http::server_error ("Cannot create changeset"); diff --git a/src/backend/apidb/changeset_upload/node_updater.cpp b/src/backend/apidb/changeset_upload/node_updater.cpp index 3e124ae6..0b6792da 100644 --- a/src/backend/apidb/changeset_upload/node_updater.cpp +++ b/src/backend/apidb/changeset_upload/node_updater.cpp @@ -16,6 +16,7 @@ #include "cgimap/logger.hpp" #include "cgimap/options.hpp" #include "cgimap/util.hpp" +#include "cgimap/request_helpers.hpp" #include @@ -32,8 +33,10 @@ ApiDB_Node_Updater::ApiDB_Node_Updater(Transaction_Manager &_m, + const RequestContext& _req_ctx, api06::OSMChange_Tracking &ct) : m(_m), + req_ctx(_req_ctx), ct(ct) {} diff --git a/src/backend/apidb/changeset_upload/relation_updater.cpp b/src/backend/apidb/changeset_upload/relation_updater.cpp index fc804fb2..d08315d6 100644 --- a/src/backend/apidb/changeset_upload/relation_updater.cpp +++ b/src/backend/apidb/changeset_upload/relation_updater.cpp @@ -28,8 +28,10 @@ ApiDB_Relation_Updater::ApiDB_Relation_Updater(Transaction_Manager &_m, + const RequestContext& _req_ctx, api06::OSMChange_Tracking &ct) : m(_m), + req_ctx(_req_ctx), ct(ct) {} diff --git a/src/backend/apidb/changeset_upload/way_updater.cpp b/src/backend/apidb/changeset_upload/way_updater.cpp index 1064f6f0..661e0d46 100644 --- a/src/backend/apidb/changeset_upload/way_updater.cpp +++ b/src/backend/apidb/changeset_upload/way_updater.cpp @@ -15,6 +15,7 @@ #include "cgimap/logger.hpp" #include "cgimap/options.hpp" #include "cgimap/util.hpp" +#include "cgimap/request_helpers.hpp" #include #include @@ -30,8 +31,10 @@ ApiDB_Way_Updater::ApiDB_Way_Updater(Transaction_Manager &_m, + const RequestContext& _req_ctx, api06::OSMChange_Tracking &ct) : m(_m), + req_ctx(_req_ctx), ct(ct) {} diff --git a/src/backend/apidb/pgsql_update.cpp b/src/backend/apidb/pgsql_update.cpp index 9a981c7d..9ae6ef76 100644 --- a/src/backend/apidb/pgsql_update.cpp +++ b/src/backend/apidb/pgsql_update.cpp @@ -24,6 +24,8 @@ namespace po = boost::program_options; +struct RequestContext; + namespace { std::string connect_db_str(const po::variables_map &options) { // build the connection string. @@ -107,27 +109,27 @@ bool pgsql_update::is_api_write_disabled() const { } std::unique_ptr -pgsql_update::get_changeset_updater(osm_changeset_id_t changeset, osm_user_id_t uid) +pgsql_update::get_changeset_updater(const RequestContext& req_ctx, osm_changeset_id_t changeset) { - return std::make_unique(m, changeset, uid); + return std::make_unique(m, req_ctx, changeset); } std::unique_ptr -pgsql_update::get_node_updater(api06::OSMChange_Tracking &ct) +pgsql_update::get_node_updater(const RequestContext& req_ctx, api06::OSMChange_Tracking &ct) { - return std::make_unique(m, ct); + return std::make_unique(m, req_ctx, ct); } std::unique_ptr -pgsql_update::get_way_updater(api06::OSMChange_Tracking &ct) +pgsql_update::get_way_updater(const RequestContext& req_ctx, api06::OSMChange_Tracking &ct) { - return std::make_unique(m, ct); + return std::make_unique(m, req_ctx, ct); } std::unique_ptr -pgsql_update::get_relation_updater(api06::OSMChange_Tracking &ct) +pgsql_update::get_relation_updater(const RequestContext& req_ctx, api06::OSMChange_Tracking &ct) { - return std::make_unique(m, ct); + return std::make_unique(m, req_ctx, ct); } void pgsql_update::commit() { diff --git a/src/process_request.cpp b/src/process_request.cpp index 9d56a1c4..1fbbef53 100644 --- a/src/process_request.cpp +++ b/src/process_request.cpp @@ -11,6 +11,7 @@ #include "cgimap/http.hpp" #include "cgimap/logger.hpp" #include "cgimap/request_helpers.hpp" +#include "cgimap/request_context.hpp" #include "cgimap/choose_formatter.hpp" #include "cgimap/output_formatter.hpp" #include "cgimap/output_writer.hpp" @@ -261,11 +262,13 @@ process_get_request(request &req, const handler& handler, * process a POST/PUT request. */ std::tuple -process_post_put_request(request &req, const handler& handler, - const data_selection::factory& factory, - data_update::factory& update_factory, - std::optional user_id, - const string &ip, const string &generator) { +process_post_put_request(request &req, + RequestContext& req_ctx, + const handler& handler, + const data_selection::factory& factory, + data_update::factory& update_factory, + const string &ip, + const string &generator) { std::size_t bytes_written = 0; @@ -285,7 +288,7 @@ process_post_put_request(request &req, const handler& handler, // Executing the responder constructor parses the payload, performs db CRUD operations // and eventually calls db commit(), in case there are no issues with the data. - auto responder = pe_handler.responder(*data_update, payload, user_id); + auto responder = pe_handler.responder(*data_update, payload, req_ctx); // does the responder instance carry all the data which is needed to construct a response? if (!pe_handler.requires_selection_after_update()) @@ -422,7 +425,7 @@ std::optional determine_user_id (const request& req, bool& allow_api_write) { // Try to authenticate user via OAuth2 Bearer Token - std::optional user_id = oauth2::validate_bearer_token (req, selection, allow_api_write); + std::optional user_id = oauth2::validate_bearer_token(req, selection, allow_api_write); return user_id; } @@ -438,7 +441,7 @@ void process_request(request &req, rate_limiter &limiter, data_update::factory* update_factory) { try { - + RequestContext req_ctx{}; // get the client IP address const std::string ip = fcgi_get_env(req, "REMOTE_ADDR"); @@ -462,7 +465,6 @@ void process_request(request &req, rate_limiter &limiter, // ------ - std::set user_roles; bool allow_api_write = true; @@ -471,7 +473,7 @@ void process_request(request &req, rate_limiter &limiter, // create a data selection for the request auto selection = factory.make_selection(*default_transaction); - std::optional user_id = determine_user_id (req, *selection, allow_api_write); + std::optional user_id = determine_user_id(req, *selection, allow_api_write); // Initially assume IP based client key string client_key = addr_prefix + ip; @@ -480,10 +482,14 @@ void process_request(request &req, rate_limiter &limiter, // set the client key and user roles accordingly if (user_id) { client_key = (fmt::format("{}{}", user_prefix, (*user_id))); - user_roles = selection->get_roles_for_user(*user_id); + + // C++20: switch to designated initializer for readability + req_ctx.user = UserInfo{ *user_id, + selection->get_roles_for_user(*user_id), + allow_api_write }; } - auto is_moderator = user_roles.count(osm_user_role_t::moderator) > 0; + auto is_moderator = req_ctx.user && (*req_ctx.user).has_role(osm_user_role_t::moderator); bool exceeded_limit; int retry_seconds; @@ -495,6 +501,7 @@ void process_request(request &req, rate_limiter &limiter, } auto start_time = std::chrono::high_resolution_clock::now(); + req_ctx.start_time = start_time; if (is_moderator && show_redactions_requested(req)) { selection->set_redactions_visible(true); @@ -524,7 +531,7 @@ void process_request(request &req, rate_limiter &limiter, throw http::bad_request("Backend does not support given HTTP method"); std::tie(request_name, bytes_written) = - process_post_put_request(req, *handler, factory, *update_factory, user_id, ip, generator); + process_post_put_request(req, req_ctx, *handler, factory, *update_factory, ip, generator); } break; diff --git a/test/test_apidb_backend_changeset_uploads.cpp b/test/test_apidb_backend_changeset_uploads.cpp index 3e99b0f9..f47c5a1a 100644 --- a/test/test_apidb_backend_changeset_uploads.cpp +++ b/test/test_apidb_backend_changeset_uploads.cpp @@ -31,6 +31,7 @@ #include "cgimap/process_request.hpp" #include "cgimap/output_buffer.hpp" #include "cgimap/zlib.hpp" +#include "cgimap/request_context.hpp" #include "cgimap/api06/changeset_upload/osmchange_handler.hpp" #include "cgimap/api06/changeset_upload/osmchange_input_format.hpp" @@ -154,9 +155,10 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_nodes", "[changeset][upload SECTION("Create new node") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); node_updater->add_node(-25.3448570, 131.0325171, 1, -1, { {"name", "Uluṟu"}, {"ele", "863"} }); node_updater->process_new_nodes(); @@ -211,10 +213,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_nodes", "[changeset][upload SECTION("Create two nodes with the same old_id") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); node_updater->add_node(0, 0 , 1, -2, {}); node_updater->add_node(10, 20 , 1, -2, {}); @@ -224,9 +227,10 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_nodes", "[changeset][upload SECTION("Change existing node") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); node_updater->modify_node(10, 20, 1, node_id, node_version, {}); node_updater->process_modify_nodes(); @@ -278,10 +282,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_nodes", "[changeset][upload SECTION("Change existing node with incorrect version number") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); node_updater->modify_node(40, 50, 1, node_id, 666, {}); REQUIRE_THROWS_MATCHES(node_updater->process_modify_nodes(), http::conflict, @@ -290,9 +295,10 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_nodes", "[changeset][upload SECTION("Change existing node multiple times") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); int sign = -1; @@ -343,10 +349,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_nodes", "[changeset][upload SECTION("Delete existing node") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); node_updater->delete_node(1, node_id, node_version++, false); node_updater->process_delete_nodes(); @@ -383,10 +390,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_nodes", "[changeset][upload SECTION("Try to delete already deleted node (if-unused not set)") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); node_updater->delete_node(1, node_id, node_version, false); REQUIRE_THROWS_AS(node_updater->process_delete_nodes(), http::gone); @@ -394,10 +402,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_nodes", "[changeset][upload SECTION("Try to delete already deleted node (if-unused set)") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); node_updater->delete_node(1, node_id, node_version, true); REQUIRE_NOTHROW(node_updater->process_delete_nodes()); @@ -408,10 +417,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_nodes", "[changeset][upload SECTION("Delete non-existing node") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); node_updater->delete_node(1, 424471234567890, 1, false); REQUIRE_THROWS_MATCHES(node_updater->process_delete_nodes(), http::not_found, @@ -420,10 +430,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_nodes", "[changeset][upload SECTION("Modify non-existing node") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); node_updater->modify_node(40, 50, 1, 4712334567890, 1, {}); REQUIRE_THROWS_MATCHES(node_updater->process_modify_nodes(), http::not_found, @@ -456,10 +467,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_ways", "[changeset][upload] SECTION("Create new way with two nodes") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); - auto way_updater = upd->get_way_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); node_updater->add_node(-25.3448570, 131.0325171, 1, -1, { {"name", "Uluṟu"}, {"ele", "863"} }); node_updater->add_node(-25.3448570, 131.2325171, 1, -2, { }); @@ -525,11 +537,12 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_ways", "[changeset][upload] SECTION("Create two ways with the same old_id must fail") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); - auto way_updater = upd->get_way_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); node_updater->add_node(0, 0 , 1, -1, {}); @@ -544,10 +557,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_ways", "[changeset][upload] SECTION("Create way with unknown placeholder ids") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); way_updater->add_way(1, -1, { -1, -2}, { {"highway", "path"}}); REQUIRE_THROWS_MATCHES(way_updater->process_new_ways(), http::bad_request, @@ -556,9 +570,10 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_ways", "[changeset][upload] SECTION("Change existing way") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); way_updater->modify_way(1, way_id, way_version, { static_cast(node_new_ids[2]) }, @@ -572,12 +587,13 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_ways", "[changeset][upload] // foreign key relationship on the current_way_nodes table (current_way_nodes_node_id_fkey). auto future = std::async(std::launch::async, [&] { + RequestContext ctx2{}; api06::OSMChange_Tracking change_tracking_2nd{}; auto factory = tdb.get_new_data_update_factory(); auto txn_2nd = factory->get_default_transaction(); auto upd_2nd = factory->make_data_update(*txn_2nd); - auto node_updater = upd_2nd->get_node_updater(change_tracking_2nd); + auto node_updater = upd_2nd->get_node_updater(ctx2, change_tracking_2nd); node_updater->delete_node(2, static_cast(node_new_ids[2]), 1, false); // throws precondition_failed exception once the main process commits and releases the lock. node_updater->process_delete_nodes(); @@ -640,10 +656,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_ways", "[changeset][upload] SECTION("Change existing way with incorrect version number") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); way_updater->modify_way(1, way_id, 666, {static_cast(node_new_ids[0])}, {}); REQUIRE_THROWS_MATCHES(way_updater->process_modify_ways(), http::conflict, @@ -652,10 +669,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_ways", "[changeset][upload] SECTION("Change existing way with incorrect version number and non-existing node id") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); way_updater->modify_way(1, way_id, 666, {static_cast(5934531745)}, {}); REQUIRE_THROWS_MATCHES(way_updater->process_modify_ways(), http::conflict, @@ -664,10 +682,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_ways", "[changeset][upload] SECTION("Change existing way with unknown node id") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); way_updater->modify_way(1, way_id, way_version, {static_cast(node_new_ids[0]), 9574853485634}, {}); REQUIRE_THROWS_MATCHES(way_updater->process_modify_ways(), http::precondition_failed, @@ -676,10 +695,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_ways", "[changeset][upload] SECTION("Change existing way with unknown placeholder node id") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); way_updater->modify_way(1, way_id, way_version, {-5}, {}); REQUIRE_THROWS_MATCHES(way_updater->process_modify_ways(), http::bad_request, @@ -688,10 +708,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_ways", "[changeset][upload] SECTION("TODO: Change existing way multiple times") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); @@ -700,10 +721,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_ways", "[changeset][upload] SECTION("Try to delete node which still belongs to way, if-unused not set") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); node_updater->delete_node(1, node_new_ids[2], 1, false); REQUIRE_THROWS_MATCHES(node_updater->process_delete_nodes(), http::precondition_failed, @@ -712,10 +734,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_ways", "[changeset][upload] SECTION("Try to delete node which still belongs to way, if-unused set") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); node_updater->delete_node(1, node_new_ids[2], 1, true); REQUIRE_NOTHROW(node_updater->process_delete_nodes()); @@ -726,10 +749,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_ways", "[changeset][upload] SECTION("Delete existing way") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); way_updater->delete_way(1, way_id, way_version++, false); way_updater->process_delete_ways(); @@ -763,10 +787,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_ways", "[changeset][upload] SECTION("Try to delete already deleted node (if-unused not set)") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); way_updater->delete_way(1, way_id, way_version, false); REQUIRE_THROWS_MATCHES(way_updater->process_delete_ways(), http::gone, @@ -775,10 +800,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_ways", "[changeset][upload] SECTION("Try to delete already deleted node (if-unused set)") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); way_updater->delete_way(1, way_id, way_version, true); @@ -789,10 +815,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_ways", "[changeset][upload] SECTION("Delete non-existing way") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); way_updater->delete_way(1, 424471234567890, 1, false); REQUIRE_THROWS_MATCHES(way_updater->process_delete_ways(), http::not_found, @@ -801,10 +828,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_ways", "[changeset][upload] SECTION("Modify non-existing way") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); way_updater->modify_way(1, 424471234567890, 1, {static_cast(node_new_ids[0])}, {}); REQUIRE_THROWS_MATCHES(way_updater->process_modify_ways(), http::not_found, @@ -843,12 +871,13 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Create new relation with two nodes, and one way") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); - auto way_updater = upd->get_way_updater(change_tracking); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); node_updater->add_node(-25.3448570, 131.0325171, 1, -1, { {"name", "Uluṟu"}, {"ele", "863"} }); node_updater->add_node(-25.3448570, 131.2325171, 1, -2, { }); @@ -942,11 +971,12 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Create new relation with two nodes, and one way, only placeholder ids") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); - auto way_updater = upd->get_way_updater(change_tracking); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); node_updater->add_node(-25.3448570, 131.0325171, 1, -1, { {"name", "Uluṟu"} }); node_updater->add_node(-25.3448570, 131.2325171, 1, -2, { }); @@ -1036,10 +1066,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Create two relations with the same old_id") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->add_relation(1, -1, {}, {}); rel_updater->add_relation(1, -1, {}, {{"key", "value"}}); @@ -1049,10 +1080,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Create one relation with self reference") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->add_relation(1, -1, { { "Relation", -1, "role1" }}, {{"key1", "value1"}}); REQUIRE_THROWS_MATCHES(rel_updater->process_new_relations(), http::bad_request, @@ -1061,10 +1093,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Create two relations with references to each other") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->add_relation(1, -1, { { "Relation", -2, "role1" }}, {{"key1", "value1"}}); rel_updater->add_relation(1, -2, { { "Relation", -1, "role2" }}, {{"key2", "value2"}}); @@ -1074,10 +1107,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Create two relations with parent/child relationship") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->add_relation(1, -1, { }, {{"key1", "value1"}}); rel_updater->add_relation(1, -2, { { "Relation", -1, "role2" }}, {{"key2", "value2"}}); @@ -1119,10 +1153,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Create relation with unknown node placeholder id") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->add_relation(1, -1, { { "Node", -10, "role1" }}, {{"key1", "value1"}}); REQUIRE_THROWS_MATCHES(rel_updater->process_new_relations(), http::bad_request, @@ -1131,10 +1166,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Create relation with unknown way placeholder id") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->add_relation(1, -1, { { "Way", -10, "role1" }}, {{"key1", "value1"}}); REQUIRE_THROWS_MATCHES(rel_updater->process_new_relations(), http::bad_request, @@ -1143,10 +1179,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Create relation with unknown relation placeholder id") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->add_relation(1, -1, { { "Relation", -10, "role1" }}, {{"key1", "value1"}}); REQUIRE_THROWS_MATCHES(rel_updater->process_new_relations(), http::bad_request, @@ -1155,10 +1192,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Change existing relation") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->modify_relation(1, relation_id, relation_version, { @@ -1225,10 +1263,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Change existing relation with incorrect version number") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->modify_relation(1, relation_id, 666, { {"Node", static_cast(node_new_ids[0]), ""} }, {}); @@ -1238,10 +1277,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Change existing relation with incorrect version number and non-existing node id") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->modify_relation(1, relation_id, 666, { {"Node", static_cast(1434253485634), ""} }, {}); REQUIRE_THROWS_MATCHES(rel_updater->process_modify_relations(), http::conflict, @@ -1250,11 +1290,12 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Change existing relation with unknown node id") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->modify_relation(1, relation_id, relation_version, { {"Node", 1434253485634, ""} }, {}); REQUIRE_THROWS_MATCHES(rel_updater->process_modify_relations(), http::precondition_failed, @@ -1263,10 +1304,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Change existing relation with unknown way id") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->modify_relation(1, relation_id, relation_version, { {"Way", 9574853485634, ""} }, {}); REQUIRE_THROWS_MATCHES(rel_updater->process_modify_relations(), http::precondition_failed, @@ -1275,10 +1317,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Change existing relation with unknown relation id") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->modify_relation(1, relation_id, relation_version, { {"Relation", 9574853485634, ""} }, {}); REQUIRE_THROWS_MATCHES(rel_updater->process_modify_relations(), http::precondition_failed, @@ -1287,11 +1330,12 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Change existing relation with unknown node placeholder id") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->modify_relation(1, relation_id, relation_version, { {"Node", -10, ""} }, {}); REQUIRE_THROWS_MATCHES(rel_updater->process_modify_relations(), http::bad_request, @@ -1300,10 +1344,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Change existing relation with unknown way placeholder id") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->modify_relation(1, relation_id, relation_version, { {"Way", -10, ""} }, {}); REQUIRE_THROWS_MATCHES(rel_updater->process_modify_relations(), http::bad_request, @@ -1312,10 +1357,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Change existing relation with unknown relation placeholder id") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->modify_relation(1, relation_id, relation_version, { {"Relation", -10, ""} }, {}); REQUIRE_THROWS_MATCHES(rel_updater->process_modify_relations(), http::bad_request, @@ -1324,11 +1370,12 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("TODO: Change existing relation multiple times") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); @@ -1336,9 +1383,10 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Preparation for next test case: create a new relation with node_new_ids[2] as only member") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->add_relation(1, -1, { @@ -1352,10 +1400,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Try to delete node which still belongs to relation, if-unused not set") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); node_updater->delete_node(1, node_new_ids[2], 1, false); REQUIRE_THROWS_MATCHES(node_updater->process_delete_nodes(), http::precondition_failed, @@ -1364,10 +1413,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Try to delete node which still belongs to relation, if-unused set") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); node_updater->delete_node(1, node_new_ids[2], 1, true); REQUIRE_NOTHROW(node_updater->process_delete_nodes()); @@ -1379,10 +1429,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Try to delete way which still belongs to relation, if-unused not set") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); way_updater->delete_way(1, way_new_id, 1, false); REQUIRE_THROWS_MATCHES(way_updater->process_delete_ways(), http::precondition_failed, @@ -1391,10 +1442,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Try to delete way which still belongs to relation, if-unused set") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto way_updater = upd->get_way_updater(change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); way_updater->delete_way(1, way_new_id, 1, true); REQUIRE_NOTHROW(way_updater->process_delete_ways()); @@ -1406,10 +1458,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Try to delete relation which still belongs to relation, if-unused not set") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->delete_relation(1, relation_id_1, relation_version_1, false); REQUIRE_THROWS_MATCHES(rel_updater->process_delete_relations(), http::precondition_failed, @@ -1418,10 +1471,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Try to delete relation which still belongs to relation, if-unused set") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->delete_relation(1, relation_id_1, relation_version_1, true); REQUIRE_NOTHROW(rel_updater->process_delete_relations()); @@ -1434,9 +1488,10 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Delete existing relation") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->delete_relation(1, relation_id, relation_version++, false); rel_updater->process_delete_relations(); @@ -1471,10 +1526,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Delete two relations with references to each other") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->delete_relation(1, relation_id_1, relation_version_1, false); rel_updater->delete_relation(1, relation_id_2, relation_version_2, false); @@ -1491,10 +1547,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Revert deletion of two relations with master/child relationship") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->modify_relation(1, relation_id_1, relation_version_1, @@ -1507,10 +1564,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Try to delete already deleted relation (if-unused not set)") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->delete_relation(1, relation_id, relation_version, false); REQUIRE_THROWS_MATCHES(rel_updater->process_delete_relations(), http::gone, @@ -1519,10 +1577,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Try to delete already deleted relation (if-unused set)") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->delete_relation(1, relation_id, relation_version, true); REQUIRE_NOTHROW(rel_updater->process_delete_relations()); @@ -1533,10 +1592,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Delete non-existing relation") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->delete_relation(1, 424471234567890, 1, false); REQUIRE_THROWS_MATCHES(rel_updater->process_delete_relations(), http::not_found, @@ -1545,10 +1605,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Modify non-existing relation") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->modify_relation(1, 424471234567890, 1, {}, {}); REQUIRE_THROWS_MATCHES(rel_updater->process_modify_relations(), http::not_found, @@ -1568,10 +1629,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Create three relations with grandparent/parent/child relationship") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->add_relation(1, -1, { }, {{"key1", "value1"}}); rel_updater->add_relation(1, -2, { { "Relation", -1, "role2" }}, {{"key2", "value2"}}); @@ -1594,10 +1656,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Try to delete child/parent relations which still belong to grandparent relation, if-unused set") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); rel_updater->delete_relation(1, relation_l3_id_1, relation_l3_version_1, true); rel_updater->delete_relation(1, relation_l3_id_2, relation_l3_version_2, true); @@ -1616,14 +1679,15 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up { // this test is checking that locking in ApiDB_Relation_Updater::lock_future_members is working as expected + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking{}; SECTION("Prepare data") { auto upd = tdb.get_data_update(); - auto node_updater = upd->get_node_updater(change_tracking); - auto way_updater = upd->get_way_updater(change_tracking); - auto rel_updater = upd->get_relation_updater(change_tracking); + auto node_updater = upd->get_node_updater(ctx, change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking); node_updater->add_node(-25.3448570, 131.0325171, 1, -1, { {"name", "Uluṟu"}, {"ele", "863"} }); node_updater->add_node(-25.3448570, 131.2325171, 1, -2, { }); @@ -1659,10 +1723,11 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up SECTION("Create new relation") { + RequestContext ctx{}; api06::OSMChange_Tracking change_tracking_new_rel{}; auto upd = tdb.get_data_update(); - auto rel_updater = upd->get_relation_updater(change_tracking_new_rel); + auto rel_updater = upd->get_relation_updater(ctx, change_tracking_new_rel); rel_updater->add_relation(1, -1, { @@ -1678,12 +1743,13 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up // while the new relation hasn't been committed yet auto future_node = std::async(std::launch::async, [&] { + RequestContext ctx2{}; api06::OSMChange_Tracking change_tracking_2nd{}; auto factory = tdb.get_new_data_update_factory(); auto txn_2nd = factory->get_default_transaction(); auto upd_2nd = factory->make_data_update(*txn_2nd); - auto node_updater = upd_2nd->get_node_updater(change_tracking_2nd); + auto node_updater = upd_2nd->get_node_updater(ctx2, change_tracking_2nd); node_updater->delete_node(2, static_cast(node_new_ids[2]), 1, false); // throws precondition_failed exception once the main process commits and releases the lock. node_updater->process_delete_nodes(); @@ -1691,12 +1757,13 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up }); auto future_way = std::async(std::launch::async, [&] { + RequestContext ctx3{}; api06::OSMChange_Tracking change_tracking_2nd{}; auto factory = tdb.get_new_data_update_factory(); auto txn_2nd = factory->get_default_transaction(); auto upd_2nd = factory->make_data_update(*txn_2nd); - auto way_updater = upd_2nd->get_way_updater(change_tracking_2nd); + auto way_updater = upd_2nd->get_way_updater(ctx3, change_tracking_2nd); way_updater->delete_way(2, static_cast(way_new_id), 1, false); // throws precondition_failed exception once the main process commits and releases the lock. way_updater->process_delete_ways(); @@ -1704,12 +1771,13 @@ TEST_CASE_METHOD( DatabaseTestsFixture, "test_single_relations", "[changeset][up }); auto future_rel = std::async(std::launch::async, [&] { + RequestContext ctx4{}; api06::OSMChange_Tracking change_tracking_2nd{}; auto factory = tdb.get_new_data_update_factory(); auto txn_2nd = factory->get_default_transaction(); auto upd_2nd = factory->make_data_update(*txn_2nd); - auto rel_updater = upd_2nd->get_relation_updater(change_tracking_2nd); + auto rel_updater = upd_2nd->get_relation_updater(ctx4, change_tracking_2nd); rel_updater->delete_relation(2, static_cast(relation_id), 1, false); // throws precondition_failed exception once the main process commits and releases the lock. rel_updater->process_delete_relations(); @@ -1757,12 +1825,17 @@ std::vector process_payload(test_database &tdb, osm_changes auto sel = tdb.get_data_selection(); auto upd = tdb.get_data_update(); + // C++20: switch to designated initializer for readability + UserInfo user{}; + user.id = uid; + RequestContext ctx{}; + ctx.user = user; api06::OSMChange_Tracking change_tracking{}; - auto changeset_updater = upd->get_changeset_updater(changeset, uid); - auto node_updater = upd->get_node_updater(change_tracking); - auto way_updater = upd->get_way_updater(change_tracking); - auto relation_updater = upd->get_relation_updater(change_tracking); + auto changeset_updater = upd->get_changeset_updater(ctx, changeset); + auto node_updater = upd->get_node_updater(ctx, change_tracking); + auto way_updater = upd->get_way_updater(ctx, change_tracking); + auto relation_updater = upd->get_relation_updater(ctx, change_tracking); changeset_updater->lock_current_changeset(true); @@ -1785,9 +1858,14 @@ std::vector process_payload(test_database &tdb, osm_changes TEST_CASE_METHOD( DatabaseTestsFixture, "test_changeset_update", "[changeset][upload][db]" ) { + // C++20: switch to designated initializer for readability + UserInfo user{}; + user.id = 1; + RequestContext ctx{}; + ctx.user = user; auto upd = tdb.get_data_update(); - auto changeset_updater = upd->get_changeset_updater(1, 1); + auto changeset_updater = upd->get_changeset_updater(ctx, 1); SECTION("Initialize test data") { tdb.run_sql(