mirror of https://gitee.com/bigwinds/arangodb
handle custom types
This commit is contained in:
parent
3076549984
commit
ea7a7b4242
|
@ -36,6 +36,7 @@ namespace arangodb {
|
|||
namespace velocypack {
|
||||
class AttributeTranslator;
|
||||
class Dumper;
|
||||
class Options;
|
||||
class Slice;
|
||||
|
||||
struct AttributeExcludeHandler {
|
||||
|
@ -47,8 +48,12 @@ struct AttributeExcludeHandler {
|
|||
struct CustomTypeHandler {
|
||||
virtual ~CustomTypeHandler() {}
|
||||
|
||||
virtual void toJson(Slice const& value, Dumper* dumper,
|
||||
Slice const& base) = 0;
|
||||
virtual void dump(Slice const& value, Dumper* dumper,
|
||||
Slice const& base) = 0;
|
||||
|
||||
virtual std::string toString(Slice const& value, Options const* options,
|
||||
Slice const& base) = 0;
|
||||
|
||||
};
|
||||
|
||||
struct Options {
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <vector>
|
||||
#include <iosfwd>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
#include "velocypack/velocypack-common.h"
|
||||
|
|
|
@ -433,7 +433,7 @@ void Dumper::dumpValue(Slice const* slice, Slice const* base) {
|
|||
if (options->customTypeHandler == nullptr) {
|
||||
handleUnsupportedType(slice);
|
||||
} else {
|
||||
options->customTypeHandler->toJson(*slice, this, *base);
|
||||
options->customTypeHandler->dump(*slice, this, *base);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "Options.h"
|
||||
#include "Basics/Exceptions.h"
|
||||
#include "Storage/Marker.h"
|
||||
#include "Utils/CollectionNameResolver.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
|
||||
|
@ -66,14 +67,14 @@ struct SystemAttributeExcludeHandler : public VPackAttributeExcludeHandler {
|
|||
|
||||
|
||||
// custom type value handler, used for deciphering the _id attribute
|
||||
struct CustomIdTypeHandler : public VPackCustomTypeHandler {
|
||||
explicit CustomIdTypeHandler(TRI_vocbase_t* vocbase)
|
||||
struct CustomTypeHandler : public VPackCustomTypeHandler {
|
||||
explicit CustomTypeHandler(TRI_vocbase_t* vocbase)
|
||||
: vocbase(vocbase), resolver(nullptr), ownsResolver(false) {}
|
||||
|
||||
CustomIdTypeHandler(TRI_vocbase_t* vocbase, CollectionNameResolver* resolver)
|
||||
CustomTypeHandler(TRI_vocbase_t* vocbase, CollectionNameResolver* resolver)
|
||||
: vocbase(vocbase), resolver(resolver), ownsResolver(false) {}
|
||||
|
||||
~CustomIdTypeHandler() {
|
||||
~CustomTypeHandler() {
|
||||
if (ownsResolver) {
|
||||
delete resolver;
|
||||
}
|
||||
|
@ -87,9 +88,9 @@ struct CustomIdTypeHandler : public VPackCustomTypeHandler {
|
|||
return resolver;
|
||||
}
|
||||
|
||||
void toJson(VPackSlice const& value, VPackDumper* dumper,
|
||||
VPackSlice const& base) override final {
|
||||
if (value.head() != 0xf0) {
|
||||
void dump(VPackSlice const& value, VPackDumper* dumper,
|
||||
VPackSlice const& base) override final {
|
||||
if (value.head() != 0xf3) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||
"invalid custom type");
|
||||
}
|
||||
|
@ -99,7 +100,8 @@ struct CustomIdTypeHandler : public VPackCustomTypeHandler {
|
|||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||
"invalid value type");
|
||||
}
|
||||
uint64_t cid = arangodb::velocypack::readUInt64(value.start() + 1);
|
||||
|
||||
uint64_t cid = MarkerHelper::readNumber<uint64_t>(value.begin() + 1, sizeof(uint64_t));
|
||||
char buffer[512]; // This is enough for collection name + _key
|
||||
size_t len = getResolver()->getCollectionName(&buffer[0], cid);
|
||||
buffer[len] = '/';
|
||||
|
@ -114,6 +116,34 @@ struct CustomIdTypeHandler : public VPackCustomTypeHandler {
|
|||
memcpy(&buffer[len + 1], p, keyLength);
|
||||
dumper->appendString(&buffer[0], len + 1 + keyLength);
|
||||
}
|
||||
|
||||
std::string toString(VPackSlice const& value, VPackOptions const* options,
|
||||
VPackSlice const& base) override final {
|
||||
if (value.head() != 0xf0) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||
"invalid custom type");
|
||||
}
|
||||
|
||||
// _id
|
||||
if (!base.isObject()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||
"invalid value type");
|
||||
}
|
||||
|
||||
uint64_t cid = MarkerHelper::readNumber<uint64_t>(value.begin() + 1, sizeof(uint64_t));
|
||||
std::string result(getResolver()->getCollectionName(cid));
|
||||
result.push_back('/');
|
||||
VPackSlice key = base.get(TRI_VOC_ATTRIBUTE_KEY);
|
||||
|
||||
VPackValueLength keyLength;
|
||||
char const* p = key.getString(keyLength);
|
||||
if (p == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||
"invalid _key value");
|
||||
}
|
||||
result.append(p, keyLength);
|
||||
return result;
|
||||
}
|
||||
|
||||
TRI_vocbase_t* vocbase;
|
||||
CollectionNameResolver* resolver;
|
||||
|
@ -156,6 +186,10 @@ void StorageOptions::initialize() {
|
|||
insertOptions->attributeExcludeHandler = excludeHandler.get();
|
||||
}
|
||||
|
||||
VPackCustomTypeHandler* StorageOptions::getCustomTypeHandler(TRI_vocbase_t* vocbase) {
|
||||
return new CustomTypeHandler(vocbase);
|
||||
}
|
||||
|
||||
VPackAttributeTranslator const* StorageOptions::getTranslator() {
|
||||
return translator.get();
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include <velocypack/Options.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
struct TRI_vocbase_t;
|
||||
|
||||
namespace arangodb {
|
||||
|
||||
namespace StorageOptions {
|
||||
|
@ -38,6 +40,8 @@ namespace StorageOptions {
|
|||
VPackAttributeTranslator const* getTranslator();
|
||||
VPackOptions const* getDefaultOptions();
|
||||
VPackOptions const* getInsertOptions();
|
||||
|
||||
VPackCustomTypeHandler* getCustomTypeHandler(TRI_vocbase_t*);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,15 +27,23 @@
|
|||
#include "Basics/Common.h"
|
||||
|
||||
#include <velocypack/Buffer.h>
|
||||
#include <velocypack/Options.h>
|
||||
#include <velocypack/Slice.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
namespace arangodb {
|
||||
|
||||
struct OperationResult {
|
||||
OperationResult() : buffer(), code(TRI_ERROR_NO_ERROR), wasSynchronous(false) {}
|
||||
explicit OperationResult(int code) : buffer(), code(code), wasSynchronous(false) {}
|
||||
OperationResult(int code, std::shared_ptr<VPackBuffer<uint8_t>> buffer) : buffer(buffer), code(code), wasSynchronous(false) {}
|
||||
OperationResult() : buffer(), customTypeHandler(nullptr), code(TRI_ERROR_NO_ERROR), wasSynchronous(false) {}
|
||||
OperationResult(std::shared_ptr<VPackBuffer<uint8_t>> buffer, VPackCustomTypeHandler* handler) : buffer(buffer), customTypeHandler(handler), code(TRI_ERROR_NO_ERROR), wasSynchronous(false) {}
|
||||
OperationResult(int code, std::shared_ptr<VPackBuffer<uint8_t>> buffer) : buffer(buffer), customTypeHandler(nullptr), code(code), wasSynchronous(false) {}
|
||||
OperationResult(std::shared_ptr<VPackBuffer<uint8_t>> buffer, bool wasSynchronous) : buffer(buffer), customTypeHandler(nullptr), code(TRI_ERROR_NO_ERROR), wasSynchronous(wasSynchronous) {}
|
||||
explicit OperationResult(std::shared_ptr<VPackBuffer<uint8_t>> buffer) : OperationResult(TRI_ERROR_NO_ERROR, buffer) {}
|
||||
explicit OperationResult(int code) : OperationResult(code, nullptr) { }
|
||||
|
||||
~OperationResult() {
|
||||
// TODO: handle destruction of customTypeHandler
|
||||
}
|
||||
|
||||
bool successful() const {
|
||||
return code == TRI_ERROR_NO_ERROR;
|
||||
|
@ -51,6 +59,7 @@ struct OperationResult {
|
|||
}
|
||||
|
||||
std::shared_ptr<VPackBuffer<uint8_t>> buffer;
|
||||
VPackCustomTypeHandler* customTypeHandler;
|
||||
int code;
|
||||
bool wasSynchronous;
|
||||
};
|
||||
|
|
|
@ -514,7 +514,7 @@ OperationResult Transaction::documentLocal(std::string const& collectionName,
|
|||
resultBuilder.add(VPackValue(mptr.vpack()));
|
||||
}
|
||||
|
||||
return OperationResult(TRI_ERROR_NO_ERROR, resultBuilder.steal());
|
||||
return OperationResult(resultBuilder.steal(), StorageOptions::getCustomTypeHandler(_vocbase));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -638,7 +638,7 @@ OperationResult Transaction::insertLocal(std::string const& collectionName,
|
|||
resultBuilder.add(TRI_VOC_ATTRIBUTE_KEY, VPackValue(resultKey));
|
||||
resultBuilder.close();
|
||||
|
||||
return OperationResult(TRI_ERROR_NO_ERROR, resultBuilder.steal());
|
||||
return OperationResult(resultBuilder.steal(), options.waitForSync);
|
||||
}
|
||||
|
||||
OperationResult Transaction::replace(std::string const& collectionName,
|
||||
|
@ -784,7 +784,7 @@ OperationResult Transaction::updateLocal(std::string const& collectionName,
|
|||
resultBuilder.add(TRI_VOC_ATTRIBUTE_KEY, VPackValue(resultKey));
|
||||
resultBuilder.close();
|
||||
|
||||
return OperationResult(TRI_ERROR_NO_ERROR, resultBuilder.steal());
|
||||
return OperationResult(resultBuilder.steal(), options.waitForSync);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -896,6 +896,6 @@ OperationResult Transaction::removeLocal(std::string const& collectionName,
|
|||
resultBuilder.add(TRI_VOC_ATTRIBUTE_KEY, VPackValue(key));
|
||||
resultBuilder.close();
|
||||
|
||||
return OperationResult(TRI_ERROR_NO_ERROR, resultBuilder.steal());
|
||||
return OperationResult(resultBuilder.steal(), options.waitForSync);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue