mirror of https://gitee.com/bigwinds/arangodb
further work on RemoveNode
This commit is contained in:
parent
655d7759bf
commit
773c29cecf
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
using namespace triagens::aql;
|
using namespace triagens::aql;
|
||||||
using Json = triagens::basics::Json;
|
using Json = triagens::basics::Json;
|
||||||
|
using JsonHelper = triagens::basics::JsonHelper;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief a quick method to decide whether a value is true
|
/// @brief a quick method to decide whether a value is true
|
||||||
|
@ -156,6 +157,106 @@ bool AqlValue::isString () const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief whether or not the AqlValue contains a list value
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool AqlValue::isList () const {
|
||||||
|
switch (_type) {
|
||||||
|
case JSON: {
|
||||||
|
TRI_json_t const* json = _json->json();
|
||||||
|
return TRI_IsListJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
case SHAPED: {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DOCVEC:
|
||||||
|
case RANGE: {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EMPTY: {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief whether or not the AqlValue contains an array value
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool AqlValue::isArray () const {
|
||||||
|
switch (_type) {
|
||||||
|
case JSON: {
|
||||||
|
TRI_json_t const* json = _json->json();
|
||||||
|
return TRI_IsArrayJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
case SHAPED: {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DOCVEC:
|
||||||
|
case RANGE:
|
||||||
|
case EMPTY: {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief get a string representation of the AqlValue
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::string AqlValue::toString () const {
|
||||||
|
switch (_type) {
|
||||||
|
case JSON: {
|
||||||
|
TRI_json_t const* json = _json->json();
|
||||||
|
TRI_ASSERT(TRI_IsStringJson(json));
|
||||||
|
return std::string(json->_value._string.data, json->_value._string.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
case SHAPED:
|
||||||
|
case DOCVEC:
|
||||||
|
case RANGE:
|
||||||
|
case EMPTY: {
|
||||||
|
// cannot convert these types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::string("");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief get a string representation of the AqlValue
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
char const* AqlValue::toChar () const {
|
||||||
|
switch (_type) {
|
||||||
|
case JSON: {
|
||||||
|
TRI_json_t const* json = _json->json();
|
||||||
|
TRI_ASSERT(TRI_IsStringJson(json));
|
||||||
|
return json->_value._string.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SHAPED:
|
||||||
|
case DOCVEC:
|
||||||
|
case RANGE:
|
||||||
|
case EMPTY: {
|
||||||
|
// cannot convert these types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief construct a V8 value as input for the expression execution in V8
|
/// @brief construct a V8 value as input for the expression execution in V8
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -327,6 +428,96 @@ Json AqlValue::toJson (AQL_TRANSACTION_V8* trx,
|
||||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief extract an attribute value from the AqlValue
|
||||||
|
/// this will fail if the value is not an array
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Json AqlValue::extractArrayMember (AQL_TRANSACTION_V8* trx,
|
||||||
|
TRI_document_collection_t const* document,
|
||||||
|
char const* name) const {
|
||||||
|
switch (_type) {
|
||||||
|
case JSON: {
|
||||||
|
TRI_ASSERT(_json != nullptr);
|
||||||
|
TRI_json_t const* json = _json->json();
|
||||||
|
|
||||||
|
if (TRI_IsArrayJson(json)) {
|
||||||
|
TRI_json_t const* found = TRI_LookupArrayJson(json, name);
|
||||||
|
|
||||||
|
if (found != nullptr) {
|
||||||
|
return Json(TRI_UNKNOWN_MEM_ZONE, TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, found));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// attribute does not exist or something went wrong - fall-through to returning null below
|
||||||
|
return Json(Json::Null);
|
||||||
|
}
|
||||||
|
|
||||||
|
case SHAPED: {
|
||||||
|
TRI_ASSERT(document != nullptr);
|
||||||
|
TRI_ASSERT(_marker != nullptr);
|
||||||
|
|
||||||
|
auto shaper = document->getShaper();
|
||||||
|
|
||||||
|
// look for the attribute name in the shape
|
||||||
|
if (*name == '_') {
|
||||||
|
if (strcmp(name, "_key") == 0) {
|
||||||
|
// _key value is copied into JSON
|
||||||
|
return Json(TRI_UNKNOWN_MEM_ZONE, TRI_EXTRACT_MARKER_KEY(_marker));
|
||||||
|
}
|
||||||
|
else if (strcmp(name, "_id") == 0) {
|
||||||
|
std::string id(trx->resolver()->getCollectionName(document->_info._cid));
|
||||||
|
id.push_back('/');
|
||||||
|
id.append(TRI_EXTRACT_MARKER_KEY(_marker));
|
||||||
|
return Json(TRI_UNKNOWN_MEM_ZONE, id);
|
||||||
|
}
|
||||||
|
else if (strcmp(name, "_rev") == 0) {
|
||||||
|
TRI_voc_rid_t rid = TRI_EXTRACT_MARKER_RID(_marker);
|
||||||
|
return Json(TRI_UNKNOWN_MEM_ZONE, JsonHelper::uint64String(TRI_UNKNOWN_MEM_ZONE, rid));
|
||||||
|
}
|
||||||
|
else if (strcmp(name, "_from") == 0) {
|
||||||
|
std::string from(trx->resolver()->getCollectionName(TRI_EXTRACT_MARKER_FROM_CID(_marker)));
|
||||||
|
from.push_back('/');
|
||||||
|
from.append(TRI_EXTRACT_MARKER_FROM_KEY(_marker));
|
||||||
|
return Json(TRI_UNKNOWN_MEM_ZONE, from);
|
||||||
|
}
|
||||||
|
else if (strcmp(name, "_to") == 0) {
|
||||||
|
std::string to(trx->resolver()->getCollectionName(TRI_EXTRACT_MARKER_TO_CID(_marker)));
|
||||||
|
to.push_back('/');
|
||||||
|
to.append(TRI_EXTRACT_MARKER_TO_KEY(_marker));
|
||||||
|
return Json(TRI_UNKNOWN_MEM_ZONE, to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_shape_pid_t pid = shaper->lookupAttributePathByName(shaper, name);
|
||||||
|
if (pid != 0) {
|
||||||
|
// attribute exists
|
||||||
|
TRI_shaped_json_t document;
|
||||||
|
TRI_EXTRACT_SHAPED_JSON_MARKER(document, _marker);
|
||||||
|
|
||||||
|
TRI_shaped_json_t json;
|
||||||
|
TRI_shape_t const* shape;
|
||||||
|
|
||||||
|
bool ok = TRI_ExtractShapedJsonVocShaper(shaper, &document, 0, pid, &json, &shape);
|
||||||
|
if (ok && shape != nullptr) {
|
||||||
|
return Json(TRI_UNKNOWN_MEM_ZONE, TRI_JsonShapedJson(shaper, &json));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// attribute does not exist or something went wrong - fall-through to returning null
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DOCVEC:
|
||||||
|
case RANGE:
|
||||||
|
case EMPTY: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Json(Json::Null);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief create an AqlValue from a vector of AqlItemBlock*s
|
/// @brief create an AqlValue from a vector of AqlItemBlock*s
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -156,6 +156,32 @@ namespace triagens {
|
||||||
|
|
||||||
bool isString () const;
|
bool isString () const;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief whether or not the AqlValue contains a list value
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool isList () const;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief whether or not the AqlValue contains an array value
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool isArray () const;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief get a string representation of the AqlValue
|
||||||
|
/// this will fail if the value is not a string
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::string toString () const;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief get a string representation of the AqlValue
|
||||||
|
/// this will fail if the value is not a string
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
char const* toChar () const;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief construct a V8 value as input for the expression execution in V8
|
/// @brief construct a V8 value as input for the expression execution in V8
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -170,6 +196,15 @@ namespace triagens {
|
||||||
triagens::basics::Json toJson (AQL_TRANSACTION_V8*,
|
triagens::basics::Json toJson (AQL_TRANSACTION_V8*,
|
||||||
TRI_document_collection_t const*) const;
|
TRI_document_collection_t const*) const;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief extract an attribute value from the AqlValue
|
||||||
|
/// this will fail if the value is not an array
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
triagens::basics::Json extractArrayMember (AQL_TRANSACTION_V8*,
|
||||||
|
TRI_document_collection_t const*,
|
||||||
|
char const*) const;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief create an AqlValue from a vector of AqlItemBlock*s
|
/// @brief create an AqlValue from a vector of AqlItemBlock*s
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -37,6 +37,16 @@
|
||||||
|
|
||||||
using namespace triagens::aql;
|
using namespace triagens::aql;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- static initialization
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief initialize a singleton NOP node instance
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
AstNode const Ast::NopNode = { NODE_TYPE_NOP };
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- constructors / destructors
|
// --SECTION-- constructors / destructors
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -181,12 +191,18 @@ AstNode* Ast::createNodeReturn (AstNode const* expression) {
|
||||||
|
|
||||||
AstNode* Ast::createNodeRemove (AstNode const* expression,
|
AstNode* Ast::createNodeRemove (AstNode const* expression,
|
||||||
AstNode const* collection,
|
AstNode const* collection,
|
||||||
AstNode* options) {
|
AstNode const* options) {
|
||||||
AstNode* node = createNode(NODE_TYPE_REMOVE);
|
AstNode* node = createNode(NODE_TYPE_REMOVE);
|
||||||
|
|
||||||
|
if (options == nullptr) {
|
||||||
|
// no options given. now use default options
|
||||||
|
options = &NopNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->addMember(options);
|
||||||
node->addMember(collection);
|
node->addMember(collection);
|
||||||
node->addMember(expression);
|
node->addMember(expression);
|
||||||
|
|
||||||
// TODO: handle options
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,9 +730,7 @@ AstNode* Ast::createNodeRange (AstNode const* start,
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
AstNode* Ast::createNodeNop () {
|
AstNode* Ast::createNodeNop () {
|
||||||
AstNode* node = createNode(NODE_TYPE_NOP);
|
return const_cast<AstNode*>(&NopNode);
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -253,7 +253,7 @@ namespace triagens {
|
||||||
|
|
||||||
AstNode* createNodeRemove (AstNode const*,
|
AstNode* createNodeRemove (AstNode const*,
|
||||||
AstNode const*,
|
AstNode const*,
|
||||||
AstNode*);
|
AstNode const*);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief create an AST insert node
|
/// @brief create an AST insert node
|
||||||
|
@ -679,6 +679,12 @@ namespace triagens {
|
||||||
|
|
||||||
AstNode const* _writeOptions;
|
AstNode const* _writeOptions;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief a singleton NOP node instance
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static AstNode const NopNode;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,6 +236,35 @@ void AstNode::toJson (TRI_json_t* json,
|
||||||
TRI_PushBack3ListJson(zone, json, node);
|
TRI_PushBack3ListJson(zone, json, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief convert the node's value to a boolean value
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool AstNode::toBoolean () const {
|
||||||
|
if (type == NODE_TYPE_VALUE) {
|
||||||
|
switch (value.type) {
|
||||||
|
case VALUE_TYPE_BOOL: {
|
||||||
|
return value.value._bool;
|
||||||
|
}
|
||||||
|
case VALUE_TYPE_INT: {
|
||||||
|
return (value.value._int != 0);
|
||||||
|
}
|
||||||
|
case VALUE_TYPE_DOUBLE: {
|
||||||
|
return value.value._double != 0.0;
|
||||||
|
}
|
||||||
|
case VALUE_TYPE_STRING: {
|
||||||
|
return (*value.value._string != '\0');
|
||||||
|
}
|
||||||
|
case VALUE_TYPE_NULL:
|
||||||
|
case VALUE_TYPE_FAIL: {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief whether or not a node is simple enough to be used in a simple
|
/// @brief whether or not a node is simple enough to be used in a simple
|
||||||
/// expression
|
/// expression
|
||||||
|
|
|
@ -181,6 +181,12 @@ namespace triagens {
|
||||||
void toJson (TRI_json_t*,
|
void toJson (TRI_json_t*,
|
||||||
TRI_memory_zone_t*) const;
|
TRI_memory_zone_t*) const;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief convert the node's value to a boolean value
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool toBoolean () const;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief whether or not a value node is of numeric type
|
/// @brief whether or not a value node is of numeric type
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -422,12 +428,30 @@ namespace triagens {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief the node type
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
AstNodeType const type;
|
AstNodeType const type;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief the node value
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
AstNodeValue value;
|
AstNodeValue value;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- private variables
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief the node's sub nodes
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TRI_vector_pointer_t members;
|
TRI_vector_pointer_t members;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1888,9 +1888,46 @@ RemoveBlock::RemoveBlock (AQL_TRANSACTION_V8* trx,
|
||||||
RemoveBlock::~RemoveBlock () {
|
RemoveBlock::~RemoveBlock () {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief get some - this accumulates all input and calls the remove() method
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
AqlItemBlock* RemoveBlock::getSome (size_t atLeast,
|
AqlItemBlock* RemoveBlock::getSome (size_t atLeast,
|
||||||
size_t atMost) {
|
size_t atMost) {
|
||||||
|
|
||||||
|
std::vector<AqlItemBlock*> blocks;
|
||||||
|
|
||||||
|
// loop over input until it is exhausted
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
auto res = ExecutionBlock::getSome(atLeast, atMost);
|
||||||
|
|
||||||
|
if (res == nullptr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
blocks.push_back(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(blocks);
|
||||||
|
for (auto it = blocks.begin(); it != blocks.end(); ++it) {
|
||||||
|
delete (*it);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
for (auto it = blocks.begin(); it != blocks.end(); ++it) {
|
||||||
|
delete (*it);
|
||||||
|
}
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief the actual work horse for removing data
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void RemoveBlock::remove (std::vector<AqlItemBlock*>& blocks) {
|
||||||
auto ep = static_cast<RemoveNode const*>(getPlanNode());
|
auto ep = static_cast<RemoveNode const*>(getPlanNode());
|
||||||
auto it = _varOverview->varInfo.find(ep->_inVariable->id);
|
auto it = _varOverview->varInfo.find(ep->_inVariable->id);
|
||||||
TRI_ASSERT(it != _varOverview->varInfo.end());
|
TRI_ASSERT(it != _varOverview->varInfo.end());
|
||||||
|
@ -1901,54 +1938,66 @@ AqlItemBlock* RemoveBlock::getSome (size_t atLeast,
|
||||||
if (ep->_outVariable == nullptr) {
|
if (ep->_outVariable == nullptr) {
|
||||||
// don't return anything
|
// don't return anything
|
||||||
|
|
||||||
// loop over input until it is exhausted
|
// loop over all blocks
|
||||||
while (true) {
|
for (auto it = blocks.begin(); it != blocks.end(); ++it) {
|
||||||
auto res = ExecutionBlock::getSome(atLeast, atMost);
|
auto res = (*it);
|
||||||
|
|
||||||
if (res == nullptr) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto document = res->getDocumentCollection(registerId);
|
auto document = res->getDocumentCollection(registerId);
|
||||||
|
|
||||||
try {
|
|
||||||
size_t const n = res->size();
|
size_t const n = res->size();
|
||||||
|
|
||||||
|
// loop over the complete block
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
AqlValue a = res->getValue(i, registerId);
|
AqlValue a = res->getValue(i, registerId);
|
||||||
|
|
||||||
if (a.isEmpty()) {
|
char const* key = nullptr;
|
||||||
// no value for _key. TODO: should we fail with an error in this case?
|
int errorCode = TRI_ERROR_NO_ERROR;
|
||||||
|
|
||||||
|
if (a.isArray()) {
|
||||||
|
// value is an array. now extract the _key attribute
|
||||||
|
Json member(a.extractArrayMember(_trx, document, "_key"));
|
||||||
|
|
||||||
|
TRI_json_t* json = member.json();
|
||||||
|
if (TRI_IsStringJson(json)) {
|
||||||
|
key = json->_value._string.data;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errorCode = TRI_ERROR_ARANGO_DOCUMENT_KEY_MISSING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (a.isString()) {
|
||||||
|
// value is a string
|
||||||
|
key = a.toChar();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errorCode = TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorCode != TRI_ERROR_NO_ERROR) {
|
||||||
|
if (ep->_options.ignoreErrors) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
THROW_ARANGO_EXCEPTION(errorCode);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// no error. we expect to have a key
|
||||||
|
TRI_ASSERT(key != nullptr);
|
||||||
|
|
||||||
if (a.isString()) {
|
errorCode = TRI_RemoveShapedJsonDocumentCollection(trxCollection,
|
||||||
std::cout << "VALUE IS A STRING\n";
|
(TRI_voc_key_t) key,
|
||||||
|
0,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
false,
|
||||||
|
ep->_options.waitForSync);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << JsonHelper::toString(a.toJson(_trx, document)) << "\n";
|
(*it) = nullptr;
|
||||||
std::string key = "gig";
|
|
||||||
|
|
||||||
int removed = TRI_RemoveShapedJsonDocumentCollection(trxCollection, (TRI_voc_key_t) key.c_str(), 0, nullptr, nullptr, false, false);
|
|
||||||
|
|
||||||
std::cout << "REMOVE RESULT: " << removed << "\n";
|
|
||||||
}
|
|
||||||
delete res;
|
delete res;
|
||||||
}
|
}
|
||||||
catch (...) {
|
|
||||||
delete res;
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// will never get here
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOT YET IMPLEMENTED
|
|
||||||
TRI_ASSERT(false);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- struct ExecutionBlock::VarOverview
|
// --SECTION-- struct ExecutionBlock::VarOverview
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -1058,6 +1058,18 @@ namespace triagens {
|
||||||
virtual AqlItemBlock* getSome (size_t atLeast,
|
virtual AqlItemBlock* getSome (size_t atLeast,
|
||||||
size_t atMost);
|
size_t atMost);
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- private methods
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief the actual work horse for removing data
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void remove (std::vector<AqlItemBlock*>&);
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- private variables
|
// --SECTION-- private variables
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
#include "Aql/Collection.h"
|
#include "Aql/Collection.h"
|
||||||
#include "Aql/Expression.h"
|
#include "Aql/Expression.h"
|
||||||
|
#include "Aql/ModificationOptions.h"
|
||||||
#include "Aql/Variable.h"
|
#include "Aql/Variable.h"
|
||||||
#include "Aql/Types.h"
|
#include "Aql/Types.h"
|
||||||
#include "Aql/WalkerWorker.h"
|
#include "Aql/WalkerWorker.h"
|
||||||
|
@ -1087,6 +1088,63 @@ namespace triagens {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- class ModificationNode
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief abstract base class for modification operations
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class ModificationNode : public ExecutionNode {
|
||||||
|
|
||||||
|
friend class ExecutionBlock;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief constructor with a vocbase and a collection and options
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
ModificationNode (TRI_vocbase_t* vocbase,
|
||||||
|
Collection* collection,
|
||||||
|
ModificationOptions const& options)
|
||||||
|
: ExecutionNode(),
|
||||||
|
_vocbase(vocbase),
|
||||||
|
_collection(collection),
|
||||||
|
_options(options) {
|
||||||
|
|
||||||
|
TRI_ASSERT(_vocbase != nullptr);
|
||||||
|
TRI_ASSERT(_collection != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- protected variables
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief _vocbase, the database
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TRI_vocbase_t* _vocbase;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief collection
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Collection* _collection;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief modification operation options
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ModificationOptions _options;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- class RemoveNode
|
// --SECTION-- class RemoveNode
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -1095,7 +1153,7 @@ namespace triagens {
|
||||||
/// @brief class RemoveNode
|
/// @brief class RemoveNode
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class RemoveNode : public ExecutionNode {
|
class RemoveNode : public ModificationNode {
|
||||||
|
|
||||||
friend class ExecutionBlock;
|
friend class ExecutionBlock;
|
||||||
friend class RemoveBlock;
|
friend class RemoveBlock;
|
||||||
|
@ -1108,16 +1166,13 @@ namespace triagens {
|
||||||
|
|
||||||
RemoveNode (TRI_vocbase_t* vocbase,
|
RemoveNode (TRI_vocbase_t* vocbase,
|
||||||
Collection* collection,
|
Collection* collection,
|
||||||
|
ModificationOptions const& options,
|
||||||
Variable const* inVariable,
|
Variable const* inVariable,
|
||||||
Variable const* outVariable)
|
Variable const* outVariable)
|
||||||
: ExecutionNode(),
|
: ModificationNode(vocbase, collection, options),
|
||||||
_vocbase(vocbase),
|
|
||||||
_collection(collection),
|
|
||||||
_inVariable(inVariable),
|
_inVariable(inVariable),
|
||||||
_outVariable(outVariable) {
|
_outVariable(outVariable) {
|
||||||
|
|
||||||
TRI_ASSERT(_vocbase != nullptr);
|
|
||||||
TRI_ASSERT(_collection != nullptr);
|
|
||||||
TRI_ASSERT(_inVariable != nullptr);
|
TRI_ASSERT(_inVariable != nullptr);
|
||||||
// _outVariable might be a nullptr
|
// _outVariable might be a nullptr
|
||||||
}
|
}
|
||||||
|
@ -1143,7 +1198,7 @@ namespace triagens {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual ExecutionNode* clone () const {
|
virtual ExecutionNode* clone () const {
|
||||||
auto c = new RemoveNode(_vocbase, _collection, _inVariable, _outVariable);
|
auto c = new RemoveNode(_vocbase, _collection, _options, _inVariable, _outVariable);
|
||||||
cloneDependencies(c);
|
cloneDependencies(c);
|
||||||
return static_cast<ExecutionNode*>(c);
|
return static_cast<ExecutionNode*>(c);
|
||||||
}
|
}
|
||||||
|
@ -1164,18 +1219,6 @@ namespace triagens {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief _vocbase, the database
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_vocbase_t* _vocbase;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief collection
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
Collection* _collection;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief input variable
|
/// @brief input variable
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -99,6 +99,37 @@ ExecutionPlan* ExecutionPlan::instanciateFromAst (Ast const* ast) {
|
||||||
// --SECTION-- private functions
|
// --SECTION-- private functions
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief create modification options from an AST node
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ModificationOptions ExecutionPlan::createOptions (AstNode const* node) {
|
||||||
|
ModificationOptions options;
|
||||||
|
|
||||||
|
// parse the modification options we got
|
||||||
|
if (node != nullptr && node->type == NODE_TYPE_ARRAY) {
|
||||||
|
size_t n = node->numMembers();
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
auto member = node->getMember(i);
|
||||||
|
if (member != nullptr && member->type == NODE_TYPE_ARRAY_ELEMENT) {
|
||||||
|
auto name = member->getStringValue();
|
||||||
|
auto value = member->getMember(0);
|
||||||
|
|
||||||
|
TRI_ASSERT(value->isConstant());
|
||||||
|
|
||||||
|
if (strcmp(name, "waitForSync") == 0) {
|
||||||
|
options.waitForSync = value->toBoolean();
|
||||||
|
}
|
||||||
|
else if (strcmp(name, "ignoreErrors") == 0) {
|
||||||
|
options.ignoreErrors = value->toBoolean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief add a node to the plan, will delete node if addition fails
|
/// @brief add a node to the plan, will delete node if addition fails
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -487,9 +518,10 @@ ExecutionNode* ExecutionPlan::fromNodeRemove (Ast const* ast,
|
||||||
ExecutionNode* previous,
|
ExecutionNode* previous,
|
||||||
AstNode const* node) {
|
AstNode const* node) {
|
||||||
TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_REMOVE);
|
TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_REMOVE);
|
||||||
TRI_ASSERT(node->numMembers() == 2);
|
TRI_ASSERT(node->numMembers() == 3);
|
||||||
|
|
||||||
char const* collectionName = node->getMember(0)->getStringValue();
|
auto options = createOptions(node->getMember(0));
|
||||||
|
char const* collectionName = node->getMember(1)->getStringValue();
|
||||||
auto collections = ast->query()->collections();
|
auto collections = ast->query()->collections();
|
||||||
auto collection = collections->get(collectionName);
|
auto collection = collections->get(collectionName);
|
||||||
|
|
||||||
|
@ -497,20 +529,20 @@ ExecutionNode* ExecutionPlan::fromNodeRemove (Ast const* ast,
|
||||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto expression = node->getMember(1);
|
auto expression = node->getMember(2);
|
||||||
ExecutionNode* en = nullptr;
|
ExecutionNode* en = nullptr;
|
||||||
|
|
||||||
if (expression->type == NODE_TYPE_REFERENCE) {
|
if (expression->type == NODE_TYPE_REFERENCE) {
|
||||||
// operand is already a variable
|
// operand is already a variable
|
||||||
auto v = static_cast<Variable*>(expression->getData());
|
auto v = static_cast<Variable*>(expression->getData());
|
||||||
TRI_ASSERT(v != nullptr);
|
TRI_ASSERT(v != nullptr);
|
||||||
en = addNode(new RemoveNode(ast->query()->vocbase(), collection, v, nullptr));
|
en = addNode(new RemoveNode(ast->query()->vocbase(), collection, options, v, nullptr));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// operand is some misc expression
|
// operand is some misc expression
|
||||||
auto calc = createTemporaryCalculation(ast, expression);
|
auto calc = createTemporaryCalculation(ast, expression);
|
||||||
calc->addDependency(previous);
|
calc->addDependency(previous);
|
||||||
en = addNode(new RemoveNode(ast->query()->vocbase(), collection, calc->outVariable(), nullptr));
|
en = addNode(new RemoveNode(ast->query()->vocbase(), collection, options, calc->outVariable(), nullptr));
|
||||||
previous = calc;
|
previous = calc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
#include "Basics/Common.h"
|
#include "Basics/Common.h"
|
||||||
#include "arangod/Aql/ExecutionNode.h"
|
#include "arangod/Aql/ExecutionNode.h"
|
||||||
|
#include "arangod/Aql/ModificationOptions.h"
|
||||||
|
|
||||||
namespace triagens {
|
namespace triagens {
|
||||||
namespace aql {
|
namespace aql {
|
||||||
|
@ -109,6 +110,12 @@ namespace triagens {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief create modification options from an AST node
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ModificationOptions createOptions (AstNode const*);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief add a node to the plan, will delete node if addition fails
|
/// @brief add a node to the plan, will delete node if addition fails
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -162,8 +162,6 @@ void Expression::analyzeExpression () {
|
||||||
_type = V8;
|
_type = V8;
|
||||||
_canThrow = _node->canThrow();
|
_canThrow = _node->canThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "CAN THROW: " << _canThrow << "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -191,68 +189,8 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
|
||||||
if (result._type == AqlValue::SHAPED) {
|
if (result._type == AqlValue::SHAPED) {
|
||||||
TRI_ASSERT(myCollection != nullptr);
|
TRI_ASSERT(myCollection != nullptr);
|
||||||
|
|
||||||
auto shaper = myCollection->getShaper();
|
auto j = result.extractArrayMember(trx, myCollection, name);
|
||||||
|
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal()));
|
||||||
// look for the attribute name in the shape
|
|
||||||
if (*name == '_') {
|
|
||||||
if (strcmp(name, "_key") == 0) {
|
|
||||||
// _key value is copied into JSON
|
|
||||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, TRI_EXTRACT_MARKER_KEY(result._marker)));
|
|
||||||
}
|
|
||||||
else if (strcmp(name, "_id") == 0) {
|
|
||||||
std::string id(trx->resolver()->getCollectionName(myCollection->_info._cid));
|
|
||||||
id.push_back('/');
|
|
||||||
id.append(TRI_EXTRACT_MARKER_KEY(result._marker));
|
|
||||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, id));
|
|
||||||
}
|
|
||||||
else if (strcmp(name, "_rev") == 0) {
|
|
||||||
TRI_voc_rid_t rid = TRI_EXTRACT_MARKER_RID(result._marker);
|
|
||||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, JsonHelper::uint64String(TRI_UNKNOWN_MEM_ZONE, rid)));
|
|
||||||
}
|
|
||||||
else if (strcmp(name, "_from") == 0) {
|
|
||||||
std::string from(trx->resolver()->getCollectionName(TRI_EXTRACT_MARKER_FROM_CID(result._marker)));
|
|
||||||
from.push_back('/');
|
|
||||||
from.append(TRI_EXTRACT_MARKER_FROM_KEY(result._marker));
|
|
||||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, from));
|
|
||||||
}
|
|
||||||
else if (strcmp(name, "_to") == 0) {
|
|
||||||
std::string to(trx->resolver()->getCollectionName(TRI_EXTRACT_MARKER_TO_CID(result._marker)));
|
|
||||||
to.push_back('/');
|
|
||||||
to.append(TRI_EXTRACT_MARKER_TO_KEY(result._marker));
|
|
||||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, to));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TRI_shape_pid_t pid = shaper->lookupAttributePathByName(shaper, name);
|
|
||||||
if (pid != 0) {
|
|
||||||
// attribute exists
|
|
||||||
TRI_shaped_json_t document;
|
|
||||||
TRI_EXTRACT_SHAPED_JSON_MARKER(document, result._marker);
|
|
||||||
|
|
||||||
TRI_shaped_json_t json;
|
|
||||||
TRI_shape_t const* shape;
|
|
||||||
|
|
||||||
bool ok = TRI_ExtractShapedJsonVocShaper(shaper, &document, 0, pid, &json, &shape);
|
|
||||||
if (ok && shape != nullptr) {
|
|
||||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, TRI_JsonShapedJson(shaper, &json)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// attribute does not exist or something went wrong - fall-through to returning null below
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (result._type == AqlValue::JSON) {
|
|
||||||
TRI_json_t const* json = result._json->json();
|
|
||||||
|
|
||||||
if (TRI_IsArrayJson(json)) {
|
|
||||||
TRI_json_t const* found = TRI_LookupArrayJson(json, name);
|
|
||||||
|
|
||||||
if (found != nullptr) {
|
|
||||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, found)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// attribute does not exist or something went wrong - fall-through to returning null below
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return AqlValue(new Json(Json::Null));
|
return AqlValue(new Json(Json::Null));
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief AQL, data-modification query options
|
||||||
|
///
|
||||||
|
/// @file
|
||||||
|
///
|
||||||
|
/// DISCLAIMER
|
||||||
|
///
|
||||||
|
/// Copyright 2010-2014 triagens GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
/// you may not use this file except in compliance with the License.
|
||||||
|
/// You may obtain a copy of the License at
|
||||||
|
///
|
||||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
///
|
||||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
/// See the License for the specific language governing permissions and
|
||||||
|
/// limitations under the License.
|
||||||
|
///
|
||||||
|
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// @author Max Neunhoeffer
|
||||||
|
/// @author Copyright 2014, triagens GmbH, Cologne, Germany
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef ARANGODB_AQL_MODIFICATION_OPTIONS_H
|
||||||
|
#define ARANGODB_AQL_MODIFICATION_OPTIONS_H 1
|
||||||
|
|
||||||
|
#include "Basics/Common.h"
|
||||||
|
|
||||||
|
namespace triagens {
|
||||||
|
namespace aql {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief ModificationOptions
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct ModificationOptions {
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- constructors / destructors
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief constructor, using default values
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ModificationOptions ()
|
||||||
|
: ignoreErrors(false),
|
||||||
|
waitForSync(false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- public variables
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool ignoreErrors;
|
||||||
|
bool waitForSync;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace triagens::aql
|
||||||
|
} // namespace triagens
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Local Variables:
|
||||||
|
// mode: outline-minor
|
||||||
|
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
|
||||||
|
// End:
|
||||||
|
|
Loading…
Reference in New Issue