1
0
Fork 0

do allow input to /_api/aqlfunction choose between (#4603)

This commit is contained in:
Jan 2018-02-16 14:10:17 +01:00 committed by GitHub
parent 101a9893a4
commit 9d311aac65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 24 deletions

View File

@ -39,7 +39,6 @@ RestAqlUserFunctionsHandler::RestAqlUserFunctionsHandler(GeneralRequest* request
: RestVocbaseBaseHandler(request, response) {} : RestVocbaseBaseHandler(request, response) {}
RestStatus RestAqlUserFunctionsHandler::execute() { RestStatus RestAqlUserFunctionsHandler::execute() {
auto const type = _request->requestType(); auto const type = _request->requestType();
if (type == rest::RequestType::POST) { if (type == rest::RequestType::POST) {
@ -78,8 +77,7 @@ RestStatus RestAqlUserFunctionsHandler::execute() {
generateError(res); generateError(res);
} }
return RestStatus::DONE; return RestStatus::DONE;
} } else if (type == rest::RequestType::DELETE_REQ) {
else if (type == rest::RequestType::DELETE_REQ) {
// JSF_delete_api_aqlfunction.md // JSF_delete_api_aqlfunction.md
// DELETE /_api/aqlfunction/{name} // DELETE /_api/aqlfunction/{name}
std::vector<std::string> const& suffixes = _request->decodedSuffixes(); std::vector<std::string> const& suffixes = _request->decodedSuffixes();
@ -110,24 +108,31 @@ RestStatus RestAqlUserFunctionsHandler::execute() {
generateError(res); generateError(res);
} }
return RestStatus::DONE; return RestStatus::DONE;
} // DELETE // DELETE
else if (type == rest::RequestType::GET) { } else if (type == rest::RequestType::GET) {
// JSF_get_api_aqlfunction.md // JSF_get_api_aqlfunction.md
// GET /_api/aqlfunction - figure out parameters - function namespace // GET /_api/aqlfunction - figure out parameters - function namespace
std::string functionNamespace; std::string functionNamespace;
std::vector<std::string> const& suffixes = _request->decodedSuffixes(); std::vector<std::string> const& suffixes = _request->decodedSuffixes();
if (!suffixes.empty()) {
if ((suffixes.size() != 1) || suffixes[0].empty() ) { if ((suffixes.size() != 1) || suffixes[0].empty() ) {
extractStringParameter(StaticStrings::Prefix, functionNamespace); extractStringParameter(StaticStrings::Prefix, functionNamespace);
if (functionNamespace.empty()) { if (functionNamespace.empty()) {
generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_SUPERFLUOUS_SUFFICES, generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_SUPERFLUOUS_SUFFICES,
"superfluous suffix, expecting _api/aqlfunction/[<functionname or prefix>|?" + "superfluous suffix, expecting _api/aqlfunction/[<functionname or prefix>|?" +
StaticStrings::Prefix + "=<functionname or prefix>]"); StaticStrings::Prefix + "=<functionname or prefix>]");
return RestStatus::DONE; return RestStatus::DONE;
}
} else {
functionNamespace = suffixes[0];
} }
} else { } else {
functionNamespace = suffixes[0]; extractStringParameter(StaticStrings::Prefix, functionNamespace);
if (functionNamespace.empty()) {
// compatibility mode
extractStringParameter(StaticStrings::Namespace, functionNamespace);
}
} }
// internal get // internal get
@ -135,7 +140,7 @@ RestStatus RestAqlUserFunctionsHandler::execute() {
auto res = toArrayUserFunctions(_vocbase, functionNamespace, arrayOfFunctions); auto res = toArrayUserFunctions(_vocbase, functionNamespace, arrayOfFunctions);
// error handling // error handling
if(res.ok()){ if (res.ok()) {
generateOk(rest::ResponseCode::OK, arrayOfFunctions.slice()); generateOk(rest::ResponseCode::OK, arrayOfFunctions.slice());
} else { } else {
generateError(res); generateError(res);

View File

@ -291,7 +291,6 @@ Result arangodb::registerUserFunction(TRI_vocbase_t* vocbase,
opOptions.isRestore = false; opOptions.isRestore = false;
opOptions.waitForSync = true; opOptions.waitForSync = true;
opOptions.silent = false; opOptions.silent = false;
opOptions.isSynchronousReplicationFrom = true;
// find and load collection given by name or identifier // find and load collection given by name or identifier
auto ctx = transaction::StandaloneContext::Create(vocbase); auto ctx = transaction::StandaloneContext::Create(vocbase);
@ -324,9 +323,12 @@ Result arangodb::registerUserFunction(TRI_vocbase_t* vocbase,
Result arangodb::toArrayUserFunctions(TRI_vocbase_t* vocbase, Result arangodb::toArrayUserFunctions(TRI_vocbase_t* vocbase,
std::string const& functionFilterPrefix, std::string const& functionFilterPrefix,
velocypack::Builder& result) { velocypack::Builder& result) {
std::string aql;
auto binds = std::make_shared<VPackBuilder>(); auto binds = std::make_shared<VPackBuilder>();
binds->openObject(); binds->openObject();
if (! functionFilterPrefix.empty()) { if (!functionFilterPrefix.empty()) {
aql = "FOR function IN @@col FILTER LEFT(function._key, @fnLength) == @ucName RETURN function";
std::string uc(functionFilterPrefix); std::string uc(functionFilterPrefix);
basics::StringUtils::toupperInPlace(&uc); basics::StringUtils::toupperInPlace(&uc);
if ((uc.length() < 2) || if ((uc.length() < 2) ||
@ -336,16 +338,12 @@ Result arangodb::toArrayUserFunctions(TRI_vocbase_t* vocbase,
} }
binds->add("fnLength", VPackValue(uc.length())); binds->add("fnLength", VPackValue(uc.length()));
binds->add("ucName", VPackValue(uc)); binds->add("ucName", VPackValue(uc));
} else {
aql = "FOR function IN @@col RETURN function";
} }
binds->add("@col", VPackValue(collectionName)); binds->add("@col", VPackValue(collectionName));
binds->close(); binds->close();
std::string const aql(
"FOR function IN @@col "
"FILTER LEFT(function._key, @fnLength) == @ucName "
"RETURN function"
);
arangodb::aql::Query query(false, vocbase, arangodb::aql::QueryString(aql), arangodb::aql::Query query(false, vocbase, arangodb::aql::QueryString(aql),
binds, nullptr, arangodb::aql::PART_MAIN); binds, nullptr, arangodb::aql::PART_MAIN);

View File

@ -58,8 +58,9 @@ std::string const StaticStrings::WaitForSyncString("waitForSync");
std::string const StaticStrings::IsSynchronousReplicationString( std::string const StaticStrings::IsSynchronousReplicationString(
"isSynchronousReplication"); "isSynchronousReplication");
std::string const StaticStrings::Group("group"); std::string const StaticStrings::Group("group");
std::string const StaticStrings::ReplaceExisting("replaceExisting"); std::string const StaticStrings::Namespace("namespace");
std::string const StaticStrings::Prefix("prefix"); std::string const StaticStrings::Prefix("prefix");
std::string const StaticStrings::ReplaceExisting("replaceExisting");
// replication headers // replication headers
std::string const StaticStrings::ReplicationHeaderCheckMore("x-arango-replication-checkmore"); std::string const StaticStrings::ReplicationHeaderCheckMore("x-arango-replication-checkmore");

View File

@ -63,6 +63,7 @@ class StaticStrings {
static std::string const WaitForSyncString; static std::string const WaitForSyncString;
static std::string const IsSynchronousReplicationString; static std::string const IsSynchronousReplicationString;
static std::string const Group; static std::string const Group;
static std::string const Namespace;
static std::string const ReplaceExisting; static std::string const ReplaceExisting;
static std::string const Prefix;; static std::string const Prefix;;