mirror of https://gitee.com/bigwinds/arangodb
clean up key generators a bit (#5573)
This commit is contained in:
parent
ef85bdb867
commit
448a435713
|
@ -41,6 +41,8 @@
|
||||||
#include "Cluster/ServerState.h"
|
#include "Cluster/ServerState.h"
|
||||||
#include "Scheduler/JobGuard.h"
|
#include "Scheduler/JobGuard.h"
|
||||||
#include "Scheduler/SchedulerFeature.h"
|
#include "Scheduler/SchedulerFeature.h"
|
||||||
|
#include "VocBase/KeyGenerator.h"
|
||||||
|
#include "VocBase/LogicalCollection.h"
|
||||||
#include "VocBase/ticks.h"
|
#include "VocBase/ticks.h"
|
||||||
#include "VocBase/vocbase.h"
|
#include "VocBase/vocbase.h"
|
||||||
|
|
||||||
|
@ -830,9 +832,8 @@ size_t DistributeBlock::sendToClient(AqlItemBlock* cur) {
|
||||||
/// @brief create a new document key, argument is unused here
|
/// @brief create a new document key, argument is unused here
|
||||||
#ifndef USE_ENTERPRISE
|
#ifndef USE_ENTERPRISE
|
||||||
std::string DistributeBlock::createKey(VPackSlice) const {
|
std::string DistributeBlock::createKey(VPackSlice) const {
|
||||||
ClusterInfo* ci = ClusterInfo::instance();
|
auto collInfo = _collection->getCollection();
|
||||||
uint64_t uid = ci->uniqid();
|
return collInfo->keyGenerator()->generate();
|
||||||
return std::to_string(uid);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "Indexes/Index.h"
|
#include "Indexes/Index.h"
|
||||||
#include "Utils/CollectionNameResolver.h"
|
#include "Utils/CollectionNameResolver.h"
|
||||||
#include "Utils/OperationOptions.h"
|
#include "Utils/OperationOptions.h"
|
||||||
|
#include "VocBase/KeyGenerator.h"
|
||||||
#include "VocBase/LogicalCollection.h"
|
#include "VocBase/LogicalCollection.h"
|
||||||
#include "VocBase/ticks.h"
|
#include "VocBase/ticks.h"
|
||||||
|
|
||||||
|
@ -381,8 +382,7 @@ static int distributeBabyOnShards(
|
||||||
VPackSlice keySlice = node.get(StaticStrings::KeyString);
|
VPackSlice keySlice = node.get(StaticStrings::KeyString);
|
||||||
if (keySlice.isNone()) {
|
if (keySlice.isNone()) {
|
||||||
// The user did not specify a key, let's create one:
|
// The user did not specify a key, let's create one:
|
||||||
uint64_t uid = ci->uniqid();
|
_key = collinfo->keyGenerator()->generate();
|
||||||
_key = arangodb::basics::StringUtils::itoa(uid);
|
|
||||||
} else {
|
} else {
|
||||||
userSpecifiedKey = true;
|
userSpecifiedKey = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,13 +22,11 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "KeyGenerator.h"
|
#include "KeyGenerator.h"
|
||||||
#include "Basics/conversions.h"
|
|
||||||
#include "Basics/MutexLocker.h"
|
#include "Basics/MutexLocker.h"
|
||||||
#include "Basics/NumberUtils.h"
|
#include "Basics/NumberUtils.h"
|
||||||
#include "Basics/StringUtils.h"
|
#include "Basics/StringUtils.h"
|
||||||
#include "Basics/tri-strings.h"
|
|
||||||
#include "Basics/VelocyPackHelper.h"
|
#include "Basics/VelocyPackHelper.h"
|
||||||
#include "Basics/voc-errors.h"
|
#include "Cluster/ClusterInfo.h"
|
||||||
#include "VocBase/ticks.h"
|
#include "VocBase/ticks.h"
|
||||||
#include "VocBase/vocbase.h"
|
#include "VocBase/vocbase.h"
|
||||||
|
|
||||||
|
@ -113,9 +111,6 @@ static std::array<bool, 256> const keyCharLookupTable = { {
|
||||||
KeyGenerator::KeyGenerator(bool allowUserKeys)
|
KeyGenerator::KeyGenerator(bool allowUserKeys)
|
||||||
: _allowUserKeys(allowUserKeys) {}
|
: _allowUserKeys(allowUserKeys) {}
|
||||||
|
|
||||||
/// @brief destroy the key generator
|
|
||||||
KeyGenerator::~KeyGenerator() {}
|
|
||||||
|
|
||||||
/// @brief get the generator type from VelocyPack
|
/// @brief get the generator type from VelocyPack
|
||||||
KeyGenerator::GeneratorType KeyGenerator::generatorType(
|
KeyGenerator::GeneratorType KeyGenerator::generatorType(
|
||||||
VPackSlice const& parameters) {
|
VPackSlice const& parameters) {
|
||||||
|
@ -143,6 +138,20 @@ KeyGenerator::GeneratorType KeyGenerator::generatorType(
|
||||||
return KeyGenerator::TYPE_UNKNOWN;
|
return KeyGenerator::TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool KeyGenerator::canUseType(VPackSlice const& parameters) {
|
||||||
|
auto type = generatorType(parameters);
|
||||||
|
if (type == KeyGenerator::TYPE_UNKNOWN) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ServerState::instance()->isCoordinator()) {
|
||||||
|
// cluster only supports key generator type "traditional"
|
||||||
|
return type == KeyGenerator::TYPE_TRADITIONAL;
|
||||||
|
}
|
||||||
|
// single-server supports all types
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief create a key generator based on the options specified
|
/// @brief create a key generator based on the options specified
|
||||||
KeyGenerator* KeyGenerator::factory(VPackSlice const& options) {
|
KeyGenerator* KeyGenerator::factory(VPackSlice const& options) {
|
||||||
KeyGenerator::GeneratorType type;
|
KeyGenerator::GeneratorType type;
|
||||||
|
@ -168,10 +177,11 @@ KeyGenerator* KeyGenerator::factory(VPackSlice const& options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TYPE_TRADITIONAL) {
|
if (type == TYPE_TRADITIONAL) {
|
||||||
return new TraditionalKeyGenerator(allowUserKeys);
|
if (ServerState::instance()->isCoordinator()) {
|
||||||
}
|
return new TraditionalKeyGeneratorCluster(allowUserKeys);
|
||||||
|
}
|
||||||
else if (type == TYPE_AUTOINCREMENT) {
|
return new TraditionalKeyGeneratorSingle(allowUserKeys);
|
||||||
|
} else if (type == TYPE_AUTOINCREMENT) {
|
||||||
uint64_t offset = 0;
|
uint64_t offset = 0;
|
||||||
uint64_t increment = 1;
|
uint64_t increment = 1;
|
||||||
|
|
||||||
|
@ -224,38 +234,21 @@ int KeyGenerator::globalCheck(char const* p, size_t length, bool isRestore) {
|
||||||
return TRI_ERROR_ARANGO_DOCUMENT_KEY_UNEXPECTED;
|
return TRI_ERROR_ARANGO_DOCUMENT_KEY_UNEXPECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length == 0) {
|
if (length == 0 || length > maxKeyLength) {
|
||||||
// user key is empty
|
// user key is empty or user key is too long
|
||||||
return TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length > TRI_VOC_KEY_MAX_LENGTH) {
|
|
||||||
// user key is too long
|
|
||||||
return TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD;
|
return TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief return a VelocyPack representation of the generator
|
|
||||||
/// Not virtual because this is identical for all of them
|
|
||||||
std::shared_ptr<VPackBuilder> KeyGenerator::toVelocyPack() const {
|
|
||||||
auto builder = std::make_shared<VPackBuilder>();
|
|
||||||
toVelocyPack(*builder);
|
|
||||||
builder->close();
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief create the key generator
|
/// @brief create the key generator
|
||||||
TraditionalKeyGenerator::TraditionalKeyGenerator(bool allowUserKeys)
|
TraditionalKeyGenerator::TraditionalKeyGenerator(bool allowUserKeys)
|
||||||
: KeyGenerator(allowUserKeys), _lastValue(0) {}
|
: KeyGenerator(allowUserKeys) {}
|
||||||
|
|
||||||
/// @brief destroy the key generator
|
|
||||||
TraditionalKeyGenerator::~TraditionalKeyGenerator() {}
|
|
||||||
|
|
||||||
/// @brief validate a key
|
/// @brief validate a key
|
||||||
bool TraditionalKeyGenerator::validateKey(char const* key, size_t len) {
|
bool TraditionalKeyGenerator::validateKey(char const* key, size_t len) {
|
||||||
if (len == 0 || len > TRI_VOC_KEY_MAX_LENGTH) {
|
if (len == 0 || len > maxKeyLength) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,8 +263,40 @@ bool TraditionalKeyGenerator::validateKey(char const* key, size_t len) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief validate a key
|
||||||
|
int TraditionalKeyGenerator::validate(char const* p, size_t length, bool isRestore) {
|
||||||
|
int res = globalCheck(p, length, isRestore);
|
||||||
|
|
||||||
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate user-supplied key
|
||||||
|
if (!validateKey(p, length)) {
|
||||||
|
return TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRI_ERROR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief track usage of a key - default implementation is to throw!
|
||||||
|
void TraditionalKeyGenerator::track(char const*, size_t) {
|
||||||
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "this key generator cannot track keys");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief create a VPack representation of the generator
|
||||||
|
void TraditionalKeyGenerator::toVelocyPack(VPackBuilder& builder) const {
|
||||||
|
TRI_ASSERT(!builder.isClosed());
|
||||||
|
builder.add("type", VPackValue(name()));
|
||||||
|
builder.add("allowUserKeys", VPackValue(_allowUserKeys));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief create the key generator
|
||||||
|
TraditionalKeyGeneratorSingle::TraditionalKeyGeneratorSingle(bool allowUserKeys)
|
||||||
|
: TraditionalKeyGenerator(allowUserKeys), _lastValue(0) {}
|
||||||
|
|
||||||
/// @brief generate a key
|
/// @brief generate a key
|
||||||
std::string TraditionalKeyGenerator::generate() {
|
std::string TraditionalKeyGeneratorSingle::generate() {
|
||||||
TRI_voc_tick_t tick = TRI_NewTickServer();
|
TRI_voc_tick_t tick = TRI_NewTickServer();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -286,24 +311,19 @@ std::string TraditionalKeyGenerator::generate() {
|
||||||
|
|
||||||
if (tick == UINT64_MAX) {
|
if (tick == UINT64_MAX) {
|
||||||
// sanity check
|
// sanity check
|
||||||
return "";
|
return std::string();
|
||||||
}
|
}
|
||||||
return arangodb::basics::StringUtils::itoa(tick);
|
return arangodb::basics::StringUtils::itoa(tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief validate a key
|
/// @brief validate a key
|
||||||
int TraditionalKeyGenerator::validate(char const* p, size_t length, bool isRestore) {
|
int TraditionalKeyGeneratorSingle::validate(char const* p, size_t length, bool isRestore) {
|
||||||
int res = globalCheck(p, length, isRestore);
|
int res = TraditionalKeyGenerator::validate(p, length, isRestore);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate user-supplied key
|
|
||||||
if (!validateKey(p, length)) {
|
|
||||||
return TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length > 0 && p[0] >= '0' && p[0] <= '9') {
|
if (length > 0 && p[0] >= '0' && p[0] <= '9') {
|
||||||
// potentially numeric key
|
// potentially numeric key
|
||||||
uint64_t value = NumberUtils::atoi_zero<uint64_t>(p, p + length);
|
uint64_t value = NumberUtils::atoi_zero<uint64_t>(p, p + length);
|
||||||
|
@ -322,7 +342,7 @@ int TraditionalKeyGenerator::validate(char const* p, size_t length, bool isResto
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief track usage of a key
|
/// @brief track usage of a key
|
||||||
void TraditionalKeyGenerator::track(char const* p, size_t length) {
|
void TraditionalKeyGeneratorSingle::track(char const* p, size_t length) {
|
||||||
// check the numeric key part
|
// check the numeric key part
|
||||||
if (length > 0 && p[0] >= '0' && p[0] <= '9') {
|
if (length > 0 && p[0] >= '0' && p[0] <= '9') {
|
||||||
// potentially numeric key
|
// potentially numeric key
|
||||||
|
@ -340,13 +360,23 @@ void TraditionalKeyGenerator::track(char const* p, size_t length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief create a VPack representation of the generator
|
/// @brief create a VPack representation of the generator
|
||||||
void TraditionalKeyGenerator::toVelocyPack(VPackBuilder& builder) const {
|
void TraditionalKeyGeneratorSingle::toVelocyPack(VPackBuilder& builder) const {
|
||||||
TRI_ASSERT(!builder.isClosed());
|
TRI_ASSERT(!builder.isClosed());
|
||||||
builder.add("type", VPackValue(name()));
|
TraditionalKeyGenerator::toVelocyPack(builder);
|
||||||
builder.add("allowUserKeys", VPackValue(_allowUserKeys));
|
|
||||||
builder.add("lastValue", VPackValue(_lastValue));
|
builder.add("lastValue", VPackValue(_lastValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief create the key generator
|
||||||
|
TraditionalKeyGeneratorCluster::TraditionalKeyGeneratorCluster(bool allowUserKeys)
|
||||||
|
: TraditionalKeyGenerator(allowUserKeys) {}
|
||||||
|
|
||||||
|
/// @brief generate a key
|
||||||
|
std::string TraditionalKeyGeneratorCluster::generate() {
|
||||||
|
ClusterInfo* ci = ClusterInfo::instance();
|
||||||
|
uint64_t uid = ci->uniqid();
|
||||||
|
return std::to_string(uid);
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief create the generator
|
/// @brief create the generator
|
||||||
AutoIncrementKeyGenerator::AutoIncrementKeyGenerator(bool allowUserKeys,
|
AutoIncrementKeyGenerator::AutoIncrementKeyGenerator(bool allowUserKeys,
|
||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
|
@ -356,12 +386,9 @@ AutoIncrementKeyGenerator::AutoIncrementKeyGenerator(bool allowUserKeys,
|
||||||
_offset(offset),
|
_offset(offset),
|
||||||
_increment(increment) {}
|
_increment(increment) {}
|
||||||
|
|
||||||
/// @brief destroy the generator
|
|
||||||
AutoIncrementKeyGenerator::~AutoIncrementKeyGenerator() {}
|
|
||||||
|
|
||||||
/// @brief validate a numeric key
|
/// @brief validate a numeric key
|
||||||
bool AutoIncrementKeyGenerator::validateKey(char const* key, size_t len) {
|
bool AutoIncrementKeyGenerator::validateKey(char const* key, size_t len) {
|
||||||
if (len == 0 || len > TRI_VOC_KEY_MAX_LENGTH) {
|
if (len == 0 || len > maxKeyLength) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,5 +535,5 @@ bool TRI_ValidateDocumentIdKeyGenerator(char const* key, size_t len,
|
||||||
++pos;
|
++pos;
|
||||||
|
|
||||||
// validate document key
|
// validate document key
|
||||||
return TraditionalKeyGenerator::validateKey(p, len - pos);
|
return TraditionalKeyGeneratorSingle::validateKey(p, len - pos);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,13 +26,11 @@
|
||||||
|
|
||||||
#include "Basics/Common.h"
|
#include "Basics/Common.h"
|
||||||
#include "Basics/Mutex.h"
|
#include "Basics/Mutex.h"
|
||||||
|
#include "Cluster/ServerState.h"
|
||||||
#include "VocBase/vocbase.h"
|
#include "VocBase/vocbase.h"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
/// @brief maximum length of a key in a collection
|
|
||||||
#define TRI_VOC_KEY_MAX_LENGTH (254)
|
|
||||||
|
|
||||||
namespace arangodb {
|
namespace arangodb {
|
||||||
namespace velocypack {
|
namespace velocypack {
|
||||||
class Builder;
|
class Builder;
|
||||||
|
@ -48,18 +46,25 @@ class KeyGenerator {
|
||||||
TYPE_AUTOINCREMENT = 2
|
TYPE_AUTOINCREMENT = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @brief maximum length of a key in a collection
|
||||||
|
static constexpr size_t maxKeyLength = 254;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// @brief create the generator
|
/// @brief create the generator
|
||||||
explicit KeyGenerator(bool);
|
explicit KeyGenerator(bool allowUserKeys);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// @brief destroy the generator
|
/// @brief destroy the generator
|
||||||
virtual ~KeyGenerator();
|
virtual ~KeyGenerator() = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// @brief get the generator type from VelocyPack
|
/// @brief get the generator type from VelocyPack
|
||||||
static GeneratorType generatorType(arangodb::velocypack::Slice const&);
|
static GeneratorType generatorType(arangodb::velocypack::Slice const&);
|
||||||
|
|
||||||
|
/// @brief check if the specified key generator in the VelocyPack
|
||||||
|
/// can be used in this setup (cluster / single-server)
|
||||||
|
static bool canUseType(arangodb::velocypack::Slice const&);
|
||||||
|
|
||||||
/// @brief create a key generator based on the options specified
|
/// @brief create a key generator based on the options specified
|
||||||
static KeyGenerator* factory(arangodb::velocypack::Slice const&);
|
static KeyGenerator* factory(arangodb::velocypack::Slice const&);
|
||||||
|
|
||||||
|
@ -75,9 +80,6 @@ class KeyGenerator {
|
||||||
/// @brief track usage of a key
|
/// @brief track usage of a key
|
||||||
virtual void track(char const* p, size_t length) = 0;
|
virtual void track(char const* p, size_t length) = 0;
|
||||||
|
|
||||||
/// @brief return a VelocyPack representation of the generator
|
|
||||||
std::shared_ptr<arangodb::velocypack::Builder> toVelocyPack() const;
|
|
||||||
|
|
||||||
/// @brief build a VelocyPack representation of the generator in the builder
|
/// @brief build a VelocyPack representation of the generator in the builder
|
||||||
virtual void toVelocyPack(arangodb::velocypack::Builder&) const = 0;
|
virtual void toVelocyPack(arangodb::velocypack::Builder&) const = 0;
|
||||||
|
|
||||||
|
@ -89,18 +91,32 @@ class KeyGenerator {
|
||||||
bool _allowUserKeys;
|
bool _allowUserKeys;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TraditionalKeyGenerator final : public KeyGenerator {
|
class TraditionalKeyGenerator : public KeyGenerator {
|
||||||
public:
|
public:
|
||||||
/// @brief create the generator
|
/// @brief create the generator
|
||||||
explicit TraditionalKeyGenerator(bool);
|
explicit TraditionalKeyGenerator(bool allowUserKeys);
|
||||||
|
|
||||||
/// @brief destroy the generator
|
|
||||||
~TraditionalKeyGenerator();
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// @brief validate a key
|
/// @brief validate a key
|
||||||
static bool validateKey(char const* key, size_t len);
|
static bool validateKey(char const* key, size_t len);
|
||||||
|
|
||||||
|
/// @brief validate a key
|
||||||
|
int validate(char const* p, size_t length, bool isRestore) override;
|
||||||
|
|
||||||
|
/// @brief return the generator name (must be lowercase)
|
||||||
|
static char const* name() { return "traditional"; }
|
||||||
|
|
||||||
|
/// @brief track usage of a key - default implementation is to throw!
|
||||||
|
void track(char const* p, size_t length) override;
|
||||||
|
|
||||||
|
/// @brief build a VelocyPack representation of the generator in the builder
|
||||||
|
virtual void toVelocyPack(arangodb::velocypack::Builder&) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TraditionalKeyGeneratorSingle final : public TraditionalKeyGenerator {
|
||||||
|
public:
|
||||||
|
/// @brief create the generator
|
||||||
|
explicit TraditionalKeyGeneratorSingle(bool allowUserKeys);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bool trackKeys() const override { return true; }
|
bool trackKeys() const override { return true; }
|
||||||
|
@ -112,10 +128,7 @@ class TraditionalKeyGenerator final : public KeyGenerator {
|
||||||
int validate(char const* p, size_t length, bool isRestore) override;
|
int validate(char const* p, size_t length, bool isRestore) override;
|
||||||
|
|
||||||
/// @brief track usage of a key
|
/// @brief track usage of a key
|
||||||
void track(char const* p, size_t length) override final;
|
void track(char const* p, size_t length) override;
|
||||||
|
|
||||||
/// @brief return the generator name (must be lowercase)
|
|
||||||
static std::string name() { return "traditional"; }
|
|
||||||
|
|
||||||
/// @brief build a VelocyPack representation of the generator in the builder
|
/// @brief build a VelocyPack representation of the generator in the builder
|
||||||
virtual void toVelocyPack(arangodb::velocypack::Builder&) const override;
|
virtual void toVelocyPack(arangodb::velocypack::Builder&) const override;
|
||||||
|
@ -126,14 +139,24 @@ class TraditionalKeyGenerator final : public KeyGenerator {
|
||||||
uint64_t _lastValue;
|
uint64_t _lastValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TraditionalKeyGeneratorCluster final : public TraditionalKeyGenerator {
|
||||||
|
public:
|
||||||
|
/// @brief create the generator
|
||||||
|
explicit TraditionalKeyGeneratorCluster(bool allowUserKeys);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool trackKeys() const override { return false; }
|
||||||
|
|
||||||
|
/// @brief generate a key
|
||||||
|
std::string generate() override;
|
||||||
|
};
|
||||||
|
|
||||||
class AutoIncrementKeyGenerator final : public KeyGenerator {
|
class AutoIncrementKeyGenerator final : public KeyGenerator {
|
||||||
public:
|
public:
|
||||||
/// @brief create the generator
|
/// @brief create the generator
|
||||||
AutoIncrementKeyGenerator(bool, uint64_t, uint64_t);
|
AutoIncrementKeyGenerator(bool, uint64_t, uint64_t);
|
||||||
|
|
||||||
/// @brief destroy the generator
|
|
||||||
~AutoIncrementKeyGenerator();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// @brief validate a key
|
/// @brief validate a key
|
||||||
static bool validateKey(char const* key, size_t len);
|
static bool validateKey(char const* key, size_t len);
|
||||||
|
@ -149,10 +172,10 @@ class AutoIncrementKeyGenerator final : public KeyGenerator {
|
||||||
int validate(char const* p, size_t length, bool isRestore) override;
|
int validate(char const* p, size_t length, bool isRestore) override;
|
||||||
|
|
||||||
/// @brief track usage of a key
|
/// @brief track usage of a key
|
||||||
void track(char const* p, size_t length) override final;
|
void track(char const* p, size_t length) override;
|
||||||
|
|
||||||
/// @brief return the generator name (must be lowercase)
|
/// @brief return the generator name (must be lowercase)
|
||||||
static std::string name() { return "autoincrement"; }
|
static char const* name() { return "autoincrement"; }
|
||||||
|
|
||||||
/// @brief build a VelocyPack representation of the generator in the builder
|
/// @brief build a VelocyPack representation of the generator in the builder
|
||||||
virtual void toVelocyPack(arangodb::velocypack::Builder&) const override;
|
virtual void toVelocyPack(arangodb::velocypack::Builder&) const override;
|
||||||
|
|
|
@ -251,17 +251,9 @@ LogicalCollection::LogicalCollection(
|
||||||
}
|
}
|
||||||
|
|
||||||
VPackSlice keyGenSlice = info.get("keyOptions");
|
VPackSlice keyGenSlice = info.get("keyOptions");
|
||||||
if (keyGenSlice.isObject()) {
|
if (!KeyGenerator::canUseType(keyGenSlice)) {
|
||||||
keyGenSlice = keyGenSlice.get("type");
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_CLUSTER_UNSUPPORTED,
|
||||||
if (keyGenSlice.isString()) {
|
"the specified key generator is not supported for sharded collections");
|
||||||
StringRef tmp(keyGenSlice);
|
|
||||||
if (!tmp.empty() && tmp != "traditional") {
|
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_CLUSTER_UNSUPPORTED,
|
|
||||||
"non-traditional key generators are "
|
|
||||||
"not supported for sharded "
|
|
||||||
"collections");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue