1 | #pragma once |
2 | |
3 | #include <Functions/IFunctionAdaptors.h> |
4 | #include <Common/IFactoryWithAliases.h> |
5 | |
6 | #include <functional> |
7 | #include <memory> |
8 | #include <string> |
9 | #include <unordered_map> |
10 | |
11 | |
12 | namespace DB |
13 | { |
14 | |
15 | class Context; |
16 | |
17 | |
18 | /** Creates function by name. |
19 | * Function could use for initialization (take ownership of shared_ptr, for example) |
20 | * some dictionaries from Context. |
21 | */ |
22 | class FunctionFactory : private boost::noncopyable, public IFactoryWithAliases<std::function<FunctionOverloadResolverImplPtr(const Context &)>> |
23 | { |
24 | public: |
25 | |
26 | static FunctionFactory & instance(); |
27 | |
28 | template <typename Function> |
29 | void registerFunction(CaseSensitiveness case_sensitiveness = CaseSensitive) |
30 | { |
31 | registerFunction<Function>(Function::name, case_sensitiveness); |
32 | } |
33 | |
34 | template <typename Function> |
35 | void registerFunction(const std::string & name, CaseSensitiveness case_sensitiveness = CaseSensitive) |
36 | { |
37 | if constexpr (std::is_base_of<IFunction, Function>::value) |
38 | registerFunction(name, &createDefaultFunction<Function>, case_sensitiveness); |
39 | else |
40 | registerFunction(name, &Function::create, case_sensitiveness); |
41 | } |
42 | |
43 | /// Throws an exception if not found. |
44 | FunctionOverloadResolverPtr get(const std::string & name, const Context & context) const; |
45 | |
46 | /// Returns nullptr if not found. |
47 | FunctionOverloadResolverPtr tryGet(const std::string & name, const Context & context) const; |
48 | |
49 | /// The same methods to get developer interface implementation. |
50 | FunctionOverloadResolverImplPtr getImpl(const std::string & name, const Context & context) const; |
51 | FunctionOverloadResolverImplPtr tryGetImpl(const std::string & name, const Context & context) const; |
52 | |
53 | private: |
54 | using Functions = std::unordered_map<std::string, Creator>; |
55 | |
56 | Functions functions; |
57 | Functions case_insensitive_functions; |
58 | |
59 | template <typename Function> |
60 | static FunctionOverloadResolverImplPtr createDefaultFunction(const Context & context) |
61 | { |
62 | return std::make_unique<DefaultOverloadResolver>(Function::create(context)); |
63 | } |
64 | |
65 | const Functions & getCreatorMap() const override { return functions; } |
66 | |
67 | const Functions & getCaseInsensitiveCreatorMap() const override { return case_insensitive_functions; } |
68 | |
69 | String getFactoryName() const override { return "FunctionFactory" ; } |
70 | |
71 | /// Register a function by its name. |
72 | /// No locking, you must register all functions before usage of get. |
73 | void registerFunction( |
74 | const std::string & name, |
75 | Creator creator, |
76 | CaseSensitiveness case_sensitiveness = CaseSensitive); |
77 | }; |
78 | |
79 | } |
80 | |