Arachne 1.0
Arachne - the perpetual stitcher of Wikidata entities.
Loading...
Searching...
No Matches
utils.cpp
Go to the documentation of this file.
1/*
2 * The MIT License (MIT)
3 *
4 * Copyright (c) 2025 Yaroslav Riabtsev <yaroslav.riabtsev@rwth-aachen.de>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25#include "utils.hpp"
26
27#include <algorithm>
28#include <stdexcept>
29
30namespace corespace {
31
33 static const service_profile profile {
34 .base_url = "https://query.wikidata.org/sparql",
35 .default_accept = "application/sparql-results+json",
36 .rate_hints = { "polite", "limit" }
37 };
38 return profile;
39}
40
42choose_http_method(const sparql_request& request, const std::size_t threshold) {
43 switch (request.method) {
45 return request.query.size() <= threshold ? http_method::get
48 return http_method::get;
50 return http_method::post;
51 }
52 return http_method::get;
53}
54
55std::string resolve_accept(
56 const sparql_request& request, const service_profile& profile,
57 const std::string_view override_accept
58) {
59 if (!request.accept.empty()) {
60 return request.accept;
61 }
62 if (!override_accept.empty()) {
63 return std::string { override_accept };
64 }
65 return profile.default_accept;
66}
67
68std::pair<std::string, bool>
70 if (!request.content_type.empty()) {
71 const bool use_form
72 = request.content_type == "application/x-www-form-urlencoded";
73 return { request.content_type, use_form };
74 }
76 return { "application/x-www-form-urlencoded", true };
77 }
78 return { "application/sparql-query", false };
79}
80
81network_metrics::network_metrics() {
82 for (auto& status : statuses) {
83 status.store(0, std::memory_order_relaxed);
84 }
85}
86
88 switch (kind) {
90 return wdqs_profile();
91 default:
92 throw std::invalid_argument("unknown service_kind");
93 }
94}
95
96void sort_parameters(parameter_list& params) {
97 std::ranges::sort(params, [](const auto& lhs, const auto& rhs) {
98 if (lhs.first == rhs.first) {
99 return lhs.second < rhs.second;
100 }
101 return lhs.first < rhs.first;
102 });
103}
104
106 const service_kind kind, const http_method method, parameter_list& params
107) {
108 switch (kind) {
110 if (method == http_method::get) {
111 const bool has_format
112 = std::ranges::any_of(params, [](const auto& param) {
113 return param.first == "format";
114 });
115 if (!has_format) {
116 params.emplace_back("format", "json");
117 }
118 }
119 break;
120 }
121 sort_parameters(params);
122}
123
124bool call_preview::has_param(std::string_view key) const {
125 return std::ranges::any_of(query_params, [&](const auto& p) {
126 return p.first == key;
127 });
128}
129
130std::string call_preview::get_param(const std::string_view key) const {
131 for (const auto& [fst, snd] : query_params) {
132 if (fst == key) {
133 return snd;
134 }
135 }
136 return {};
137}
138}
std::string resolve_accept(const sparql_request &request, const service_profile &profile, const std::string_view override_accept)
Resolves the Accept header value for a SPARQL request.
Definition utils.cpp:55
http_method choose_http_method(const sparql_request &request, const std::size_t threshold)
Chooses the appropriate HTTP method for a SPARQL request.
Definition utils.cpp:42
std::pair< std::string, bool > resolve_body_strategy(const sparql_request &request)
Determines the body content and strategy for a SPARQL request.
Definition utils.cpp:69
http_method
HTTP method to use for a request.
Definition utils.hpp:201
void sort_parameters(parameter_list &params)
Sorts the parameter list in-place by key.
Definition utils.cpp:96
service_kind
Identifies supported SPARQL services.
Definition utils.hpp:74
const service_profile & get_service_profile(const service_kind kind)
Retrieve the service profile for a given service kind.
Definition utils.cpp:87
void append_common_params(const service_kind kind, const http_method method, parameter_list &params)
Appends common parameters required for a service and HTTP method.
Definition utils.cpp:105
const service_profile & wdqs_profile()
Definition utils.cpp:32
http_method_hint
Hint for selecting the HTTP method for a request.
Definition utils.hpp:215
bool has_param(std::string_view key) const
Check whether a query parameter with key key exists.
Definition utils.cpp:124
std::string get_param(std::string_view key) const
Retrieve the first value for query parameter key.
Definition utils.cpp:130
network_metrics()
Zero-initialize per-status counters.
Definition utils.cpp:81
Static configuration values describing a remote service.
Definition utils.hpp:236
std::string default_accept
Definition utils.hpp:238
std::string content_type
Definition utils.hpp:225
http_method_hint method
Definition utils.hpp:219