#ifndef QUERY_BACKEND_PROVIDER_HPP #define QUERY_BACKEND_PROVIDER_HPP #include "matador/utils/library.hpp" #include #include #include namespace matador::sql { class connection_impl; struct connection_info; class dialect; class backend_provider { private: backend_provider(); public: struct basic_backend_service { virtual ~basic_backend_service() = default; [[nodiscard]] virtual connection_impl* create(const connection_info&) = 0; virtual void destroy(connection_impl*) = 0; [[nodiscard]] virtual const sql::dialect* dialect() const = 0; }; static backend_provider& instance(); connection_impl* create_connection(const std::string &connection_type, const connection_info &info); void destroy_connection(const std::string &connection_type, connection_impl *c); const dialect& connection_dialect(const std::string &connection_type); void register_backend(const std::string &connection_type, std::unique_ptr &&service); private: class backend_service final : public basic_backend_service { public: explicit backend_service(const std::string &connection_type); backend_service(const backend_service&) = delete; backend_service& operator=(const backend_service&) = delete; backend_service(backend_service&&) noexcept = default; backend_service& operator=(backend_service&&) noexcept = default; ~backend_service() override; [[nodiscard]] connection_impl* create(const connection_info&) override; void destroy(connection_impl *conn) override; [[nodiscard]] const class dialect* dialect() const override; private: typedef connection_impl*(*create_func)(const connection_info&); typedef void (*destroy_func)(connection_impl*); typedef const class dialect*(*dialect_func)(); create_func create_connection{}; destroy_func destroy_connection{}; dialect_func get_dialect{}; utils::library lib; }; private: using backends_t = std::unordered_map>; backends_t backends_; }; } #endif //QUERY_BACKEND_PROVIDER_HPP