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
|
|
|
@ -115,6 +115,8 @@ namespace arangodb {
|
||||||
_sink->push_back('"');
|
_sink->push_back('"');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void appendUInt (uint64_t);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void dumpInteger (Slice const*);
|
void dumpInteger (Slice const*);
|
||||||
|
|
|
@ -40,10 +40,7 @@ namespace arangodb {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void Dumper::dumpInteger (Slice const* slice) {
|
void Dumper::appendUInt (uint64_t v) {
|
||||||
if (slice->isType(ValueType::UInt)) {
|
|
||||||
uint64_t v = slice->getUInt();
|
|
||||||
|
|
||||||
if (10000000000000000000ULL <= v) { _sink->push_back('0' + (v / 10000000000000000000ULL) % 10); }
|
if (10000000000000000000ULL <= v) { _sink->push_back('0' + (v / 10000000000000000000ULL) % 10); }
|
||||||
if ( 1000000000000000000ULL <= v) { _sink->push_back('0' + (v / 1000000000000000000ULL) % 10); }
|
if ( 1000000000000000000ULL <= v) { _sink->push_back('0' + (v / 1000000000000000000ULL) % 10); }
|
||||||
if ( 100000000000000000ULL <= v) { _sink->push_back('0' + (v / 100000000000000000ULL) % 10); }
|
if ( 100000000000000000ULL <= v) { _sink->push_back('0' + (v / 100000000000000000ULL) % 10); }
|
||||||
|
@ -65,6 +62,13 @@ void Dumper::dumpInteger (Slice const* slice) {
|
||||||
if ( 10ULL <= v) { _sink->push_back('0' + (v / 10ULL) % 10); }
|
if ( 10ULL <= v) { _sink->push_back('0' + (v / 10ULL) % 10); }
|
||||||
|
|
||||||
_sink->push_back('0' + (v % 10));
|
_sink->push_back('0' + (v % 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dumper::dumpInteger (Slice const* slice) {
|
||||||
|
if (slice->isType(ValueType::UInt)) {
|
||||||
|
uint64_t v = slice->getUInt();
|
||||||
|
|
||||||
|
appendUInt(v);
|
||||||
}
|
}
|
||||||
else if (slice->isType(ValueType::Int)) {
|
else if (slice->isType(ValueType::Int)) {
|
||||||
int64_t v = slice->getInt();
|
int64_t v = slice->getInt();
|
||||||
|
|
|
@ -28,15 +28,18 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "Storage/Options.h"
|
#include "Storage/Options.h"
|
||||||
|
#include "Basics/Exceptions.h"
|
||||||
|
#include "Utils/CollectionNameResolver.h"
|
||||||
|
#include "VocBase/voc-types.h"
|
||||||
|
|
||||||
using namespace arangodb;
|
using namespace arangodb;
|
||||||
|
|
||||||
// global options used when converting JSON into a document
|
// global options used when converting JSON into a document
|
||||||
VPackOptions JsonToDocumentOptions;
|
VPackOptions StorageOptions::JsonToDocumentTemplate;
|
||||||
// global options used when converting documents into JSON
|
// global options used when converting documents into JSON
|
||||||
VPackOptions DocumentToJsonOptions;
|
VPackOptions StorageOptions::DocumentToJsonTemplate;
|
||||||
// global options used for other conversions
|
// global options used for other conversions
|
||||||
VPackOptions NonDocumentOptions;
|
VPackOptions StorageOptions::NonDocumentTemplate;
|
||||||
|
|
||||||
struct ExcludeHandlerImpl : public VPackAttributeExcludeHandler {
|
struct ExcludeHandlerImpl : public VPackAttributeExcludeHandler {
|
||||||
bool shouldExclude (VPackSlice const& key, int nesting) override final {
|
bool shouldExclude (VPackSlice const& key, int nesting) override final {
|
||||||
|
@ -62,16 +65,45 @@ struct ExcludeHandlerImpl : public VPackAttributeExcludeHandler {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CustomTypeHandlerImpl : public VPackCustomTypeHandler {
|
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) {
|
void toJson (VPackSlice const& value, VPackDumper* dumper, VPackSlice const& base) {
|
||||||
if (value.head() == 0xf0) {
|
if (value.head() == 0xf0) {
|
||||||
// _id
|
// _id
|
||||||
// TODO
|
if (! base.isObject()) {
|
||||||
return;
|
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) {
|
if (value.head() == 0xf1) {
|
||||||
// _rev
|
// _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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,12 +133,13 @@ struct CustomTypeHandlerImpl : public VPackCustomTypeHandler {
|
||||||
}
|
}
|
||||||
throw "unknown type!";
|
throw "unknown type!";
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
triagens::arango::CollectionNameResolver const* resolver;
|
||||||
|
TRI_voc_cid_t cid;
|
||||||
|
};
|
||||||
|
|
||||||
StorageOptions::StorageOptions ()
|
StorageOptions::StorageOptions ()
|
||||||
: _translator(new VPackAttributeTranslator),
|
: _translator(new VPackAttributeTranslator),
|
||||||
_customTypeHandler(new CustomTypeHandlerImpl),
|
|
||||||
_excludeHandler(new ExcludeHandlerImpl) {
|
_excludeHandler(new ExcludeHandlerImpl) {
|
||||||
|
|
||||||
// these attribute names will be translated into short integer values
|
// these attribute names will be translated into short integer values
|
||||||
|
@ -118,39 +151,50 @@ StorageOptions::StorageOptions ()
|
||||||
_translator->seal();
|
_translator->seal();
|
||||||
|
|
||||||
// set options for JSON to document conversion
|
// set options for JSON to document conversion
|
||||||
JsonToDocumentOptions.buildUnindexedArrays = false;
|
JsonToDocumentTemplate.buildUnindexedArrays = false;
|
||||||
JsonToDocumentOptions.buildUnindexedObjects = false;
|
JsonToDocumentTemplate.buildUnindexedObjects = false;
|
||||||
JsonToDocumentOptions.checkAttributeUniqueness = true;
|
JsonToDocumentTemplate.checkAttributeUniqueness = true;
|
||||||
JsonToDocumentOptions.sortAttributeNames = true;
|
JsonToDocumentTemplate.sortAttributeNames = true;
|
||||||
JsonToDocumentOptions.attributeTranslator = _translator.get();
|
JsonToDocumentTemplate.attributeTranslator = _translator.get();
|
||||||
JsonToDocumentOptions.customTypeHandler = _customTypeHandler.get();
|
JsonToDocumentTemplate.customTypeHandler = nullptr;
|
||||||
JsonToDocumentOptions.attributeExcludeHandler = _excludeHandler.get();
|
JsonToDocumentTemplate.attributeExcludeHandler = _excludeHandler.get();
|
||||||
|
|
||||||
// set options for document to JSON conversion
|
// set options for document to JSON conversion
|
||||||
DocumentToJsonOptions.prettyPrint = false;
|
DocumentToJsonTemplate.attributeTranslator = _translator.get();
|
||||||
DocumentToJsonOptions.escapeForwardSlashes = true;
|
DocumentToJsonTemplate.customTypeHandler = nullptr;
|
||||||
DocumentToJsonOptions.unsupportedTypeBehavior = VPackOptions::FailOnUnsupportedType;
|
DocumentToJsonTemplate.attributeExcludeHandler = nullptr;
|
||||||
DocumentToJsonOptions.attributeTranslator = _translator.get();
|
DocumentToJsonTemplate.prettyPrint = false;
|
||||||
DocumentToJsonOptions.customTypeHandler = _customTypeHandler.get();
|
DocumentToJsonTemplate.escapeForwardSlashes = true;
|
||||||
DocumentToJsonOptions.attributeExcludeHandler = nullptr;
|
DocumentToJsonTemplate.unsupportedTypeBehavior = VPackOptions::FailOnUnsupportedType;
|
||||||
|
|
||||||
|
// non-document options
|
||||||
NonDocumentOptions.prettyPrint = false;
|
NonDocumentTemplate.buildUnindexedArrays = true;
|
||||||
NonDocumentOptions.escapeForwardSlashes = true;
|
NonDocumentTemplate.buildUnindexedObjects = true;
|
||||||
NonDocumentOptions.sortAttributeNames = false;
|
NonDocumentTemplate.checkAttributeUniqueness = false;
|
||||||
NonDocumentOptions.buildUnindexedArrays = true;
|
NonDocumentTemplate.sortAttributeNames = false;
|
||||||
NonDocumentOptions.buildUnindexedObjects = true;
|
NonDocumentTemplate.attributeTranslator = nullptr;
|
||||||
NonDocumentOptions.checkAttributeUniqueness = false;
|
NonDocumentTemplate.customTypeHandler = nullptr;
|
||||||
NonDocumentOptions.unsupportedTypeBehavior = VPackOptions::FailOnUnsupportedType;
|
NonDocumentTemplate.attributeExcludeHandler = nullptr;
|
||||||
NonDocumentOptions.attributeTranslator = nullptr;
|
NonDocumentTemplate.prettyPrint = false;
|
||||||
NonDocumentOptions.customTypeHandler = nullptr;
|
NonDocumentTemplate.escapeForwardSlashes = true;
|
||||||
NonDocumentOptions.attributeExcludeHandler = nullptr;
|
NonDocumentTemplate.unsupportedTypeBehavior = VPackOptions::FailOnUnsupportedType;
|
||||||
// bool keepTopLevelOpen = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StorageOptions::~StorageOptions () {
|
StorageOptions::~StorageOptions () {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VPackOptions StorageOptions::getDocumentToJsonTemplate () {
|
||||||
|
return DocumentToJsonTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
VPackOptions StorageOptions::getJsonToDocumentTemplate () {
|
||||||
|
return JsonToDocumentTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
VPackOptions StorageOptions::getNonDocumentTemplate () {
|
||||||
|
return NonDocumentTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- END-OF-FILE
|
// --SECTION-- END-OF-FILE
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -42,15 +42,18 @@ namespace arangodb {
|
||||||
StorageOptions (StorageOptions const&) = delete;
|
StorageOptions (StorageOptions const&) = delete;
|
||||||
StorageOptions& operator= (StorageOptions const&) = delete;
|
StorageOptions& operator= (StorageOptions const&) = delete;
|
||||||
|
|
||||||
|
static VPackOptions getDocumentToJsonTemplate ();
|
||||||
|
static VPackOptions getJsonToDocumentTemplate ();
|
||||||
|
static VPackOptions getNonDocumentTemplate ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::unique_ptr<VPackAttributeTranslator> _translator;
|
std::unique_ptr<VPackAttributeTranslator> _translator;
|
||||||
std::unique_ptr<VPackCustomTypeHandler> _customTypeHandler;
|
|
||||||
std::unique_ptr<VPackAttributeExcludeHandler> _excludeHandler;
|
std::unique_ptr<VPackAttributeExcludeHandler> _excludeHandler;
|
||||||
|
|
||||||
static VPackOptions JsonToDocumentOptions;
|
static VPackOptions JsonToDocumentTemplate;
|
||||||
static VPackOptions DocumentToJsonOptions;
|
static VPackOptions DocumentToJsonTemplate;
|
||||||
static VPackOptions NonDocumentOptions;
|
static VPackOptions NonDocumentTemplate;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "Basics/json-utilities.h"
|
#include "Basics/json-utilities.h"
|
||||||
#include "Cluster/ClusterMethods.h"
|
#include "Cluster/ClusterMethods.h"
|
||||||
#include "Indexes/PrimaryIndex.h"
|
#include "Indexes/PrimaryIndex.h"
|
||||||
|
#include "Storage/Options.h"
|
||||||
#include "Utils/transactions.h"
|
#include "Utils/transactions.h"
|
||||||
#include "Utils/V8ResolverGuard.h"
|
#include "Utils/V8ResolverGuard.h"
|
||||||
#include "Utils/V8TransactionContext.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);
|
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());
|
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
|
// 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
|
/// @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,
|
std::string const& attributeName,
|
||||||
bool inObject,
|
bool inObject,
|
||||||
VPackValue const& value) {
|
VPackValue const& value) {
|
||||||
if (inObject) {
|
if (inObject) {
|
||||||
builder.add(attributeName, value);
|
context.builder.add(attributeName, value);
|
||||||
}
|
}
|
||||||
else {
|
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
|
/// @brief convert a V8 value to a VPack value
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static int V8ToVPack (v8::Isolate* isolate,
|
static int V8ToVPack (BuilderContext& context,
|
||||||
VPackBuilder& builder,
|
|
||||||
v8::Handle<v8::Value> const parameter,
|
v8::Handle<v8::Value> const parameter,
|
||||||
std::set<int>& seenHashes,
|
|
||||||
std::vector<v8::Handle<v8::Object>>& seenObjects,
|
|
||||||
std::string const& attributeName,
|
std::string const& attributeName,
|
||||||
bool inObject) {
|
bool inObject) {
|
||||||
|
v8::Isolate* isolate = context.isolate;
|
||||||
v8::HandleScope scope(isolate);
|
v8::HandleScope scope(isolate);
|
||||||
|
|
||||||
if (parameter->IsNull()) {
|
if (parameter->IsNull()) {
|
||||||
AddValue(builder, attributeName, inObject, VPackValue(VPackValueType::Null));
|
AddValue(context, attributeName, inObject, VPackValue(VPackValueType::Null));
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameter->IsBoolean()) {
|
if (parameter->IsBoolean()) {
|
||||||
v8::Handle<v8::Boolean> booleanParameter = parameter->ToBoolean();
|
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;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameter->IsNumber()) {
|
if (parameter->IsNumber()) {
|
||||||
v8::Handle<v8::Number> numberParameter = parameter->ToNumber();
|
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;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,37 +192,37 @@ static int V8ToVPack (v8::Isolate* isolate,
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
return TRI_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddValue(builder, attributeName, inObject, VPackValue(*str));
|
AddValue(context, attributeName, inObject, VPackValue(*str));
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameter->IsArray()) {
|
if (parameter->IsArray()) {
|
||||||
v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(parameter);
|
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();
|
uint32_t const n = array->Length();
|
||||||
|
|
||||||
for (uint32_t i = 0; i < n; ++i) {
|
for (uint32_t i = 0; i < n; ++i) {
|
||||||
// get address of next element
|
// 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) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.close();
|
context.builder.close();
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameter->IsObject()) {
|
if (parameter->IsObject()) {
|
||||||
if (parameter->IsBooleanObject()) {
|
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;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameter->IsNumberObject()) {
|
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;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +234,7 @@ static int V8ToVPack (v8::Isolate* isolate,
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
return TRI_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddValue(builder, attributeName, inObject, VPackValue(*str));
|
AddValue(context, attributeName, inObject, VPackValue(*str));
|
||||||
return TRI_ERROR_NO_ERROR;
|
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
|
// 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;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,10 +276,10 @@ static int V8ToVPack (v8::Isolate* isolate,
|
||||||
|
|
||||||
int hash = o->GetIdentityHash();
|
int hash = o->GetIdentityHash();
|
||||||
|
|
||||||
if (seenHashes.find(hash) != seenHashes.end()) {
|
if (context.seenHashes.find(hash) != context.seenHashes.end()) {
|
||||||
// LOG_TRACE("found hash %d", hash);
|
// LOG_TRACE("found hash %d", hash);
|
||||||
|
|
||||||
for (auto& it : seenObjects) {
|
for (auto& it : context.seenObjects) {
|
||||||
if (parameter->StrictEquals(it)) {
|
if (parameter->StrictEquals(it)) {
|
||||||
// object is recursive
|
// object is recursive
|
||||||
return TRI_ERROR_BAD_PARAMETER;
|
return TRI_ERROR_BAD_PARAMETER;
|
||||||
|
@ -277,15 +287,15 @@ static int V8ToVPack (v8::Isolate* isolate,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
seenHashes.emplace(hash);
|
context.seenHashes.emplace(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
seenObjects.emplace_back(o);
|
context.seenObjects.emplace_back(o);
|
||||||
|
|
||||||
v8::Handle<v8::Array> names = o->GetOwnPropertyNames();
|
v8::Handle<v8::Array> names = o->GetOwnPropertyNames();
|
||||||
uint32_t const n = names->Length();
|
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) {
|
for (uint32_t i = 0; i < n; ++i) {
|
||||||
// process attribute name
|
// process attribute name
|
||||||
|
@ -296,7 +306,7 @@ static int V8ToVPack (v8::Isolate* isolate,
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
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) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
// to mimic behavior of previous ArangoDB versions, we need to silently ignore this 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();
|
context.seenObjects.pop_back();
|
||||||
builder.close();
|
if (! context.keepTopLevelOpen || ! context.seenObjects.empty()) {
|
||||||
|
context.builder.close();
|
||||||
|
}
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,20 +329,15 @@ static int V8ToVPack (v8::Isolate* isolate,
|
||||||
/// @brief convert a V8 value to VPack value
|
/// @brief convert a V8 value to VPack value
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
VPackBuilder TRI_V8ToVPack (v8::Isolate* isolate,
|
int TRI_V8ToVPack (v8::Isolate* isolate,
|
||||||
v8::Handle<v8::Value> const parameter) {
|
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;
|
return res;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -54,8 +54,10 @@ v8::Handle<v8::Value> TRI_VPackToV8 (v8::Isolate* isolate,
|
||||||
/// @brief convert a V8 value to VPack value
|
/// @brief convert a V8 value to VPack value
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
VPackBuilder TRI_V8ToVPack (v8::Isolate* isolate,
|
int TRI_V8ToVPack (v8::Isolate* isolate,
|
||||||
v8::Handle<v8::Value> const);
|
VPackBuilder& builder,
|
||||||
|
v8::Handle<v8::Value> const value,
|
||||||
|
bool keepTopLevelOpen);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue