From 684ddfd12d6336152b0831cf57e6156edd15f3cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 18 Feb 2019 11:37:14 +0200 Subject: [PATCH] MXS-2302: Use filter template in hintfilter --- .../modules/filter/hintfilter/hintfilter.cc | 233 ++++++------------ server/modules/filter/hintfilter/mysqlhint.hh | 31 ++- .../filter/hintfilter/test/test_hintparser.cc | 3 +- 3 files changed, 93 insertions(+), 174 deletions(-) diff --git a/server/modules/filter/hintfilter/hintfilter.cc b/server/modules/filter/hintfilter/hintfilter.cc index 26a2871bc..bf9890d47 100644 --- a/server/modules/filter/hintfilter/hintfilter.cc +++ b/server/modules/filter/hintfilter/hintfilter.cc @@ -26,17 +26,75 @@ * */ -static MXS_FILTER* createInstance(const char* name, MXS_CONFIG_PARAMETER* params); -static MXS_FILTER_SESSION* newSession(MXS_FILTER* instance, MXS_SESSION* session); -static void closeSession(MXS_FILTER* instance, MXS_FILTER_SESSION* session); -static void freeSession(MXS_FILTER* instance, MXS_FILTER_SESSION* session); -static void setDownstream(MXS_FILTER* instance, - MXS_FILTER_SESSION* fsession, - MXS_DOWNSTREAM* downstream); -static int routeQuery(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession, GWBUF* queue); -static void diagnostic(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession, DCB* dcb); -static json_t* diagnostic_json(const MXS_FILTER* instance, const MXS_FILTER_SESSION* fsession); -static uint64_t getCapabilities(MXS_FILTER* instance); +// static +HINT_INSTANCE* HINT_INSTANCE::create(const char* zName, MXS_CONFIG_PARAMETER* ppParams) +{ + return new(std::nothrow) HINT_INSTANCE; +} + +HINT_SESSION* HINT_INSTANCE::newSession(MXS_SESSION* pSession) +{ + return new(std::nothrow) HINT_SESSION(pSession); +} + +void HINT_INSTANCE::diagnostics(DCB* pDcb) const +{ +} + +json_t* HINT_INSTANCE::diagnostics_json() const +{ + return nullptr; +} + +uint64_t HINT_INSTANCE::getCapabilities() +{ + return RCAP_TYPE_CONTIGUOUS_INPUT; +} + +HINT_SESSION::HINT_SESSION(MXS_SESSION* session) + : mxs::FilterSession(session) +{ +} + +/** + * Close a session with the filter, this is the mechanism + * by which a filter may cleanup data structure etc. + * + * @param instance The filter instance data + * @param session The session being closed + */ +HINT_SESSION::~HINT_SESSION() +{ + for (auto& a : named_hints) + { + hint_free(a.second); + } + + for (auto& a : stack) + { + hint_free(a); + } +} + +/** + * The routeQuery entry point. This is passed the query buffer + * to which the filter should be applied. Once applied the + * query should normally be passed to the downstream component + * (filter or router) in the filter chain. + * + * @param instance The filter instance data + * @param session The filter session + * @param queue The query data + */ +int HINT_SESSION::routeQuery(GWBUF* queue) +{ + if (modutil_is_SQL(queue) && gwbuf_length(queue) > 5) + { + process_hints(queue); + } + + return mxs::FilterSession::routeQuery(queue); +} extern "C" { @@ -51,22 +109,6 @@ extern "C" */ MXS_MODULE* MXS_CREATE_MODULE() { - static MXS_FILTER_OBJECT MyObject = - { - createInstance, - newSession, - closeSession, - freeSession, - setDownstream, - NULL, // No upstream requirement - routeQuery, - NULL, // No clientReply - diagnostic, - diagnostic_json, - getCapabilities, - NULL, // No destroyInstance - }; - static MXS_MODULE info = { MXS_MODULE_API_FILTER, @@ -75,7 +117,7 @@ extern "C" "A hint parsing filter", "V1.0.0", RCAP_TYPE_CONTIGUOUS_INPUT, - &MyObject, + &HINT_INSTANCE::s_object, NULL, /* Process init. */ NULL, /* Process finish. */ NULL, /* Thread init. */ @@ -88,138 +130,3 @@ extern "C" return &info; } } - -/** - * Create an instance of the filter for a particular service - * within MaxScale. - * - * @param name The name of the instance (as defined in the config file). - * @param options The options for this filter - * @param params The array of name/value pair parameters for the filter - * - * @return The instance data for this new instance - */ -static MXS_FILTER* createInstance(const char* name, MXS_CONFIG_PARAMETER* params) -{ - return static_cast(new(std::nothrow) HINT_INSTANCE); -} - -/** - * Associate a new session with this instance of the filter. - * - * @param instance The filter instance data - * @param session The session itself - * @return Session specific data for this session - */ -static MXS_FILTER_SESSION* newSession(MXS_FILTER* instance, MXS_SESSION* session) -{ - return static_cast(new(std::nothrow) HINT_SESSION); -} - -/** - * Close a session with the filter, this is the mechanism - * by which a filter may cleanup data structure etc. - * - * @param instance The filter instance data - * @param session The session being closed - */ -static void closeSession(MXS_FILTER* instance, MXS_FILTER_SESSION* session) -{ - HINT_SESSION* my_session = (HINT_SESSION*)session; - - for (auto& a : my_session->named_hints) - { - hint_free(a.second); - } - - for (auto& a : my_session->stack) - { - hint_free(a); - } -} - -/** - * Free the memory associated with this filter session. - * - * @param instance The filter instance data - * @param session The session being closed - */ -static void freeSession(MXS_FILTER* instance, MXS_FILTER_SESSION* session) -{ - delete session; -} - -/** - * Set the downstream component for this filter. - * - * @param instance The filter instance data - * @param session The session being closed - * @param downstream The downstream filter or router - */ -static void setDownstream(MXS_FILTER* instance, MXS_FILTER_SESSION* session, MXS_DOWNSTREAM* downstream) -{ - HINT_SESSION* my_session = (HINT_SESSION*)session; - - my_session->down = *downstream; -} - -/** - * The routeQuery entry point. This is passed the query buffer - * to which the filter should be applied. Once applied the - * query should normally be passed to the downstream component - * (filter or router) in the filter chain. - * - * @param instance The filter instance data - * @param session The filter session - * @param queue The query data - */ -static int routeQuery(MXS_FILTER* instance, MXS_FILTER_SESSION* session, GWBUF* queue) -{ - HINT_SESSION* my_session = (HINT_SESSION*)session; - - if (modutil_is_SQL(queue) && gwbuf_length(queue) > 5) - { - my_session->process_hints(queue); - } - - /* Now process the request */ - return my_session->down.routeQuery(my_session->down.instance, - my_session->down.session, - queue); -} - -/** - * Diagnostics routine - * - * If fsession is NULL then print diagnostics on the filter - * instance as a whole, otherwise print diagnostics for the - * particular session. - * - * @param instance The filter instance - * @param fsession Filter session, may be NULL - * @param dcb The DCB for diagnostic output - */ -static void diagnostic(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession, DCB* dcb) -{ -} - -/** - * Diagnostics routine - * - * @param instance The filter instance - * @param fsession Filter session, may be NULL - */ -static json_t* diagnostic_json(const MXS_FILTER* instance, const MXS_FILTER_SESSION* fsession) -{ - return NULL; -} - -/** - * Capability routine. - * - * @return The capabilities of the filter. - */ -static uint64_t getCapabilities(MXS_FILTER* instance) -{ - return RCAP_TYPE_NONE; -} diff --git a/server/modules/filter/hintfilter/mysqlhint.hh b/server/modules/filter/hintfilter/mysqlhint.hh index 210041f52..b0de5394c 100644 --- a/server/modules/filter/hintfilter/mysqlhint.hh +++ b/server/modules/filter/hintfilter/mysqlhint.hh @@ -14,25 +14,36 @@ #include #include +#include -/** - * The hint instance structure - */ -struct HINT_INSTANCE : public MXS_FILTER +class HINT_SESSION; + +class HINT_INSTANCE : public mxs::Filter { - int sessions = 0; +public: + static HINT_INSTANCE* create(const char* zName, MXS_CONFIG_PARAMETER* ppParams); + HINT_SESSION* newSession(MXS_SESSION* pSession); + void diagnostics(DCB* pDcb) const; + json_t* diagnostics_json() const; + uint64_t getCapabilities(); }; -/** - * A hint parser session structure - */ -struct HINT_SESSION : public MXS_FILTER_SESSION +class HINT_SESSION : public mxs::FilterSession { - MXS_DOWNSTREAM down; +public: + HINT_SESSION(MXS_SESSION* session); + ~HINT_SESSION(); + int routeQuery(GWBUF* queue); + +private: std::vector stack; std::unordered_map named_hints; template HINT* process_comment(InputIter it, InputIter end); void process_hints(GWBUF* buffer); + + // Unit testing functions + friend void count_hints(const std::string& input, int num_expected); + friend void test_parse(const std::string& input, int expected_type); }; diff --git a/server/modules/filter/hintfilter/test/test_hintparser.cc b/server/modules/filter/hintfilter/test/test_hintparser.cc index 2dad9da7a..d4ea3b8d9 100644 --- a/server/modules/filter/hintfilter/test/test_hintparser.cc +++ b/server/modules/filter/hintfilter/test/test_hintparser.cc @@ -16,6 +16,7 @@ #endif #include "../hintparser.cc" +#include "../hintfilter.cc" #include #include @@ -71,7 +72,7 @@ void test(const std::string& input, std::initializer_list expected) mxb_assert(rval); } -static HINT_SESSION session = {}; +static HINT_SESSION session(nullptr); void test_parse(const std::string& input, int expected_type) {