mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-24 10:40:49 +00:00
Add function IAccessStorage::canInsert(): now access storage can decide if it can take a new entity.
This commit is contained in:
parent
b7f0129505
commit
2846567bf1
@ -15,7 +15,7 @@ namespace ErrorCodes
|
||||
extern const int BAD_CAST;
|
||||
extern const int ACCESS_ENTITY_NOT_FOUND;
|
||||
extern const int ACCESS_ENTITY_ALREADY_EXISTS;
|
||||
extern const int ACCESS_ENTITY_STORAGE_READONLY;
|
||||
extern const int ACCESS_STORAGE_READONLY;
|
||||
extern const int UNKNOWN_USER;
|
||||
extern const int UNKNOWN_ROLE;
|
||||
}
|
||||
@ -419,7 +419,7 @@ void IAccessStorage::throwReadonlyCannotInsert(std::type_index type, const Strin
|
||||
{
|
||||
throw Exception(
|
||||
"Cannot insert " + getTypeName(type) + " " + backQuote(name) + " to " + getStorageName() + " because this storage is readonly",
|
||||
ErrorCodes::ACCESS_ENTITY_STORAGE_READONLY);
|
||||
ErrorCodes::ACCESS_STORAGE_READONLY);
|
||||
}
|
||||
|
||||
|
||||
@ -427,7 +427,7 @@ void IAccessStorage::throwReadonlyCannotUpdate(std::type_index type, const Strin
|
||||
{
|
||||
throw Exception(
|
||||
"Cannot update " + getTypeName(type) + " " + backQuote(name) + " in " + getStorageName() + " because this storage is readonly",
|
||||
ErrorCodes::ACCESS_ENTITY_STORAGE_READONLY);
|
||||
ErrorCodes::ACCESS_STORAGE_READONLY);
|
||||
}
|
||||
|
||||
|
||||
@ -435,6 +435,6 @@ void IAccessStorage::throwReadonlyCannotRemove(std::type_index type, const Strin
|
||||
{
|
||||
throw Exception(
|
||||
"Cannot remove " + getTypeName(type) + " " + backQuote(name) + " from " + getStorageName() + " because this storage is readonly",
|
||||
ErrorCodes::ACCESS_ENTITY_STORAGE_READONLY);
|
||||
ErrorCodes::ACCESS_STORAGE_READONLY);
|
||||
}
|
||||
}
|
||||
|
@ -74,6 +74,10 @@ public:
|
||||
String readName(const UUID & id) const;
|
||||
std::optional<String> tryReadName(const UUID & id) const;
|
||||
|
||||
/// Returns true if a specified entity can be inserted into this storage.
|
||||
/// This function doesn't check whether there are no entities with such name in the storage.
|
||||
bool canInsert(const AccessEntityPtr & entity) const { return canInsertImpl(entity); }
|
||||
|
||||
/// Inserts an entity to the storage. Returns ID of a new entry in the storage.
|
||||
/// Throws an exception if the specified name already exists.
|
||||
UUID insert(const AccessEntityPtr & entity);
|
||||
@ -133,6 +137,7 @@ protected:
|
||||
virtual bool existsImpl(const UUID & id) const = 0;
|
||||
virtual AccessEntityPtr readImpl(const UUID & id) const = 0;
|
||||
virtual String readNameImpl(const UUID & id) const = 0;
|
||||
virtual bool canInsertImpl(const AccessEntityPtr & entity) const = 0;
|
||||
virtual UUID insertImpl(const AccessEntityPtr & entity, bool replace_if_exists) = 0;
|
||||
virtual void removeImpl(const UUID & id) = 0;
|
||||
virtual void updateImpl(const UUID & id, const UpdateFunc & update_func) = 0;
|
||||
|
@ -26,6 +26,7 @@ private:
|
||||
bool existsImpl(const UUID & id) const override;
|
||||
AccessEntityPtr readImpl(const UUID & id) const override;
|
||||
String readNameImpl(const UUID & id) const override;
|
||||
bool canInsertImpl(const AccessEntityPtr &) const override { return true; }
|
||||
UUID insertImpl(const AccessEntityPtr & entity, bool replace_if_exists) override;
|
||||
void removeImpl(const UUID & id) override;
|
||||
void updateImpl(const UUID & id, const UpdateFunc & update_func) override;
|
||||
|
@ -8,6 +8,7 @@ namespace DB
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int ACCESS_ENTITY_FOUND_DUPLICATES;
|
||||
extern const int ACCESS_STORAGE_FOR_INSERTION_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
@ -29,10 +30,9 @@ namespace
|
||||
|
||||
|
||||
MultipleAccessStorage::MultipleAccessStorage(
|
||||
std::vector<std::unique_ptr<Storage>> nested_storages_, size_t index_of_nested_storage_for_insertion_)
|
||||
std::vector<std::unique_ptr<Storage>> nested_storages_)
|
||||
: IAccessStorage(joinStorageNames(nested_storages_))
|
||||
, nested_storages(std::move(nested_storages_))
|
||||
, nested_storage_for_insertion(nested_storages[index_of_nested_storage_for_insertion_].get())
|
||||
, ids_cache(512 /* cache size */)
|
||||
{
|
||||
}
|
||||
@ -161,13 +161,39 @@ String MultipleAccessStorage::readNameImpl(const UUID & id) const
|
||||
}
|
||||
|
||||
|
||||
bool MultipleAccessStorage::canInsertImpl(const AccessEntityPtr & entity) const
|
||||
{
|
||||
for (const auto & nested_storage : nested_storages)
|
||||
{
|
||||
if (nested_storage->canInsert(entity))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
UUID MultipleAccessStorage::insertImpl(const AccessEntityPtr & entity, bool replace_if_exists)
|
||||
{
|
||||
auto id = replace_if_exists ? nested_storage_for_insertion->insertOrReplace(entity) : nested_storage_for_insertion->insert(entity);
|
||||
IAccessStorage * nested_storage_for_insertion = nullptr;
|
||||
for (const auto & nested_storage : nested_storages)
|
||||
{
|
||||
if (nested_storage->canInsert(entity))
|
||||
{
|
||||
nested_storage_for_insertion = nested_storage.get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nested_storage_for_insertion)
|
||||
{
|
||||
throw Exception(
|
||||
"Not found a storage to insert " + entity->getTypeName() + backQuote(entity->getName()),
|
||||
ErrorCodes::ACCESS_STORAGE_FOR_INSERTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
auto id = replace_if_exists ? nested_storage_for_insertion->insertOrReplace(entity) : nested_storage_for_insertion->insert(entity);
|
||||
std::lock_guard lock{ids_cache_mutex};
|
||||
ids_cache.set(id, std::make_shared<Storage *>(nested_storage_for_insertion));
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ class MultipleAccessStorage : public IAccessStorage
|
||||
public:
|
||||
using Storage = IAccessStorage;
|
||||
|
||||
MultipleAccessStorage(std::vector<std::unique_ptr<Storage>> nested_storages_, size_t index_of_nested_storage_for_insertion_ = 0);
|
||||
MultipleAccessStorage(std::vector<std::unique_ptr<Storage>> nested_storages_);
|
||||
~MultipleAccessStorage() override;
|
||||
|
||||
std::vector<UUID> findMultiple(std::type_index type, const String & name) const;
|
||||
@ -35,6 +35,7 @@ protected:
|
||||
bool existsImpl(const UUID & id) const override;
|
||||
AccessEntityPtr readImpl(const UUID & id) const override;
|
||||
String readNameImpl(const UUID &id) const override;
|
||||
bool canInsertImpl(const AccessEntityPtr & entity) const override;
|
||||
UUID insertImpl(const AccessEntityPtr & entity, bool replace_if_exists) override;
|
||||
void removeImpl(const UUID & id) override;
|
||||
void updateImpl(const UUID & id, const UpdateFunc & update_func) override;
|
||||
@ -45,7 +46,6 @@ protected:
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<Storage>> nested_storages;
|
||||
IAccessStorage * nested_storage_for_insertion;
|
||||
mutable LRUCache<UUID, Storage *> ids_cache;
|
||||
mutable std::mutex ids_cache_mutex;
|
||||
};
|
||||
|
@ -29,6 +29,7 @@ private:
|
||||
bool existsImpl(const UUID & id) const override;
|
||||
AccessEntityPtr readImpl(const UUID & id) const override;
|
||||
String readNameImpl(const UUID & id) const override;
|
||||
bool canInsertImpl(const AccessEntityPtr &) const override { return false; }
|
||||
UUID insertImpl(const AccessEntityPtr & entity, bool replace_if_exists) override;
|
||||
void removeImpl(const UUID & id) override;
|
||||
void updateImpl(const UUID & id, const UpdateFunc & update_func) override;
|
||||
|
@ -467,7 +467,7 @@ namespace ErrorCodes
|
||||
extern const int ACCESS_ENTITY_NOT_FOUND = 492;
|
||||
extern const int ACCESS_ENTITY_ALREADY_EXISTS = 493;
|
||||
extern const int ACCESS_ENTITY_FOUND_DUPLICATES = 494;
|
||||
extern const int ACCESS_ENTITY_STORAGE_READONLY = 495;
|
||||
extern const int ACCESS_STORAGE_READONLY = 495;
|
||||
extern const int QUOTA_REQUIRES_CLIENT_KEY = 496;
|
||||
extern const int ACCESS_DENIED = 497;
|
||||
extern const int LIMIT_BY_WITH_TIES_IS_NOT_SUPPORTED = 498;
|
||||
@ -485,6 +485,7 @@ namespace ErrorCodes
|
||||
extern const int UNKNOWN_ROLE = 511;
|
||||
extern const int SET_NON_GRANTED_ROLE = 512;
|
||||
extern const int UNKNOWN_PART_TYPE = 513;
|
||||
extern const int ACCESS_STORAGE_FOR_INSERTION_NOT_FOUND = 514;
|
||||
|
||||
extern const int KEEPER_EXCEPTION = 999;
|
||||
extern const int POCO_EXCEPTION = 1000;
|
||||
|
Loading…
Reference in New Issue
Block a user