Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add datasets from parameters for Query and Update #1714

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
55 changes: 28 additions & 27 deletions src/engine/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "util/MemorySize/MemorySize.h"
#include "util/OnDestructionDontThrowDuringStackUnwinding.h"
#include "util/ParseableDuration.h"
#include "util/TypeIdentity.h"
#include "util/http/HttpUtils.h"
#include "util/http/websocket/MessageSender.h"

Expand Down Expand Up @@ -169,6 +170,7 @@ void Server::run(const string& indexBaseName, bool useText, bool usePatterns,
// _____________________________________________________________________________
ad_utility::url_parser::ParsedRequest Server::parseHttpRequest(
const ad_utility::httpUtils::HttpRequest auto& request) {
using namespace ad_utility::use_type_identity;
// For an HTTP request, `request.target()` yields the HTTP Request-URI.
// This is a concatenation of the URL path and the query strings.
auto parsedUrl = ad_utility::url_parser::parseRequestTarget(request.target());
Expand All @@ -178,16 +180,18 @@ ad_utility::url_parser::ParsedRequest Server::parseHttpRequest(
// Some valid requests (e.g. QLever's custom commands like retrieving index
// statistics) don't have a query. So an empty operation is not necessarily an
// error.
auto setOperationIfSpecifiedInParams =
[&parsedRequest]<typename Operation>(string_view paramName) {
auto operation = ad_utility::url_parser::getParameterCheckAtMostOnce(
parsedRequest.parameters_, paramName);
if (operation.has_value()) {
parsedRequest.operation_ = Operation{operation.value(), {}};
parsedRequest.parameters_.erase(paramName);
}
};
auto setOperationIfSpecifiedInParams = [&parsedRequest]<typename Operation>(
TI<Operation>,
string_view paramName) {
auto operation = ad_utility::url_parser::getParameterCheckAtMostOnce(
parsedRequest.parameters_, paramName);
if (operation.has_value()) {
parsedRequest.operation_ = Operation{operation.value(), {}};
parsedRequest.parameters_.erase(paramName);
}
};
auto addToDatasetClausesIfOperationIs = [&parsedRequest]<typename Operation>(
TI<Operation>,
const std::string& key,
bool isNamed) {
if (Operation* op = std::get_if<Operation>(&parsedRequest.operation_)) {
Expand All @@ -197,18 +201,14 @@ ad_utility::url_parser::ParsedRequest Server::parseHttpRequest(
}
};
auto addDatasetClauses = [&addToDatasetClausesIfOperationIs] {
addToDatasetClausesIfOperationIs.template operator()<Query>(
"default-graph-uri", false);
addToDatasetClausesIfOperationIs.template operator()<Query>(
"named-graph-uri", true);
addToDatasetClausesIfOperationIs.template operator()<Update>(
"using-graph-uri", false);
addToDatasetClausesIfOperationIs.template operator()<Update>(
"using-named-graph-uri", true);
addToDatasetClausesIfOperationIs(ti<Query>, "default-graph-uri", false);
addToDatasetClausesIfOperationIs(ti<Query>, "named-graph-uri", true);
addToDatasetClausesIfOperationIs(ti<Update>, "using-graph-uri", false);
addToDatasetClausesIfOperationIs(ti<Update>, "using-named-graph-uri", true);
};

if (request.method() == http::verb::get) {
setOperationIfSpecifiedInParams.template operator()<Query>("query");
setOperationIfSpecifiedInParams(ti<Query>, "query");
addDatasetClauses();

if (parsedRequest.parameters_.contains("update")) {
Expand Down Expand Up @@ -278,8 +278,8 @@ ad_utility::url_parser::ParsedRequest Server::parseHttpRequest(
throw std::runtime_error(
R"(Request must only contain one of "query" and "update".)");
}
setOperationIfSpecifiedInParams.template operator()<Query>("query");
setOperationIfSpecifiedInParams.template operator()<Update>("update");
setOperationIfSpecifiedInParams(ti<Query>, "query");
setOperationIfSpecifiedInParams(ti<Update>, "update");
addDatasetClauses();
return parsedRequest;
}
Expand Down Expand Up @@ -977,6 +977,9 @@ Awaitable<void> Server::processQueryOrUpdate(
TimeLimit timeLimit) {
using namespace ad_utility::httpUtils;

static_assert(std::is_same_v<Operation, Query> ||
std::is_same_v<Operation, Update>);
Qup42 marked this conversation as resolved.
Show resolved Hide resolved

http::status responseStatus = http::status::ok;

// Put the whole query processing in a try-catch block. If any exception
Expand All @@ -992,11 +995,10 @@ Awaitable<void> Server::processQueryOrUpdate(
if constexpr (std::is_same_v<Operation, Query>) {
co_await processQuery(params, operation, requestTimer, request, send,
timeLimit);
} else if constexpr (std::is_same_v<Operation, Update>) {
} else {
static_assert(std::is_same_v<Operation, Update>);
co_await processUpdate(params, operation, requestTimer, request, send,
timeLimit);
} else {
AD_FAIL();
}
} catch (const ParseException& e) {
responseStatus = http::status::bad_request;
Expand Down Expand Up @@ -1036,13 +1038,12 @@ Awaitable<void> Server::processQueryOrUpdate(
LOG(ERROR) << metadata.value().query_ << std::endl;
}
}
std::string operationStr = [&operation] {
const std::string operationStr = [&operation] {
if constexpr (std::is_same_v<Operation, Query>) {
return operation.query_;
} else if constexpr (std::is_same_v<Operation, Update>) {
return operation.update_;
} else {
AD_FAIL();
static_assert(std::is_same_v<Operation, Update>);
return operation.update_;
Qup42 marked this conversation as resolved.
Show resolved Hide resolved
}
}();
auto errorResponseJson = composeErrorResponseJson(
Expand Down
22 changes: 11 additions & 11 deletions test/ServerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ TEST(ServerTest, parseHttpRequest) {
"query=SELECT%20%2A%20WHERE%20%7B%7D&send=100")),
ParsedRequestIs("/", {{"send", {"100"}}},
Query{"SELECT * WHERE {}", {}}));
EXPECT_THAT(parse(MakePostRequest("/", URLENCODED,
EXPECT_THAT(parse(makePostRequest("/", URLENCODED,
"query=SELECT%20%2A%20WHERE%20%7B%7D")),
ParsedRequestIs("/", {}, Query{"SELECT * WHERE {}", {}}));
auto Iri = ad_utility::triple_component::Iri::fromIriref;
Expand All @@ -105,9 +105,9 @@ TEST(ServerTest, parseHttpRequest) {
"parameters in the URL."));
EXPECT_THAT(parse(makePostRequest("/", URLENCODED, "cmd=clear-cache")),
ParsedRequestIs("/", {{"cmd", {"clear-cache"}}}, None{}));
EXPECT_THAT(parse(MakePostRequest("/", QUERY, "SELECT * WHERE {}")),
EXPECT_THAT(parse(makePostRequest("/", QUERY, "SELECT * WHERE {}")),
ParsedRequestIs("/", {}, Query{"SELECT * WHERE {}", {}}));
EXPECT_THAT(parse(MakePostRequest("/?send=100", QUERY, "SELECT * WHERE {}")),
EXPECT_THAT(parse(makePostRequest("/?send=100", QUERY, "SELECT * WHERE {}")),
ParsedRequestIs("/", {{"send", {"100"}}},
Query{"SELECT * WHERE {}", {}}));
AD_EXPECT_THROW_WITH_MESSAGE(
Expand All @@ -123,17 +123,17 @@ TEST(ServerTest, parseHttpRequest) {
AD_EXPECT_THROW_WITH_MESSAGE(
parse(makeGetRequest("/?update=DELETE%20%2A%20WHERE%20%7B%7D")),
testing::StrEq("SPARQL Update is not allowed as GET request."));
EXPECT_THAT(parse(MakePostRequest("/", UPDATE, "DELETE * WHERE {}")),
EXPECT_THAT(parse(makePostRequest("/", UPDATE, "DELETE * WHERE {}")),
ParsedRequestIs("/", {}, Update{"DELETE * WHERE {}", {}}));
EXPECT_THAT(parse(MakePostRequest("/", URLENCODED,
EXPECT_THAT(parse(makePostRequest("/", URLENCODED,
"update=DELETE%20%2A%20WHERE%20%7B%7D")),
ParsedRequestIs("/", {}, Update{"DELETE * WHERE {}", {}}));
EXPECT_THAT(parse(MakePostRequest("/", URLENCODED,
EXPECT_THAT(parse(makePostRequest("/", URLENCODED,
"update=DELETE+%2A+WHERE%20%7B%7D")),
ParsedRequestIs("/", {}, Update{"DELETE * WHERE {}", {}}));
// Check that the correct datasets for the method (GET or POST) are added
EXPECT_THAT(
parse(MakeGetRequest("/?query=SELECT%20%2A%20WHERE%20%7B%7D&default-"
parse(makeGetRequest("/?query=SELECT%20%2A%20WHERE%20%7B%7D&default-"
"graph-uri=foo&named-graph-uri=bar&using-graph-uri="
"baz&using-named-graph-uri=cat")),
ParsedRequestIs("/",
Expand All @@ -145,7 +145,7 @@ TEST(ServerTest, parseHttpRequest) {
{DatasetClause{Iri("<foo>"), false},
DatasetClause{Iri("<bar>"), true}}}));
EXPECT_THAT(
parse(MakePostRequest("/?default-"
parse(makePostRequest("/?default-"
"graph-uri=foo&named-graph-uri=bar&using-graph-uri="
"baz&using-named-graph-uri=cat",
QUERY, "SELECT * WHERE {}")),
Expand All @@ -158,7 +158,7 @@ TEST(ServerTest, parseHttpRequest) {
{DatasetClause{Iri("<foo>"), false},
DatasetClause{Iri("<bar>"), true}}}));
EXPECT_THAT(
parse(MakePostRequest("/", URLENCODED,
parse(makePostRequest("/", URLENCODED,
"query=SELECT%20%2A%20WHERE%20%7B%7D&default-graph-"
"uri=foo&named-graph-uri=bar&using-graph-uri=baz&"
"using-named-graph-uri=cat")),
Expand All @@ -171,7 +171,7 @@ TEST(ServerTest, parseHttpRequest) {
{DatasetClause{Iri("<foo>"), false},
DatasetClause{Iri("<bar>"), true}}}));
EXPECT_THAT(
parse(MakePostRequest("/", URLENCODED,
parse(makePostRequest("/", URLENCODED,
"update=INSERT%20DATA%20%7B%7D&default-graph-uri="
"foo&named-graph-uri=bar&using-graph-uri=baz&"
"using-named-graph-uri=cat")),
Expand All @@ -186,7 +186,7 @@ TEST(ServerTest, parseHttpRequest) {
{DatasetClause{Iri("<baz>"), false},
DatasetClause{Iri("<cat>"), true}}}));
EXPECT_THAT(
parse(MakePostRequest(
parse(makePostRequest(
"/?default-graph-uri=foo&named-graph-uri=bar&using-graph-uri=baz&"
"using-named-graph-uri=cat",
UPDATE, "INSERT DATA {}")),
Expand Down
Loading