1
0
Fork 0

Merge branch 'devel' of https://github.com/arangodb/arangodb into devel

This commit is contained in:
Kaveh Vahedipour 2016-08-31 17:22:25 +02:00
commit cbe2d51eba
26 changed files with 171 additions and 57 deletions

View File

@ -61,10 +61,11 @@ list(APPEND V8_GYP_ARGS
) )
if (CROSS_COMPILING) if (CROSS_COMPILING)
list(APPEND V8_GYP_ARGS -DGYP_CROSSCOMPILE=1) list(APPEND V8_GYP_ARGS
-Dhost_arch=${V8_PROC_ARCH}
-DGYP_CROSSCOMPILE=1)
endif() endif()
################################################################################ ################################################################################
## ICU EXPORTS ## ICU EXPORTS
################################################################################ ################################################################################

View File

@ -48,6 +48,8 @@ devel
v3.0.6 (XXXX-XX-XX) v3.0.6 (XXXX-XX-XX)
------------------- -------------------
* fixed issue #2026
* slightly better error diagnostics for AQL query compilation and replication * slightly better error diagnostics for AQL query compilation and replication
* fixed issue #2018 * fixed issue #2018

View File

@ -39,8 +39,8 @@ For unattended installation, you can set the password using the
[debconf helpers](http://www.microhowto.info/howto/perform_an_unattended_installation_of_a_debian_package.html). [debconf helpers](http://www.microhowto.info/howto/perform_an_unattended_installation_of_a_debian_package.html).
``` ```
echo arangodb3 arangodb/password password NEWPASSWORD | debconf-set-selections echo arangodb3 arangodb3/password password NEWPASSWORD | debconf-set-selections
echo arangodb3 arangodb/password_again password NEWPASSWORD | debconf-set-selections echo arangodb3 arangodb3/password_again password NEWPASSWORD | debconf-set-selections
``` ```
The commands should be executed prior to the installation. The commands should be executed prior to the installation.

View File

@ -300,6 +300,16 @@ while [ $# -gt 0 ]; do
CLEAN_IT=1 CLEAN_IT=1
shift shift
;; ;;
--cxArmV8)
ARMV8=1
CXGCC=1
shift
;;
--cxArmV7)
ARMV7=1
CXGCC=1
shift
;;
*) *)
echo "Unknown option: $1" echo "Unknown option: $1"
exit 1 exit 1
@ -330,9 +340,31 @@ elif [ "$CLANG36" == 1 ]; then
CC=/usr/bin/clang-3.6 CC=/usr/bin/clang-3.6
CXX=/usr/bin/clang++-3.6 CXX=/usr/bin/clang++-3.6
CXXFLAGS="${CXXFLAGS} -std=c++11" CXXFLAGS="${CXXFLAGS} -std=c++11"
elif [ "${CXGCC}" = 1 ]; then
if [ "${ARMV8}" = 1 ]; then
export TOOL_PREFIX=aarch64-linux-gnu
BUILD_DIR="${BUILD_DIR}-ARMV8"
elif [ "${ARMV7}" = 1 ]; then
export TOOL_PREFIX=aarch64-linux-gnu
BUILD_DIR="${BUILD_DIR}-ARMV7"
else
echo "Unknown CX-Compiler!"
exit 1;
fi
export CXX=$TOOL_PREFIX-g++
export AR=$TOOL_PREFIX-ar
export RANLIB=$TOOL_PREFIX-ranlib
export CC=$TOOL_PREFIX-gcc
export LD=$TOOL_PREFIX-g++
export LINK=$TOOL_PREFIX-g++
export STRIP=$TOOL_PREFIX-strip
CONFIGURE_OPTIONS="${CONFIGURE_OPTIONS} -DCROSS_COMPILING=true"
fi fi
if [ "$SANITIZE" == 1 ]; then if [ "$SANITIZE" == 1 ]; then
if [ "$GCC5" == 1 ]; then if [ "$GCC5" == 1 ]; then
CFLAGS="${CFLAGS} -fsanitize=address -fsanitize=undefined -fno-sanitize=alignment -fno-sanitize=vptr" CFLAGS="${CFLAGS} -fsanitize=address -fsanitize=undefined -fno-sanitize=alignment -fno-sanitize=vptr"
@ -415,7 +447,7 @@ SOURCE_DIR=`compute_relative ${DST}/ ${SRC}/`
if [ ! -f Makefile -o ! -f CMakeCache.txt ]; then if [ ! -f Makefile -o ! -f CMakeCache.txt ]; then
CFLAGS="${CFLAGS}" CXXFLAGS="${CXXFLAGS}" LDFLAGS="${LDFLAGS}" LIBS="${LIBS}" \ CFLAGS="${CFLAGS}" CXXFLAGS="${CXXFLAGS}" LDFLAGS="${LDFLAGS}" LIBS="${LIBS}" \
cmake ${SOURCE_DIR} ${CONFIGURE_OPTIONS} -G "${GENERATOR}" cmake ${SOURCE_DIR} ${CONFIGURE_OPTIONS} -G "${GENERATOR}" || exit 1
fi fi
${MAKE_CMD_PREFIX} ${MAKE} ${MAKE_PARAMS} ${MAKE_CMD_PREFIX} ${MAKE} ${MAKE_PARAMS}

View File

@ -946,7 +946,7 @@ Function default_installation_directory
Return Return
FunctionEnd FunctionEnd
Function assign_proper_access_rigths Function assign_proper_access_rights
StrCpy $0 "0" StrCpy $0 "0"
AccessControl::GrantOnFile \ AccessControl::GrantOnFile \
"$INSTDIR" "(BU)" "GenericRead + GenericWrite + GenericExecute" "$INSTDIR" "(BU)" "GenericRead + GenericWrite + GenericExecute"
@ -963,7 +963,7 @@ Function is_writable
; is does not matter if we do some errors here ; is does not matter if we do some errors here
${If} $TRI_INSTALL_ALL_USERS == '1' ${If} $TRI_INSTALL_ALL_USERS == '1'
CreateDirectory $INSTDIR CreateDirectory $INSTDIR
Call assign_proper_access_rigths Call assign_proper_access_rights
${EndIf} ${EndIf}
FunctionEnd FunctionEnd

View File

@ -1,4 +1,5 @@
; CPack install script designed for a nmake build ; CPack install script designed for a nmake build
; TODO !addplugindir '@CPACK_PLUGIN_PATH@/AccessControl/Plugins'
;-------------------------------- ;--------------------------------
; Include LogicLib for more readable code ; Include LogicLib for more readable code
@ -484,14 +485,10 @@ FunctionEnd
;-------------------------------- ;--------------------------------
;Pages ;Pages
!define MUI_PAGE_CUSTOMFUNCTION_PRE skip_page
!insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_WELCOME
!define MUI_PAGE_CUSTOMFUNCTION_PRE skip_page
!insertmacro MUI_PAGE_LICENSE "@CPACK_RESOURCE_FILE_LICENSE@" !insertmacro MUI_PAGE_LICENSE "@CPACK_RESOURCE_FILE_LICENSE@"
Page custom InstallOptionsPage skip_page
!define MUI_PAGE_CUSTOMFUNCTION_PRE default_installation_directory !define MUI_PAGE_CUSTOMFUNCTION_PRE default_installation_directory
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE check_installation_directory !define MUI_PAGE_CUSTOMFUNCTION_LEAVE check_installation_directory
!insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_DIRECTORY
@ -709,7 +706,6 @@ displayAgain:
StrCmp $PASSWORD $PASSWORD_AGAIN +3 0 StrCmp $PASSWORD $PASSWORD_AGAIN +3 0
MessageBox MB_OK|MB_ICONSTOP "Passwords don't match, try again" MessageBox MB_OK|MB_ICONSTOP "Passwords don't match, try again"
Goto displayAgain Goto displayAgain
done:
Pop ${TEMP1} Pop ${TEMP1}
Return Return
@ -725,20 +721,17 @@ FunctionEnd
Function default_installation_directory Function default_installation_directory
; Read variables which defines if arango should be installed as Service ; Read variables which defines if arango should be installed as Service
!insertmacro MUI_INSTALLOPTIONS_READ $R2 "NSIS.InstallOptions.ini" "Field 2" "State" !insertmacro MUI_INSTALLOPTIONS_READ $R2 "NSIS.InstallOptions.ini" "Field 2" "State"
!insertmacro MUI_INSTALLOPTIONS_READ $R3 "NSIS.InstallOptions.ini" "Field 3" "State" !insertmacro MUI_INSTALLOPTIONS_READ $R3 "NSIS.InstallOptions.ini" "Field 3" "State"
!insertmacro MUI_INSTALLOPTIONS_READ $R4 "NSIS.InstallOptions.ini" "Field 4" "State" !insertmacro MUI_INSTALLOPTIONS_READ $R4 "NSIS.InstallOptions.ini" "Field 4" "State"
${If} $R3 == '1' ${If} $R3 == '1'
StrCpy $TRI_INSTALL_TYPE 'AllUsers' StrCpy $TRI_INSTALL_TYPE 'AllUsers'
${EndIf}
${If} $R4 == '1'
StrCpy $TRI_INSTALL_TYPE 'SingleUser'
${EndIf}
Call read_options
${EndIf} ${EndIf}
${If} $R4 == '1'
StrCpy $TRI_INSTALL_TYPE 'SingleUser'
${EndIf}
${Switch} $TRI_INSTALL_TYPE ${Switch} $TRI_INSTALL_TYPE
${Case} 'SingleUser' ${Case} 'SingleUser'
@ -750,25 +743,25 @@ Function default_installation_directory
Return Return
FunctionEnd FunctionEnd
Function assign_proper_access_rigths ; TODO Function assign_proper_access_rights
StrCpy $0 "0" ; TODO StrCpy $0 "0"
AccessControl::GrantOnFile \ ; TODO AccessControl::GrantOnFile \
"$INSTDIR" "(BU)" "GenericRead + GenericWrite + GenericExecute" ; TODO "$INSTDIR" "(BU)" "GenericRead + GenericWrite + GenericExecute"
Pop $R0 ; TODO Pop $R0
${If} $R0 == error ; TODO ${If} $R0 == error
Pop $R0 ; TODO Pop $R0
StrCpy $0 "1" ; TODO StrCpy $0 "1"
DetailPrint `AccessControl error: $R0` ; TODO DetailPrint `AccessControl error: $R0`
; MessageBox MB_OK "target directory $INSTDIR can not get cannot get correct access rigths" ; TODO ; MessageBox MB_OK "target directory $INSTDIR can not get cannot get correct access rigths"
${EndIf} ; TODO ${EndIf}
FunctionEnd ; TODO FunctionEnd
Function is_writable Function is_writable
; is does not matter if we do some errors here ; is does not matter if we do some errors here
${If} $TRI_INSTALL_ALL_USERS == '1' ${If} $TRI_INSTALL_ALL_USERS == '1'
CreateDirectory $INSTDIR CreateDirectory $INSTDIR
Call assign_proper_access_rigths ; TODO Call assign_proper_access_rights
${EndIf} ${EndIf}
FunctionEnd FunctionEnd
Function check_installation_directory Function check_installation_directory

View File

@ -2,7 +2,7 @@
set -e set -e
getent group arangodb >/dev/null || groupadd -r arangodb getent group arangodb >/dev/null || groupadd -r arangodb
getent passwd arangodb >/dev/null || useradd -r -g arangodb -d /usr/share/arangodb -s /bin/false -c "ArangoDB Application User" arangodb getent passwd arangodb >/dev/null || useradd -r -g arangodb -d /usr/share/arangodb3 -s /bin/false -c "ArangoDB Application User" arangodb
install -o arangodb -g arangodb -m 755 -d /var/lib/arangodb3 install -o arangodb -g arangodb -m 755 -d /var/lib/arangodb3
install -o arangodb -g arangodb -m 755 -d /var/lib/arangodb3-apps install -o arangodb -g arangodb -m 755 -d /var/lib/arangodb3-apps

View File

@ -192,6 +192,7 @@ struct UserVarFinder final : public WalkerWorker<ExecutionNode> {
en->getType() == ExecutionNode::INDEX || en->getType() == ExecutionNode::INDEX ||
en->getType() == ExecutionNode::ENUMERATE_LIST || en->getType() == ExecutionNode::ENUMERATE_LIST ||
en->getType() == ExecutionNode::TRAVERSAL || en->getType() == ExecutionNode::TRAVERSAL ||
en->getType() == ExecutionNode::SHORTEST_PATH ||
en->getType() == ExecutionNode::COLLECT) { en->getType() == ExecutionNode::COLLECT) {
depth += 1; depth += 1;
} }

