mirror of https://gitee.com/bigwinds/arangodb
added mergeArrays
This commit is contained in:
parent
a1892e0c7a
commit
7ef8097fe1
|
@ -3369,7 +3369,7 @@ void UpdateBlock::work (std::vector<AqlItemBlock*>& blocks) {
|
|||
TRI_json_t* old = TRI_JsonShapedJson(_collection->documentCollection()->getShaper(), &shapedJson);
|
||||
|
||||
if (old != nullptr) {
|
||||
TRI_json_t* patchedJson = TRI_MergeJson(TRI_UNKNOWN_MEM_ZONE, old, json.json(), ep->_options.nullMeansRemove);
|
||||
TRI_json_t* patchedJson = TRI_MergeJson(TRI_UNKNOWN_MEM_ZONE, old, json.json(), ep->_options.nullMeansRemove, ep->_options.mergeArrays);
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, old);
|
||||
|
||||
if (patchedJson != nullptr) {
|
||||
|
|
|
@ -251,6 +251,9 @@ ModificationOptions ExecutionPlan::createOptions (AstNode const* node) {
|
|||
// nullMeansRemove is the opposite of keepNull
|
||||
options.nullMeansRemove = value->isFalse();
|
||||
}
|
||||
else if (strcmp(name, "mergeArrays") == 0) {
|
||||
options.mergeArrays = value->isTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ ModificationOptions::ModificationOptions (Json const& json) {
|
|||
ignoreErrors = JsonHelper::getBooleanValue(array.json(), "ignoreErrors", false);
|
||||
waitForSync = JsonHelper::getBooleanValue(array.json(), "waitForSync", false);
|
||||
nullMeansRemove = JsonHelper::getBooleanValue(array.json(), "nullMeansRemove", false);
|
||||
mergeArrays = JsonHelper::getBooleanValue(array.json(), "mergeArrays", false);
|
||||
}
|
||||
|
||||
void ModificationOptions::toJson (triagens::basics::Json& json,
|
||||
|
@ -44,7 +45,8 @@ void ModificationOptions::toJson (triagens::basics::Json& json,
|
|||
flags = Json(Json::Array, 3)
|
||||
("ignoreErrors", Json(ignoreErrors))
|
||||
("waitForSync", Json(waitForSync))
|
||||
("nullMeansRemove", Json(nullMeansRemove));
|
||||
("nullMeansRemove", Json(nullMeansRemove))
|
||||
("mergeArrays", Json(mergeArrays));
|
||||
|
||||
json ("modificationFlags", flags);
|
||||
}
|
||||
|
|
|
@ -53,7 +53,8 @@ namespace triagens {
|
|||
ModificationOptions ()
|
||||
: ignoreErrors(false),
|
||||
waitForSync(false),
|
||||
nullMeansRemove(false) {
|
||||
nullMeansRemove(false),
|
||||
mergeArrays(false) {
|
||||
}
|
||||
|
||||
void toJson (triagens::basics::Json& json, TRI_memory_zone_t* zone) const;
|
||||
|
@ -65,6 +66,7 @@ namespace triagens {
|
|||
bool ignoreErrors;
|
||||
bool waitForSync;
|
||||
bool nullMeansRemove;
|
||||
bool mergeArrays;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -1051,6 +1051,7 @@ int modifyDocumentOnCoordinator (
|
|||
bool waitForSync,
|
||||
bool isPatch,
|
||||
bool keepNull, // only counts for isPatch == true
|
||||
bool mergeArrays, // only counts for isPatch == true
|
||||
TRI_json_t* json,
|
||||
map<string, string> const& headers,
|
||||
triagens::rest::HttpResponse::HttpResponseCode& responseCode,
|
||||
|
@ -1115,6 +1116,12 @@ int modifyDocumentOnCoordinator (
|
|||
if (! keepNull) {
|
||||
revstr += "&keepNull=false";
|
||||
}
|
||||
if (mergeArrays) {
|
||||
revstr += "&mergeArrays=true";
|
||||
}
|
||||
else {
|
||||
revstr += "&mergeArrays=false";
|
||||
}
|
||||
}
|
||||
else {
|
||||
reqType = triagens::rest::HttpRequest::HTTP_REQUEST_PUT;
|
||||
|
|
|
@ -177,6 +177,7 @@ namespace triagens {
|
|||
bool waitForSync,
|
||||
bool isPatch,
|
||||
bool keepNull, // only counts for isPatch == true
|
||||
bool mergeArrays, // only counts for isPatch == true
|
||||
TRI_json_t* json,
|
||||
std::map<std::string, std::string> const& headers,
|
||||
triagens::rest::HttpResponse::HttpResponseCode& responseCode,
|
||||
|
|
|
@ -1202,6 +1202,12 @@ bool RestDocumentHandler::replaceDocument () {
|
|||
/// from the existing document that are contained in the patch document with an
|
||||
/// attribute value of *null*.
|
||||
///
|
||||
/// @RESTQUERYPARAM{mergeArrays,boolean,optional}
|
||||
/// Controls whether arrays (not lists) will be merged if present in both the
|
||||
/// existing and the patch document. If set to *false*, the value in the
|
||||
/// patch document will overwrite the existing document's value. If set to
|
||||
/// *true*, arrays will be merged. The default is *true*.
|
||||
///
|
||||
/// @RESTQUERYPARAM{waitForSync,boolean,optional}
|
||||
/// Wait until document has been synced to disk.
|
||||
///
|
||||
|
@ -1410,6 +1416,7 @@ bool RestDocumentHandler::modifyDocument (bool isPatch) {
|
|||
if (isPatch) {
|
||||
// patching an existing document
|
||||
bool nullMeansRemove;
|
||||
bool mergeArrays;
|
||||
bool found;
|
||||
char const* valueStr = _request->value("keepNull", found);
|
||||
if (! found || StringUtils::boolean(valueStr)) {
|
||||
|
@ -1421,6 +1428,15 @@ bool RestDocumentHandler::modifyDocument (bool isPatch) {
|
|||
nullMeansRemove = true;
|
||||
}
|
||||
|
||||
valueStr = _request->value("mergeArrays", found);
|
||||
if (! found || StringUtils::boolean(valueStr)) {
|
||||
// the default is true
|
||||
mergeArrays = true;
|
||||
}
|
||||
else {
|
||||
mergeArrays = false;
|
||||
}
|
||||
|
||||
// read the existing document
|
||||
TRI_doc_mptr_copy_t oldDocument;
|
||||
|
||||
|
@ -1471,7 +1487,7 @@ bool RestDocumentHandler::modifyDocument (bool isPatch) {
|
|||
}
|
||||
}
|
||||
|
||||
TRI_json_t* patchedJson = TRI_MergeJson(TRI_UNKNOWN_MEM_ZONE, old, json, nullMeansRemove);
|
||||
TRI_json_t* patchedJson = TRI_MergeJson(TRI_UNKNOWN_MEM_ZONE, old, json, nullMeansRemove, mergeArrays);
|
||||
TRI_FreeJson(shaper->_memoryZone, old);
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||
|
||||
|
@ -1574,13 +1590,17 @@ bool RestDocumentHandler::modifyDocumentCoordinator (
|
|||
string resultBody;
|
||||
|
||||
bool keepNull = true;
|
||||
if (! strcmp(_request->value("keepNull"),"false")) {
|
||||
if (! strcmp(_request->value("keepNull"), "false")) {
|
||||
keepNull = false;
|
||||
}
|
||||
bool mergeArrays = true;
|
||||
if (TRI_EqualString(_request->value("mergeArrays"), "false")) {
|
||||
mergeArrays = false;
|
||||
}
|
||||
|
||||
int error = triagens::arango::modifyDocumentOnCoordinator(
|
||||
dbname, collname, key, rev, policy, waitForSync, isPatch,
|
||||
keepNull, json, headers, responseCode, resultHeaders, resultBody);
|
||||
keepNull, mergeArrays, json, headers, responseCode, resultHeaders, resultBody);
|
||||
|
||||
if (error != TRI_ERROR_NO_ERROR) {
|
||||
generateTransactionError(collname, error);
|
||||
|
|
|
@ -91,6 +91,7 @@ struct InsertOptions {
|
|||
struct UpdateOptions {
|
||||
bool overwrite = false;
|
||||
bool keepNull = true;
|
||||
bool mergeArrays = true;
|
||||
bool waitForSync = false;
|
||||
bool silent = false;
|
||||
};
|
||||
|
@ -701,6 +702,7 @@ static v8::Handle<v8::Value> ModifyVocbaseColCoordinator (
|
|||
bool waitForSync,
|
||||
bool isPatch,
|
||||
bool keepNull, // only counts if isPatch==true
|
||||
bool mergeArrays, // only counts if isPatch==true
|
||||
bool silent,
|
||||
v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
|
@ -734,7 +736,7 @@ static v8::Handle<v8::Value> ModifyVocbaseColCoordinator (
|
|||
|
||||
error = triagens::arango::modifyDocumentOnCoordinator(
|
||||
dbname, collname, key, rev, policy, waitForSync, isPatch,
|
||||
keepNull, json, headers, responseCode, resultHeaders, resultBody);
|
||||
keepNull, mergeArrays, json, headers, responseCode, resultHeaders, resultBody);
|
||||
// Note that the json has been freed inside!
|
||||
|
||||
if (error != TRI_ERROR_NO_ERROR) {
|
||||
|
@ -875,6 +877,7 @@ static v8::Handle<v8::Value> ReplaceVocbaseCol (bool useCollection,
|
|||
options.waitForSync,
|
||||
false, // isPatch
|
||||
true, // keepNull, does not matter
|
||||
false, // mergeArrays, does not matter
|
||||
options.silent,
|
||||
argv));
|
||||
}
|
||||
|
@ -1081,7 +1084,7 @@ static v8::Handle<v8::Value> UpdateVocbaseCol (bool useCollection,
|
|||
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
|
||||
|
||||
if (argLength < 2 || argLength > 5) {
|
||||
TRI_V8_EXCEPTION_USAGE(scope, "update(<document>, <data>, {overwrite: booleanValue, keepNull: booleanValue, waitForSync: booleanValue})");
|
||||
TRI_V8_EXCEPTION_USAGE(scope, "update(<document>, <data>, {overwrite: booleanValue, keepNull: booleanValue, mergeArrays: booleanValue, waitForSync: booleanValue})");
|
||||
}
|
||||
|
||||
if (argLength > 2) {
|
||||
|
@ -1094,6 +1097,9 @@ static v8::Handle<v8::Value> UpdateVocbaseCol (bool useCollection,
|
|||
if (optionsObject->Has(v8g->KeepNullKey)) {
|
||||
options.keepNull = TRI_ObjectToBoolean(optionsObject->Get(v8g->KeepNullKey));
|
||||
}
|
||||
if (optionsObject->Has(v8g->MergeArraysKey)) {
|
||||
options.mergeArrays = TRI_ObjectToBoolean(optionsObject->Get(v8g->MergeArraysKey));
|
||||
}
|
||||
if (optionsObject->Has(v8g->WaitForSyncKey)) {
|
||||
options.waitForSync = TRI_ObjectToBoolean(optionsObject->Get(v8g->WaitForSyncKey));
|
||||
}
|
||||
|
@ -1160,6 +1166,7 @@ static v8::Handle<v8::Value> UpdateVocbaseCol (bool useCollection,
|
|||
options.waitForSync,
|
||||
true, // isPatch
|
||||
options.keepNull,
|
||||
options.mergeArrays,
|
||||
options.silent,
|
||||
argv));
|
||||
}
|
||||
|
@ -1226,7 +1233,7 @@ static v8::Handle<v8::Value> UpdateVocbaseCol (bool useCollection,
|
|||
}
|
||||
}
|
||||
|
||||
TRI_json_t* patchedJson = TRI_MergeJson(TRI_UNKNOWN_MEM_ZONE, old, json, ! options.keepNull);
|
||||
TRI_json_t* patchedJson = TRI_MergeJson(TRI_UNKNOWN_MEM_ZONE, old, json, ! options.keepNull, options.mergeArrays);
|
||||
TRI_FreeJson(zone, old);
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||
|
||||
|
|
|
@ -786,7 +786,7 @@ class KeySpace {
|
|||
TRI_V8_EXCEPTION(scope, TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
TRI_json_t* merged = TRI_MergeJson(TRI_UNKNOWN_MEM_ZONE, found->json, other, nullMeansRemove);
|
||||
TRI_json_t* merged = TRI_MergeJson(TRI_UNKNOWN_MEM_ZONE, found->json, other, nullMeansRemove, false);
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, other);
|
||||
|
||||
if (merged == nullptr) {
|
||||
|
|
|
@ -1174,6 +1174,7 @@ ArangoCollection.prototype.replace = function (id, data, overwrite, waitForSync)
|
|||
/// @param id the id of the document
|
||||
/// @param overwrite (optional) a boolean value or a json object
|
||||
/// @param keepNull (optional) determines if null values should saved or not
|
||||
/// @param mergeArrays (optional) whether or not array values should be merged
|
||||
/// @param waitForSync (optional) a boolean value .
|
||||
/// @example update("example/996280832675", { a : 1, c : 2} )
|
||||
/// @example update("example/996280832675", { a : 1, c : 2, x: null}, true, true, true)
|
||||
|
@ -1212,6 +1213,11 @@ ArangoCollection.prototype.update = function (id, data, overwrite, keepNull, wai
|
|||
}
|
||||
params = "?keepNull=" + options.keepNull;
|
||||
|
||||
if (! options.hasOwnProperty("mergeArrays")) {
|
||||
options.mergeArrays = true;
|
||||
}
|
||||
params += "&mergeArrays=" + options.mergeArrays;
|
||||
|
||||
if (options.hasOwnProperty("overwrite") && options.overwrite) {
|
||||
params += "&policy=last";
|
||||
}
|
||||
|
|
|
@ -758,6 +758,10 @@ ArangoDatabase.prototype._update = function (id, data, overwrite, keepNull, wait
|
|||
options.keepNull = true;
|
||||
}
|
||||
params = "?keepNull=" + options.keepNull;
|
||||
if (! options.hasOwnProperty("mergeArrays")) {
|
||||
options.mergeArrays = true;
|
||||
}
|
||||
params += "&mergeArrays=" + options.mergeArrays;
|
||||
|
||||
if (options.hasOwnProperty("overwrite") && options.overwrite) {
|
||||
params += "&policy=last";
|
||||
|
|
|
@ -1173,6 +1173,7 @@ ArangoCollection.prototype.replace = function (id, data, overwrite, waitForSync)
|
|||
/// @param id the id of the document
|
||||
/// @param overwrite (optional) a boolean value or a json object
|
||||
/// @param keepNull (optional) determines if null values should saved or not
|
||||
/// @param mergeArrays (optional) whether or not array values should be merged
|
||||
/// @param waitForSync (optional) a boolean value .
|
||||
/// @example update("example/996280832675", { a : 1, c : 2} )
|
||||
/// @example update("example/996280832675", { a : 1, c : 2, x: null}, true, true, true)
|
||||
|
@ -1211,6 +1212,11 @@ ArangoCollection.prototype.update = function (id, data, overwrite, keepNull, wai
|
|||
}
|
||||
params = "?keepNull=" + options.keepNull;
|
||||
|
||||
if (! options.hasOwnProperty("mergeArrays")) {
|
||||
options.mergeArrays = true;
|
||||
}
|
||||
params += "&mergeArrays=" + options.mergeArrays;
|
||||
|
||||
if (options.hasOwnProperty("overwrite") && options.overwrite) {
|
||||
params += "&policy=last";
|
||||
}
|
||||
|
|
|
@ -757,6 +757,10 @@ ArangoDatabase.prototype._update = function (id, data, overwrite, keepNull, wait
|
|||
options.keepNull = true;
|
||||
}
|
||||
params = "?keepNull=" + options.keepNull;
|
||||
if (! options.hasOwnProperty("mergeArrays")) {
|
||||
options.mergeArrays = true;
|
||||
}
|
||||
params += "&mergeArrays=" + options.mergeArrays;
|
||||
|
||||
if (options.hasOwnProperty("overwrite") && options.overwrite) {
|
||||
params += "&policy=last";
|
||||
|
|
|
@ -40,7 +40,8 @@
|
|||
static TRI_json_t* MergeRecursive (TRI_memory_zone_t* zone,
|
||||
TRI_json_t const* lhs,
|
||||
TRI_json_t const* rhs,
|
||||
bool nullMeansRemove) {
|
||||
bool nullMeansRemove,
|
||||
bool mergeArrays) {
|
||||
TRI_json_t* result = TRI_CopyJson(zone, lhs);
|
||||
|
||||
if (result == nullptr) {
|
||||
|
@ -65,7 +66,7 @@ static TRI_json_t* MergeRecursive (TRI_memory_zone_t* zone,
|
|||
// existing array does not have the attribute => append new attribute
|
||||
if (value->_type == TRI_JSON_ARRAY) {
|
||||
TRI_json_t* empty = TRI_CreateArrayJson(zone);
|
||||
TRI_json_t* merged = MergeRecursive(zone, empty, value, nullMeansRemove);
|
||||
TRI_json_t* merged = MergeRecursive(zone, empty, value, nullMeansRemove, mergeArrays);
|
||||
TRI_Insert3ArrayJson(zone, result, key->_value._string.data, merged);
|
||||
|
||||
TRI_FreeJson(zone, empty);
|
||||
|
@ -76,8 +77,8 @@ static TRI_json_t* MergeRecursive (TRI_memory_zone_t* zone,
|
|||
}
|
||||
else {
|
||||
// existing array already has the attribute => replace attribute
|
||||
if (lhsValue->_type == TRI_JSON_ARRAY && value->_type == TRI_JSON_ARRAY) {
|
||||
TRI_json_t* merged = MergeRecursive(zone, lhsValue, value, nullMeansRemove);
|
||||
if (lhsValue->_type == TRI_JSON_ARRAY && value->_type == TRI_JSON_ARRAY && mergeArrays) {
|
||||
TRI_json_t* merged = MergeRecursive(zone, lhsValue, value, nullMeansRemove, mergeArrays);
|
||||
TRI_ReplaceArrayJson(zone, result, key->_value._string.data, merged);
|
||||
TRI_FreeJson(zone, merged);
|
||||
}
|
||||
|
@ -732,13 +733,14 @@ bool TRI_HasDuplicateKeyJson (TRI_json_t const* object) {
|
|||
TRI_json_t* TRI_MergeJson (TRI_memory_zone_t* zone,
|
||||
TRI_json_t const* lhs,
|
||||
TRI_json_t const* rhs,
|
||||
bool nullMeansRemove) {
|
||||
bool nullMeansRemove,
|
||||
bool mergeArrays) {
|
||||
TRI_json_t* result;
|
||||
|
||||
TRI_ASSERT(lhs->_type == TRI_JSON_ARRAY);
|
||||
TRI_ASSERT(rhs->_type == TRI_JSON_ARRAY);
|
||||
|
||||
result = MergeRecursive(zone, lhs, rhs, nullMeansRemove);
|
||||
result = MergeRecursive(zone, lhs, rhs, nullMeansRemove, mergeArrays);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -137,6 +137,7 @@ bool TRI_HasDuplicateKeyJson (TRI_json_t const*);
|
|||
TRI_json_t* TRI_MergeJson (TRI_memory_zone_t*,
|
||||
TRI_json_t const*,
|
||||
TRI_json_t const*,
|
||||
bool,
|
||||
bool);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -92,6 +92,7 @@ TRI_v8_global_s::TRI_v8_global_s (v8::Isolate* isolate)
|
|||
KeyOptionsKey(),
|
||||
LengthKey(),
|
||||
LifeTimeKey(),
|
||||
MergeArraysKey(),
|
||||
NameKey(),
|
||||
OperationIDKey(),
|
||||
ParametersKey(),
|
||||
|
@ -176,6 +177,7 @@ TRI_v8_global_s::TRI_v8_global_s (v8::Isolate* isolate)
|
|||
KeyOptionsKey = v8::Persistent<v8::String>::New(isolate, TRI_V8_SYMBOL("keyOptions"));
|
||||
LengthKey = v8::Persistent<v8::String>::New(isolate, TRI_V8_SYMBOL("length"));
|
||||
LifeTimeKey = v8::Persistent<v8::String>::New(isolate, TRI_V8_SYMBOL("lifeTime"));
|
||||
MergeArraysKey = v8::Persistent<v8::String>::New(isolate, TRI_V8_SYMBOL("mergeArrays"));
|
||||
NameKey = v8::Persistent<v8::String>::New(isolate, TRI_V8_SYMBOL("name"));
|
||||
OperationIDKey = v8::Persistent<v8::String>::New(isolate, TRI_V8_SYMBOL("operationID"));
|
||||
OverwriteKey = v8::Persistent<v8::String>::New(isolate, TRI_V8_SYMBOL("overwrite"));
|
||||
|
|
|
@ -555,6 +555,12 @@ typedef struct TRI_v8_global_s {
|
|||
|
||||
v8::Persistent<v8::String> LifeTimeKey;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief "mergeArrays" key name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
v8::Persistent<v8::String> MergeArraysKey;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief "name" key
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue