#pragma once #include #include #include namespace DB { /// Implementation of IAccessStorage which contains multiple nested storages. class MultipleAccessStorage : public IAccessStorage { public: static constexpr char STORAGE_TYPE[] = "multiple"; using Storage = IAccessStorage; using StoragePtr = std::shared_ptr; using ConstStoragePtr = std::shared_ptr; MultipleAccessStorage(const String & storage_name_ = STORAGE_TYPE); ~MultipleAccessStorage() override; const char * getStorageType() const override { return STORAGE_TYPE; } void setStorages(const std::vector & storages); void addStorage(const StoragePtr & new_storage); void removeStorage(const StoragePtr & storage_to_remove); std::vector getStorages(); std::vector getStorages() const; std::shared_ptr> getStoragesPtr(); ConstStoragePtr findStorage(const UUID & id) const; StoragePtr findStorage(const UUID & id); ConstStoragePtr getStorage(const UUID & id) const; StoragePtr getStorage(const UUID & id); protected: std::optional findImpl(EntityType type, const String & name) const override; std::vector findAllImpl(EntityType type) const override; 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; scope_guard subscribeForChangesImpl(const UUID & id, const OnChangedHandler & handler) const override; scope_guard subscribeForChangesImpl(EntityType type, const OnChangedHandler & handler) const override; bool hasSubscriptionImpl(const UUID & id) const override; bool hasSubscriptionImpl(EntityType type) const override; UUID loginImpl(const Credentials & credentials, const Poco::Net::IPAddress & address, const ExternalAuthenticators & external_authenticators) const override; UUID getIDOfLoggedUserImpl(const String & user_name) const override; private: using Storages = std::vector; std::shared_ptr getStoragesInternal() const; void updateSubscriptionsToNestedStorages(std::unique_lock & lock) const; std::shared_ptr nested_storages; mutable LRUCache ids_cache; mutable std::list handlers_by_type[static_cast(EntityType::MAX)]; mutable std::unordered_map subscriptions_to_nested_storages[static_cast(EntityType::MAX)]; mutable std::mutex mutex; }; }