View File

@ -581,7 +581,7 @@ ExecutionNode const* ExecutionNode::getLoop() const {
auto type = node->getType(); auto type = node->getType();
if (type == ENUMERATE_COLLECTION || type == INDEX || type == TRAVERSAL || if (type == ENUMERATE_COLLECTION || type == INDEX || type == TRAVERSAL ||
type == ENUMERATE_LIST) { type == ENUMERATE_LIST || type == SHORTEST_PATH) {
return node; return node;
} }
} }
@ -1147,7 +1147,7 @@ void ExecutionNode::RegisterPlan::after(ExecutionNode* en) {
en->getVarsUsedLater(); en->getVarsUsedLater();
std::vector<Variable const*> const& varsUsedHere = std::vector<Variable const*> const& varsUsedHere =
en->getVariablesUsedHere(); en->getVariablesUsedHere();
// We need to delete those variables that have been used here but are not // We need to delete those variables that have been used here but are not
// used any more later: // used any more later:
std::unordered_set<RegisterId> regsToClear; std::unordered_set<RegisterId> regsToClear;
@ -1160,7 +1160,7 @@ void ExecutionNode::RegisterPlan::after(ExecutionNode* en) {
if (it2 == varInfo.end()) { if (it2 == varInfo.end()) {
// report an error here to prevent crashing // report an error here to prevent crashing
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "missing variable #" + std::to_string(v->id) + " for node " + en->getTypeString() + " while planning registers"); THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "missing variable #" + std::to_string(v->id) + " (" + v->name + ") for node " + en->getTypeString() + " while planning registers");
} }
// finally adjust the variable inside the IN calculation // finally adjust the variable inside the IN calculation

View File

@ -749,7 +749,7 @@ ExecutionNode* ExecutionPlan::fromNodeTraversal(ExecutionNode* previous,
return addDependency(previous, en); return addDependency(previous, en);
} }
AstNode const* ExecutionPlan::parseTraversalVertexNode(ExecutionNode* previous, AstNode const* ExecutionPlan::parseTraversalVertexNode(ExecutionNode*& previous,
AstNode const* vertex) { AstNode const* vertex) {
if (vertex->type == NODE_TYPE_OBJECT && vertex->isConstant()) { if (vertex->type == NODE_TYPE_OBJECT && vertex->isConstant()) {
size_t n = vertex->numMembers(); size_t n = vertex->numMembers();
@ -767,6 +767,8 @@ AstNode const* ExecutionPlan::parseTraversalVertexNode(ExecutionNode* previous,
// operand is some misc expression // operand is some misc expression
auto calc = createTemporaryCalculation(vertex, previous); auto calc = createTemporaryCalculation(vertex, previous);
vertex = _ast->createNodeReference(getOutVariable(calc)); vertex = _ast->createNodeReference(getOutVariable(calc));
// update previous so the caller has an updated value
previous = calc;
} }
return vertex; return vertex;
@ -1960,6 +1962,7 @@ bool ExecutionPlan::isDeadSimple() const {
nodeType == ExecutionNode::ENUMERATE_COLLECTION || nodeType == ExecutionNode::ENUMERATE_COLLECTION ||
nodeType == ExecutionNode::ENUMERATE_LIST || nodeType == ExecutionNode::ENUMERATE_LIST ||
nodeType == ExecutionNode::TRAVERSAL || nodeType == ExecutionNode::TRAVERSAL ||
nodeType == ExecutionNode::SHORTEST_PATH ||
nodeType == ExecutionNode::INDEX) { nodeType == ExecutionNode::INDEX) {
// these node types are not simple // these node types are not simple
return false; return false;

View File

@ -286,7 +286,7 @@ class ExecutionPlan {
ExecutionNode* fromJson(arangodb::basics::Json const& Json); ExecutionNode* fromJson(arangodb::basics::Json const& Json);
/// @brief create an vertex element for graph nodes /// @brief create an vertex element for graph nodes
AstNode const* parseTraversalVertexNode(ExecutionNode*, AstNode const*); AstNode const* parseTraversalVertexNode(ExecutionNode*&, AstNode const*);
private: private:
/// @brief map from node id to the actual node /// @brief map from node id to the actual node

View File

@ -32,6 +32,7 @@
#include "Aql/Function.h" #include "Aql/Function.h"
#include "Aql/IndexNode.h" #include "Aql/IndexNode.h"
#include "Aql/ModificationNodes.h" #include "Aql/ModificationNodes.h"
#include "Aql/ShortestPathNode.h"
#include "Aql/SortCondition.h" #include "Aql/SortCondition.h"
#include "Aql/SortNode.h" #include "Aql/SortNode.h"
#include "Aql/TraversalConditionFinder.h" #include "Aql/TraversalConditionFinder.h"
@ -324,7 +325,8 @@ void arangodb::aql::removeRedundantSortsRule(Optimizer* opt,
} }
} else if (current->getType() == EN::ENUMERATE_LIST || } else if (current->getType() == EN::ENUMERATE_LIST ||
current->getType() == EN::ENUMERATE_COLLECTION || current->getType() == EN::ENUMERATE_COLLECTION ||
current->getType() == EN::TRAVERSAL) { current->getType() == EN::TRAVERSAL ||
current->getType() == EN::SHORTEST_PATH) {
// ok, but we cannot remove two different sorts if one of these node // ok, but we cannot remove two different sorts if one of these node
// types is between them // types is between them
// example: in the following query, the one sort will be optimized // example: in the following query, the one sort will be optimized
@ -764,10 +766,10 @@ void arangodb::aql::removeSortRandRule(Optimizer* opt, ExecutionPlan* plan,
case EN::SUBQUERY: case EN::SUBQUERY:
case EN::ENUMERATE_LIST: case EN::ENUMERATE_LIST:
case EN::TRAVERSAL: case EN::TRAVERSAL:
case EN::SHORTEST_PATH:
case EN::INDEX: { case EN::INDEX: {
// if we found another SortNode, an CollectNode, FilterNode, a // if we found another SortNode, a CollectNode, FilterNode, a
// SubqueryNode, // SubqueryNode, an EnumerateListNode, a TraversalNode or an IndexNode
// an EnumerateListNode, a TraversalNode or an IndexNode
// this means we cannot apply our optimization // this means we cannot apply our optimization
collectionNode = nullptr; collectionNode = nullptr;
current = nullptr; current = nullptr;
@ -949,7 +951,9 @@ void arangodb::aql::moveCalculationsDownRule(Optimizer* opt,
} else if (currentType == EN::INDEX || } else if (currentType == EN::INDEX ||
currentType == EN::ENUMERATE_COLLECTION || currentType == EN::ENUMERATE_COLLECTION ||
currentType == EN::ENUMERATE_LIST || currentType == EN::ENUMERATE_LIST ||
currentType == EN::TRAVERSAL || currentType == EN::COLLECT || currentType == EN::TRAVERSAL ||
currentType == EN::SHORTEST_PATH ||
currentType == EN::COLLECT ||
currentType == EN::NORESULTS) { currentType == EN::NORESULTS) {
// we will not push further down than such nodes // we will not push further down than such nodes
shouldMove = false; shouldMove = false;
@ -1241,6 +1245,17 @@ class arangodb::aql::RedundantCalculationsReplacer final
std::unordered_map<VariableId, Variable const*> const& replacements) std::unordered_map<VariableId, Variable const*> const& replacements)
: _replacements(replacements) { : _replacements(replacements) {
} }
template <typename T>
void replaceStartTargetVariables(ExecutionNode* en) {
auto node = static_cast<T*>(en);
if (node->_inStartVariable != nullptr) {
node->_inStartVariable = Variable::replace(node->_inStartVariable, _replacements);
}
if (node->_inTargetVariable != nullptr) {
node->_inTargetVariable = Variable::replace(node->_inTargetVariable, _replacements);
}
}
template <typename T> template <typename T>
void replaceInVariable(ExecutionNode* en) { void replaceInVariable(ExecutionNode* en) {
@ -1290,6 +1305,11 @@ class arangodb::aql::RedundantCalculationsReplacer final
replaceInVariable<TraversalNode>(en); replaceInVariable<TraversalNode>(en);
break; break;
} }
case EN::SHORTEST_PATH: {
replaceStartTargetVariables<ShortestPathNode>(en);
break;
}
case EN::COLLECT: { case EN::COLLECT: {
auto node = static_cast<CollectNode*>(en); auto node = static_cast<CollectNode*>(en);
@ -3589,7 +3609,7 @@ void arangodb::aql::patchUpdateStatementsRule(Optimizer* opt,
} }
} }
if (type == EN::TRAVERSAL) { if (type == EN::TRAVERSAL || type == EN::SHORTEST_PATH) {
// unclear what will be read by the traversal // unclear what will be read by the traversal
modified = false; modified = false;
break; break;

View File

@ -38,6 +38,7 @@ namespace aql {
/// @brief class ShortestPathNode /// @brief class ShortestPathNode
class ShortestPathNode : public ExecutionNode { class ShortestPathNode : public ExecutionNode {
friend class ExecutionBlock; friend class ExecutionBlock;
friend class RedundantCalculationsReplacer;
friend class ShortestPathBlock; friend class ShortestPathBlock;
/// @brief constructor with a vocbase and a collection name /// @brief constructor with a vocbase and a collection name

View File

@ -1356,6 +1356,11 @@ size_t ClusterComm::performSingleRequest(
if (req.result.status == CL_COMM_BACKEND_UNAVAILABLE) { if (req.result.status == CL_COMM_BACKEND_UNAVAILABLE) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_CLUSTER_BACKEND_UNAVAILABLE); THROW_ARANGO_EXCEPTION(TRI_ERROR_CLUSTER_BACKEND_UNAVAILABLE);
} }
if (req.result.status == CL_COMM_ERROR && req.result.result != nullptr
&& req.result.result->getHttpReturnCode() == 503) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_CLUSTER_BACKEND_UNAVAILABLE);
}
// Add correct recognition of content type later. // Add correct recognition of content type later.
basics::StringBuffer& buffer = req.result.result->getBody(); basics::StringBuffer& buffer = req.result.result->getBody();

View File

@ -123,6 +123,11 @@ static void mergeResults(
resultBody->openArray(); resultBody->openArray();
for (auto const& pair : reverseMapping) { for (auto const& pair : reverseMapping) {
VPackSlice arr = resultMap.find(pair.first)->second->slice(); VPackSlice arr = resultMap.find(pair.first)->second->slice();
if (arr.isObject() && arr.hasKey("error") && arr.get("error").isBoolean() && arr.get("error").getBoolean()) {
// an error occurred, now rethrow the error
int res = arr.get("errorNum").getNumericValue<int>();
THROW_ARANGO_EXCEPTION(res);
}
resultBody->add(arr.at(pair.second)); resultBody->add(arr.at(pair.second));
} }
resultBody->close(); resultBody->close();
@ -736,6 +741,7 @@ int createDocumentOnCoordinator(
bool useMultiple = slice.isArray(); bool useMultiple = slice.isArray();
int res = TRI_ERROR_NO_ERROR; int res = TRI_ERROR_NO_ERROR;
if (useMultiple) { if (useMultiple) {
VPackValueLength length = slice.length(); VPackValueLength length = slice.length();
for (VPackValueLength idx = 0; idx < length; ++idx) { for (VPackValueLength idx = 0; idx < length; ++idx) {
@ -766,6 +772,7 @@ int createDocumentOnCoordinator(
// Now prepare the requests: // Now prepare the requests:
std::vector<ClusterCommRequest> requests; std::vector<ClusterCommRequest> requests;
auto body = std::make_shared<std::string>(); auto body = std::make_shared<std::string>();
for (auto const& it : shardMap) { for (auto const& it : shardMap) {
if (!useMultiple) { if (!useMultiple) {
TRI_ASSERT(it.second.size() == 1); TRI_ASSERT(it.second.size() == 1);
@ -801,7 +808,7 @@ int createDocumentOnCoordinator(
"shard:" + it.first, arangodb::GeneralRequest::RequestType::POST, "shard:" + it.first, arangodb::GeneralRequest::RequestType::POST,
baseUrl + StringUtils::urlEncode(it.first) + optsUrlPart, body); baseUrl + StringUtils::urlEncode(it.first) + optsUrlPart, body);
} }
// Perform the requests // Perform the requests
size_t nrDone = 0; size_t nrDone = 0;
cc->performRequests(requests, CL_DEFAULT_TIMEOUT, nrDone, Logger::REQUESTS); cc->performRequests(requests, CL_DEFAULT_TIMEOUT, nrDone, Logger::REQUESTS);

View File

@ -159,6 +159,9 @@ bool GeneralServer::handleRequestAsync(GeneralCommTask* task,
if (res != TRI_ERROR_DISPATCHER_IS_STOPPING) { if (res != TRI_ERROR_DISPATCHER_IS_STOPPING) {
LOG(WARN) << "unable to add job to the job queue: " LOG(WARN) << "unable to add job to the job queue: "
<< TRI_errno_string(res); << TRI_errno_string(res);
} else {
task->handleSimpleError(GeneralResponse::ResponseCode::SERVICE_UNAVAILABLE);
return true;
} }
// todo send info to async work manager? // todo send info to async work manager?
return false; return false;
@ -194,6 +197,11 @@ bool GeneralServer::handleRequest(GeneralCommTask* task,
// add the job to the dispatcher // add the job to the dispatcher
int res = DispatcherFeature::DISPATCHER->addJob(job, startThread); int res = DispatcherFeature::DISPATCHER->addJob(job, startThread);
if (res == TRI_ERROR_DISPATCHER_IS_STOPPING) {
task->handleSimpleError(GeneralResponse::ResponseCode::SERVICE_UNAVAILABLE);
return true;
}
// job is in queue now // job is in queue now
return res == TRI_ERROR_NO_ERROR; return res == TRI_ERROR_NO_ERROR;
} }

View File

@ -164,6 +164,10 @@ static int runServer(int argc, char** argv) {
try { try {
server.run(argc, argv); server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
}
} catch (std::exception const& ex) { } catch (std::exception const& ex) {
LOG(ERR) << "arangod terminated because of an unhandled exception: " LOG(ERR) << "arangod terminated because of an unhandled exception: "
<< ex.what(); << ex.what();

View File

@ -64,6 +64,10 @@ int main(int argc, char* argv[]) {
try { try {
server.run(argc, argv); server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
}
} catch (std::exception const& ex) { } catch (std::exception const& ex) {
LOG(ERR) << "arangobench terminated because of an unhandled exception: " LOG(ERR) << "arangobench terminated because of an unhandled exception: "
<< ex.what(); << ex.what();

View File

@ -60,6 +60,10 @@ int main(int argc, char* argv[]) {
try { try {
server.run(argc, argv); server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
}
} catch (std::exception const& ex) { } catch (std::exception const& ex) {
LOG(ERR) << "arangodump terminated because of an unhandled exception: " LOG(ERR) << "arangodump terminated because of an unhandled exception: "
<< ex.what(); << ex.what();

View File

@ -62,6 +62,10 @@ int main(int argc, char* argv[]) {
try { try {
server.run(argc, argv); server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
}
} catch (std::exception const& ex) { } catch (std::exception const& ex) {
LOG(ERR) << "arangoimp terminated because of an unhandled exception: " LOG(ERR) << "arangoimp terminated because of an unhandled exception: "
<< ex.what(); << ex.what();

View File

@ -62,6 +62,10 @@ int main(int argc, char* argv[]) {
try { try {
server.run(argc, argv); server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
}
} catch (std::exception const& ex) { } catch (std::exception const& ex) {
LOG(ERR) << "arangorestore terminated because of an unhandled exception: " LOG(ERR) << "arangorestore terminated because of an unhandled exception: "
<< ex.what(); << ex.what();

View File

@ -72,6 +72,10 @@ int main(int argc, char* argv[]) {
try { try {
server.run(argc, argv); server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
}
} catch (std::exception const& ex) { } catch (std::exception const& ex) {
LOG(ERR) << "arangosh terminated because of an unhandled exception: " LOG(ERR) << "arangosh terminated because of an unhandled exception: "
<< ex.what(); << ex.what();

View File

@ -56,6 +56,10 @@ int main(int argc, char* argv[]) {
try { try {
server.run(argc, argv); server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
}
} catch (std::exception const& ex) { } catch (std::exception const& ex) {
LOG(ERR) << "arangovpack terminated because of an unhandled exception: " LOG(ERR) << "arangovpack terminated because of an unhandled exception: "
<< ex.what(); << ex.what();

View File

@ -166,6 +166,11 @@ void ApplicationServer::run(int argc, char* argv[]) {
// file(s) // file(s)
parseOptions(argc, argv); parseOptions(argc, argv);
if (!_helpSection.empty()) {
// help shown. we can exit early
return;
}
// seal the options // seal the options
_options->seal(); _options->seal();
@ -285,17 +290,17 @@ void ApplicationServer::collectOptions() {
void ApplicationServer::parseOptions(int argc, char* argv[]) { void ApplicationServer::parseOptions(int argc, char* argv[]) {
ArgumentParser parser(_options.get()); ArgumentParser parser(_options.get());
std::string helpSection = parser.helpSection(argc, argv); _helpSection = parser.helpSection(argc, argv);
if (!helpSection.empty()) { if (!_helpSection.empty()) {
// user asked for "--help" // user asked for "--help"
// translate "all" to "*" // translate "all" to "*"
if (helpSection == "all") { if (_helpSection == "all") {
helpSection = "*"; _helpSection = "*";
} }
_options->printHelp(helpSection); _options->printHelp(_helpSection);
exit(EXIT_SUCCESS); return;
} }
if (!parser.parse(argc, argv)) { if (!parser.parse(argc, argv)) {

View File

@ -166,6 +166,9 @@ class ApplicationServer {
~ApplicationServer(); ~ApplicationServer();
std::string helpSection() const { return _helpSection; }
bool helpShown() const { return !_helpSection.empty(); }
// adds a feature to the application server. the application server // adds a feature to the application server. the application server
// will take ownership of the feature object and destroy it in its // will take ownership of the feature object and destroy it in its
// destructor // destructor
@ -297,6 +300,9 @@ class ApplicationServer {
// reporter for progress // reporter for progress
std::vector<ProgressHandler> _progressReports; std::vector<ProgressHandler> _progressReports;
// help section displayed
std::string _helpSection;
}; };
} }
} }

View File

@ -49,7 +49,9 @@ VPackSlice FakeRequest::payload(arangodb::velocypack::Options const* options) {
if( _contentType == ContentType::JSON) { if( _contentType == ContentType::JSON) {
VPackParser parser(options); VPackParser parser(options);
parser.parse(_body, static_cast<size_t>(_contentLength)); if (_contentLength > 0) {
parser.parse(_body, static_cast<size_t>(_contentLength));
}
_vpackBuilder = parser.steal(); _vpackBuilder = parser.steal();
return VPackSlice(_vpackBuilder->slice()); return VPackSlice(_vpackBuilder->slice());
} else /*VPACK*/{ } else /*VPACK*/{