mirror of https://gitee.com/bigwinds/arangodb
document creation
This commit is contained in:
parent
5f25de1710
commit
f5e71197ce
|
@ -1,47 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Library to build up VPack documents.
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2015 ArangoDB 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 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Max Neunhoeffer
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2015, ArangoDB GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef VELOCYPACK_DUMP_H
|
||||
#define VELOCYPACK_DUMP_H 1
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "velocypack/velocypack-common.h"
|
||||
#include "velocypack/Buffer.h"
|
||||
#include "velocypack/Dumper.h"
|
||||
|
||||
namespace arangodb {
|
||||
namespace velocypack {
|
||||
|
||||
// some alias types for easier usage
|
||||
typedef Dumper<CharBuffer, false> BufferDumper;
|
||||
typedef Dumper<std::string, false> StringDumper;
|
||||
typedef Dumper<std::string, true> StringPrettyDumper;
|
||||
|
||||
} // namespace arangodb::velocypack
|
||||
} // namespace arangodb
|
||||
|
||||
#endif
|
|
@ -114,6 +114,8 @@ namespace arangodb {
|
|||
dumpString(str.c_str(), str.size());
|
||||
_sink->push_back('"');
|
||||
}
|
||||
|
||||
void appendUInt (uint64_t);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -39,32 +39,36 @@ namespace arangodb {
|
|||
int fpconv_dtoa (double fp, char dest[24]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Dumper::appendUInt (uint64_t v) {
|
||||
if (10000000000000000000ULL <= v) { _sink->push_back('0' + (v / 10000000000000000000ULL) % 10); }
|
||||
if ( 1000000000000000000ULL <= v) { _sink->push_back('0' + (v / 1000000000000000000ULL) % 10); }
|
||||
if ( 100000000000000000ULL <= v) { _sink->push_back('0' + (v / 100000000000000000ULL) % 10); }
|
||||
if ( 10000000000000000ULL <= v) { _sink->push_back('0' + (v / 10000000000000000ULL) % 10); }
|
||||
if ( 1000000000000000ULL <= v) { _sink->push_back('0' + (v / 1000000000000000ULL) % 10); }
|
||||
if ( 100000000000000ULL <= v) { _sink->push_back('0' + (v / 100000000000000ULL) % 10); }
|
||||
if ( 10000000000000ULL <= v) { _sink->push_back('0' + (v / 10000000000000ULL) % 10); }
|
||||
if ( 1000000000000ULL <= v) { _sink->push_back('0' + (v / 1000000000000ULL) % 10); }
|
||||
if ( 100000000000ULL <= v) { _sink->push_back('0' + (v / 100000000000ULL) % 10); }
|
||||
if ( 10000000000ULL <= v) { _sink->push_back('0' + (v / 10000000000ULL) % 10); }
|
||||
if ( 1000000000ULL <= v) { _sink->push_back('0' + (v / 1000000000ULL) % 10); }
|
||||
if ( 100000000ULL <= v) { _sink->push_back('0' + (v / 100000000ULL) % 10); }
|
||||
if ( 10000000ULL <= v) { _sink->push_back('0' + (v / 10000000ULL) % 10); }
|
||||
if ( 1000000ULL <= v) { _sink->push_back('0' + (v / 1000000ULL) % 10); }
|
||||
if ( 100000ULL <= v) { _sink->push_back('0' + (v / 100000ULL) % 10); }
|
||||
if ( 10000ULL <= v) { _sink->push_back('0' + (v / 10000ULL) % 10); }
|
||||
if ( 1000ULL <= v) { _sink->push_back('0' + (v / 1000ULL) % 10); }
|
||||
if ( 100ULL <= v) { _sink->push_back('0' + (v / 100ULL) % 10); }
|
||||
if ( 10ULL <= v) { _sink->push_back('0' + (v / 10ULL) % 10); }
|
||||
|
||||
_sink->push_back('0' + (v % 10));
|
||||
}
|
||||
|
||||
void Dumper::dumpInteger (Slice const* slice) {
|
||||
if (slice->isType(ValueType::UInt)) {
|
||||
uint64_t v = slice->getUInt();
|
||||
|
||||
if (10000000000000000000ULL <= v) { _sink->push_back('0' + (v / 10000000000000000000ULL) % 10); }
|
||||
if ( 1000000000000000000ULL <= v) { _sink->push_back('0' + (v / 1000000000000000000ULL) % 10); }
|
||||
if ( 100000000000000000ULL <= v) { _sink->push_back('0' + (v / 100000000000000000ULL) % 10); }
|
||||
if ( 10000000000000000ULL <= v) { _sink->push_back('0' + (v / 10000000000000000ULL) % 10); }
|
||||
if ( 1000000000000000ULL <= v) { _sink->push_back('0' + (v / 1000000000000000ULL) % 10); }
|
||||
if ( 100000000000000ULL <= v) { _sink->push_back('0' + (v / 100000000000000ULL) % 10); }
|
||||
if ( 10000000000000ULL <= v) { _sink->push_back('0' + (v / 10000000000000ULL) % 10); }
|
||||
if ( 1000000000000ULL <= v) { _sink->push_back('0' + (v / 1000000000000ULL) % 10); }
|
||||
if ( 100000000000ULL <= v) { _sink->push_back('0' + (v / 100000000000ULL) % 10); }
|
||||
if ( 10000000000ULL <= v) { _sink->push_back('0' + (v / 10000000000ULL) % 10); }
|
||||
if ( 1000000000ULL <= v) { _sink->push_back('0' + (v / 1000000000ULL) % 10); }
|
||||
if ( 100000000ULL <= v) { _sink->push_back('0' + (v / 100000000ULL) % 10); }
|
||||
if ( 10000000ULL <= v) { _sink->push_back('0' + (v / 10000000ULL) % 10); }
|
||||
if ( 1000000ULL <= v) { _sink->push_back('0' + (v / 1000000ULL) % 10); }
|
||||
if ( 100000ULL <= v) { _sink->push_back('0' + (v / 100000ULL) % 10); }
|
||||
if ( 10000ULL <= v) { _sink->push_back('0' + (v / 10000ULL) % 10); }
|
||||
if ( 1000ULL <= v) { _sink->push_back('0' + (v / 1000ULL) % 10); }
|
||||
if ( 100ULL <= v) { _sink->push_back('0' + (v / 100ULL) % 10); }
|
||||
if ( 10ULL <= v) { _sink->push_back('0' + (v / 10ULL) % 10); }
|
||||
|
||||
_sink->push_back('0' + (v % 10));
|
||||
appendUInt(v);
|
||||
}
|
||||
else if (slice->isType(ValueType::Int)) {
|
||||
int64_t v = slice->getInt();
|
||||
|
|
|
@ -28,15 +28,18 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Storage/Options.h"
|
||||
#include "Basics/Exceptions.h"
|
||||
#include "Utils/CollectionNameResolver.h"
|
||||
#include "VocBase/voc-types.h"
|
||||
|
||||
using namespace arangodb;
|
||||
|
||||
// global options used when converting JSON into a document
|
||||
VPackOptions JsonToDocumentOptions;
|
||||
VPackOptions StorageOptions::JsonToDocumentTemplate;
|
||||
// global options used when converting documents into JSON
|
||||
VPackOptions DocumentToJsonOptions;
|
||||
VPackOptions StorageOptions::DocumentToJsonTemplate;
|
||||
// global options used for other conversions
|
||||
VPackOptions NonDocumentOptions;
|
||||
VPackOptions StorageOptions::NonDocumentTemplate;
|
||||
|
||||
struct ExcludeHandlerImpl : public VPackAttributeExcludeHandler {
|
||||
bool shouldExclude (VPackSlice const& key, int nesting) override final {
|
||||
|
@ -62,16 +65,45 @@ struct ExcludeHandlerImpl : public VPackAttributeExcludeHandler {
|
|||
};
|
||||
|
||||
struct CustomTypeHandlerImpl : public VPackCustomTypeHandler {
|
||||
CustomTypeHandlerImpl (triagens::arango::CollectionNameResolver const* resolver,
|
||||
TRI_voc_cid_t cid)
|
||||
: resolver(resolver),
|
||||
cid(cid) {
|
||||
}
|
||||
|
||||
void toJson (VPackSlice const& value, VPackDumper* dumper, VPackSlice const& base) {
|
||||
if (value.head() == 0xf0) {
|
||||
// _id
|
||||
// TODO
|
||||
return;
|
||||
if (! base.isObject()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid value type");
|
||||
}
|
||||
char buffer[512]; // TODO: check if size is appropriate
|
||||
size_t len = resolver->getCollectionName(&buffer[0], cid);
|
||||
buffer[len] = '/';
|
||||
VPackSlice key = base.get("_key");
|
||||
|
||||
VPackValueLength keyLength;
|
||||
char const* p = key.getString(keyLength);
|
||||
if (p == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid _key value");
|
||||
}
|
||||
memcpy(&buffer[len + 1], p, keyLength);
|
||||
dumper->appendString(&buffer[0], len + 1 + keyLength);
|
||||
}
|
||||
|
||||
if (value.head() == 0xf1) {
|
||||
// _rev
|
||||
// TODO
|
||||
uint64_t rev = 0;
|
||||
uint8_t const* start = value.start() + 1;
|
||||
uint8_t const* end = start + value.byteSize();
|
||||
do {
|
||||
rev <<= 8;
|
||||
rev += static_cast<uint64_t>(*start++);
|
||||
}
|
||||
while (start < end);
|
||||
dumper->sink()->push_back('"');
|
||||
dumper->appendUInt(rev);
|
||||
dumper->sink()->push_back('"');
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -101,12 +133,13 @@ struct CustomTypeHandlerImpl : public VPackCustomTypeHandler {
|
|||
}
|
||||
throw "unknown type!";
|
||||
}
|
||||
|
||||
triagens::arango::CollectionNameResolver const* resolver;
|
||||
TRI_voc_cid_t cid;
|
||||
};
|
||||
|
||||
|
||||
StorageOptions::StorageOptions ()
|
||||
: _translator(new VPackAttributeTranslator),
|
||||
_customTypeHandler(new CustomTypeHandlerImpl),
|
||||
_excludeHandler(new ExcludeHandlerImpl) {
|
||||
|
||||
// these attribute names will be translated into short integer values
|
||||
|
@ -118,38 +151,49 @@ StorageOptions::StorageOptions ()
|
|||
_translator->seal();
|
||||
|
||||
// set options for JSON to document conversion
|
||||
JsonToDocumentOptions.buildUnindexedArrays = false;
|
||||
JsonToDocumentOptions.buildUnindexedObjects = false;
|
||||
JsonToDocumentOptions.checkAttributeUniqueness = true;
|
||||
JsonToDocumentOptions.sortAttributeNames = true;
|
||||
JsonToDocumentOptions.attributeTranslator = _translator.get();
|
||||
JsonToDocumentOptions.customTypeHandler = _customTypeHandler.get();
|
||||
JsonToDocumentOptions.attributeExcludeHandler = _excludeHandler.get();
|
||||
JsonToDocumentTemplate.buildUnindexedArrays = false;
|
||||
JsonToDocumentTemplate.buildUnindexedObjects = false;
|
||||
JsonToDocumentTemplate.checkAttributeUniqueness = true;
|
||||
JsonToDocumentTemplate.sortAttributeNames = true;
|
||||
JsonToDocumentTemplate.attributeTranslator = _translator.get();
|
||||
JsonToDocumentTemplate.customTypeHandler = nullptr;
|
||||
JsonToDocumentTemplate.attributeExcludeHandler = _excludeHandler.get();
|
||||
|
||||
// set options for document to JSON conversion
|
||||
DocumentToJsonOptions.prettyPrint = false;
|
||||
DocumentToJsonOptions.escapeForwardSlashes = true;
|
||||
DocumentToJsonOptions.unsupportedTypeBehavior = VPackOptions::FailOnUnsupportedType;
|
||||
DocumentToJsonOptions.attributeTranslator = _translator.get();
|
||||
DocumentToJsonOptions.customTypeHandler = _customTypeHandler.get();
|
||||
DocumentToJsonOptions.attributeExcludeHandler = nullptr;
|
||||
DocumentToJsonTemplate.attributeTranslator = _translator.get();
|
||||
DocumentToJsonTemplate.customTypeHandler = nullptr;
|
||||
DocumentToJsonTemplate.attributeExcludeHandler = nullptr;
|
||||
DocumentToJsonTemplate.prettyPrint = false;
|
||||
DocumentToJsonTemplate.escapeForwardSlashes = true;
|
||||
DocumentToJsonTemplate.unsupportedTypeBehavior = VPackOptions::FailOnUnsupportedType;
|
||||
|
||||
|
||||
NonDocumentOptions.prettyPrint = false;
|
||||
NonDocumentOptions.escapeForwardSlashes = true;
|
||||
NonDocumentOptions.sortAttributeNames = false;
|
||||
NonDocumentOptions.buildUnindexedArrays = true;
|
||||
NonDocumentOptions.buildUnindexedObjects = true;
|
||||
NonDocumentOptions.checkAttributeUniqueness = false;
|
||||
NonDocumentOptions.unsupportedTypeBehavior = VPackOptions::FailOnUnsupportedType;
|
||||
NonDocumentOptions.attributeTranslator = nullptr;
|
||||
NonDocumentOptions.customTypeHandler = nullptr;
|
||||
NonDocumentOptions.attributeExcludeHandler = nullptr;
|
||||
// bool keepTopLevelOpen = false;
|
||||
// non-document options
|
||||
NonDocumentTemplate.buildUnindexedArrays = true;
|
||||
NonDocumentTemplate.buildUnindexedObjects = true;
|
||||
NonDocumentTemplate.checkAttributeUniqueness = false;
|
||||
NonDocumentTemplate.sortAttributeNames = false;
|
||||
NonDocumentTemplate.attributeTranslator = nullptr;
|
||||
NonDocumentTemplate.customTypeHandler = nullptr;
|
||||
NonDocumentTemplate.attributeExcludeHandler = nullptr;
|
||||
NonDocumentTemplate.prettyPrint = false;
|
||||
NonDocumentTemplate.escapeForwardSlashes = true;
|
||||
NonDocumentTemplate.unsupportedTypeBehavior = VPackOptions::FailOnUnsupportedType;
|
||||
}
|
||||
|
||||
StorageOptions::~StorageOptions () {
|
||||
}
|
||||
|
||||
VPackOptions StorageOptions::getDocumentToJsonTemplate () {
|
||||
return DocumentToJsonTemplate;
|
||||
}
|
||||
|
||||
VPackOptions StorageOptions::getJsonToDocumentTemplate () {
|
||||
return JsonToDocumentTemplate;
|
||||
}
|
||||
|
||||
VPackOptions StorageOptions::getNonDocumentTemplate () {
|
||||
return NonDocumentTemplate;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
|
|
|
@ -42,15 +42,18 @@ namespace arangodb {
|
|||
StorageOptions (StorageOptions const&) = delete;
|
||||
StorageOptions& operator= (StorageOptions const&) = delete;
|
||||
|
||||
static VPackOptions getDocumentToJsonTemplate ();
|
||||
static VPackOptions getJsonToDocumentTemplate ();
|
||||
static VPackOptions getNonDocumentTemplate ();
|
||||
|
||||
private:
|
||||
|
||||
std::unique_ptr<VPackAttributeTranslator> _translator;
|
||||
std::unique_ptr<VPackCustomTypeHandler> _customTypeHandler;
|
||||
std::unique_ptr<VPackAttributeExcludeHandler> _excludeHandler;
|
||||
|
||||
static VPackOptions JsonToDocumentOptions;
|
||||
static VPackOptions DocumentToJsonOptions;
|
||||
static VPackOptions NonDocumentOptions;
|
||||
static VPackOptions JsonToDocumentTemplate;
|
||||
static VPackOptions DocumentToJsonTemplate;
|
||||
static VPackOptions NonDocumentTemplate;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "Basics/json-utilities.h"
|
||||
#include "Cluster/ClusterMethods.h"
|
||||
#include "Indexes/PrimaryIndex.h"
|
||||
#include "Storage/Options.h"
|
||||
#include "Utils/transactions.h"
|
||||
#include "Utils/V8ResolverGuard.h"
|
||||
#include "Utils/V8TransactionContext.h"
|
||||
|
@ -1005,11 +1006,23 @@ static void InsertVocbaseCol (TRI_vocbase_col_t* col,
|
|||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
|
||||
}
|
||||
|
||||
VPackBuilder builder = TRI_V8ToVPack(isolate, args[0]->ToObject());
|
||||
VPackOptions vOptions = arangodb::StorageOptions::getDocumentToJsonTemplate();
|
||||
VPackBuilder builder(&vOptions);
|
||||
int res2 = TRI_V8ToVPack(isolate, builder, args[0]->ToObject(), true);
|
||||
|
||||
if (res2 || builder.hasKey("_key")) {
|
||||
}
|
||||
else {
|
||||
}
|
||||
|
||||
builder.close();
|
||||
|
||||
VPackSlice slice(builder.slice());
|
||||
for (auto const& it : VPackObjectIterator(slice)) {
|
||||
std::cout << "KEY: " << it.key.copyString() << "\n";
|
||||
}
|
||||
|
||||
//std::cout << "GOT: " << VPackHexDump(slice) << "\n\n";
|
||||
// std::cout << "GOT: " << VPackHexDump(slice) << "\n\n";
|
||||
|
||||
|
||||
// set document key
|
||||
|
|
|
@ -128,19 +128,31 @@ v8::Handle<v8::Value> TRI_VPackToV8 (v8::Isolate* isolate,
|
|||
}
|
||||
}
|
||||
|
||||
struct BuilderContext {
|
||||
BuilderContext (v8::Isolate* isolate, VPackBuilder& builder, bool keepTopLevelOpen)
|
||||
: isolate(isolate), builder(builder), keepTopLevelOpen(keepTopLevelOpen) {
|
||||
}
|
||||
|
||||
v8::Isolate* isolate;
|
||||
VPackBuilder& builder;
|
||||
std::set<int> seenHashes;
|
||||
std::vector<v8::Handle<v8::Object>> seenObjects;
|
||||
bool keepTopLevelOpen;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief adds a VPackValue to either an array or an object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void AddValue (VPackBuilder& builder,
|
||||
static void AddValue (BuilderContext& context,
|
||||
std::string const& attributeName,
|
||||
bool inObject,
|
||||
VPackValue const& value) {
|
||||
if (inObject) {
|
||||
builder.add(attributeName, value);
|
||||
context.builder.add(attributeName, value);
|
||||
}
|
||||
else {
|
||||
builder.add(value);
|
||||
context.builder.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,29 +160,27 @@ static void AddValue (VPackBuilder& builder,
|
|||
/// @brief convert a V8 value to a VPack value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int V8ToVPack (v8::Isolate* isolate,
|
||||
VPackBuilder& builder,
|
||||
static int V8ToVPack (BuilderContext& context,
|
||||
v8::Handle<v8::Value> const parameter,
|
||||
std::set<int>& seenHashes,
|
||||
std::vector<v8::Handle<v8::Object>>& seenObjects,
|
||||
std::string const& attributeName,
|
||||
bool inObject) {
|
||||
v8::Isolate* isolate = context.isolate;
|
||||
v8::HandleScope scope(isolate);
|
||||
|
||||
if (parameter->IsNull()) {
|
||||
AddValue(builder, attributeName, inObject, VPackValue(VPackValueType::Null));
|
||||
AddValue(context, attributeName, inObject, VPackValue(VPackValueType::Null));
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
if (parameter->IsBoolean()) {
|
||||
v8::Handle<v8::Boolean> booleanParameter = parameter->ToBoolean();
|
||||
AddValue(builder, attributeName, inObject, VPackValue(booleanParameter->Value()));
|
||||
AddValue(context, attributeName, inObject, VPackValue(booleanParameter->Value()));
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
if (parameter->IsNumber()) {
|
||||
v8::Handle<v8::Number> numberParameter = parameter->ToNumber();
|
||||
AddValue(builder, attributeName, inObject, VPackValue(numberParameter->Value()));
|
||||
AddValue(context, attributeName, inObject, VPackValue(numberParameter->Value()));
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -182,37 +192,37 @@ static int V8ToVPack (v8::Isolate* isolate,
|
|||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
AddValue(builder, attributeName, inObject, VPackValue(*str));
|
||||
AddValue(context, attributeName, inObject, VPackValue(*str));
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
if (parameter->IsArray()) {
|
||||
v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(parameter);
|
||||
|
||||
AddValue(builder, attributeName, inObject, VPackValue(VPackValueType::Array));
|
||||
AddValue(context, attributeName, inObject, VPackValue(VPackValueType::Array));
|
||||
uint32_t const n = array->Length();
|
||||
|
||||
for (uint32_t i = 0; i < n; ++i) {
|
||||
// get address of next element
|
||||
int res = V8ToVPack(isolate, builder, array->Get(i), seenHashes, seenObjects, "", false);
|
||||
int res = V8ToVPack(context, array->Get(i), "", false);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
builder.close();
|
||||
context.builder.close();
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
if (parameter->IsObject()) {
|
||||
if (parameter->IsBooleanObject()) {
|
||||
AddValue(builder, attributeName, inObject, VPackValue(v8::Handle<v8::BooleanObject>::Cast(parameter)->BooleanValue()));
|
||||
AddValue(context, attributeName, inObject, VPackValue(v8::Handle<v8::BooleanObject>::Cast(parameter)->BooleanValue()));
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
if (parameter->IsNumberObject()) {
|
||||
AddValue(builder, attributeName, inObject, VPackValue(v8::Handle<v8::NumberObject>::Cast(parameter)->NumberValue()));
|
||||
AddValue(context, attributeName, inObject, VPackValue(v8::Handle<v8::NumberObject>::Cast(parameter)->NumberValue()));
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -224,7 +234,7 @@ static int V8ToVPack (v8::Isolate* isolate,
|
|||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
AddValue(builder, attributeName, inObject, VPackValue(*str));
|
||||
AddValue(context, attributeName, inObject, VPackValue(*str));
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -256,7 +266,7 @@ static int V8ToVPack (v8::Isolate* isolate,
|
|||
}
|
||||
|
||||
// this passes ownership for the utf8 string to the JSON object
|
||||
AddValue(builder, attributeName, inObject, VPackValue(*str));
|
||||
AddValue(context, attributeName, inObject, VPackValue(*str));
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -266,10 +276,10 @@ static int V8ToVPack (v8::Isolate* isolate,
|
|||
|
||||
int hash = o->GetIdentityHash();
|
||||
|
||||
if (seenHashes.find(hash) != seenHashes.end()) {
|
||||
if (context.seenHashes.find(hash) != context.seenHashes.end()) {
|
||||
// LOG_TRACE("found hash %d", hash);
|
||||
|
||||
for (auto& it : seenObjects) {
|
||||
for (auto& it : context.seenObjects) {
|
||||
if (parameter->StrictEquals(it)) {
|
||||
// object is recursive
|
||||
return TRI_ERROR_BAD_PARAMETER;
|
||||
|
@ -277,15 +287,15 @@ static int V8ToVPack (v8::Isolate* isolate,
|
|||
}
|
||||
}
|
||||
else {
|
||||
seenHashes.emplace(hash);
|
||||
context.seenHashes.emplace(hash);
|
||||
}
|
||||
|
||||
seenObjects.emplace_back(o);
|
||||
context.seenObjects.emplace_back(o);
|
||||
|
||||
v8::Handle<v8::Array> names = o->GetOwnPropertyNames();
|
||||
uint32_t const n = names->Length();
|
||||
|
||||
AddValue(builder, attributeName, inObject, VPackValue(VPackValueType::Object));
|
||||
AddValue(context, attributeName, inObject, VPackValue(VPackValueType::Object));
|
||||
|
||||
for (uint32_t i = 0; i < n; ++i) {
|
||||
// process attribute name
|
||||
|
@ -296,7 +306,7 @@ static int V8ToVPack (v8::Isolate* isolate,
|
|||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
int res = V8ToVPack(isolate, builder, o->Get(key), seenHashes, seenObjects, *str, true);
|
||||
int res = V8ToVPack(context, o->Get(key), *str, true);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
// to mimic behavior of previous ArangoDB versions, we need to silently ignore this error
|
||||
|
@ -305,8 +315,10 @@ static int V8ToVPack (v8::Isolate* isolate,
|
|||
}
|
||||
}
|
||||
|
||||
seenObjects.pop_back();
|
||||
builder.close();
|
||||
context.seenObjects.pop_back();
|
||||
if (! context.keepTopLevelOpen || ! context.seenObjects.empty()) {
|
||||
context.builder.close();
|
||||
}
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -317,20 +329,15 @@ static int V8ToVPack (v8::Isolate* isolate,
|
|||
/// @brief convert a V8 value to VPack value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
VPackBuilder TRI_V8ToVPack (v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> const parameter) {
|
||||
int TRI_V8ToVPack (v8::Isolate* isolate,
|
||||
VPackBuilder& builder,
|
||||
v8::Handle<v8::Value> const value,
|
||||
bool keepTopLevelOpen) {
|
||||
|
||||
VPackBuilder builder;
|
||||
BuilderContext context(isolate, builder, keepTopLevelOpen);
|
||||
int res = V8ToVPack(context, value, "", false);
|
||||
|
||||
std::set<int> seenHashes;
|
||||
std::vector<v8::Handle<v8::Object>> seenObjects;
|
||||
int res = V8ToVPack(isolate, builder, parameter, seenHashes, seenObjects, "", false);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
}
|
||||
|
||||
return builder;
|
||||
return res;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -54,8 +54,10 @@ v8::Handle<v8::Value> TRI_VPackToV8 (v8::Isolate* isolate,
|
|||
/// @brief convert a V8 value to VPack value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
VPackBuilder TRI_V8ToVPack (v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> const);
|
||||
int TRI_V8ToVPack (v8::Isolate* isolate,
|
||||
VPackBuilder& builder,
|
||||
v8::Handle<v8::Value> const value,
|
||||
bool keepTopLevelOpen);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue