diff --git a/include/maxscale/session.h b/include/maxscale/session.h index 3553cc0ab..77ab61b89 100644 --- a/include/maxscale/session.h +++ b/include/maxscale/session.h @@ -46,6 +46,7 @@ MXS_BEGIN_DECLS struct dcb; struct service; struct filter_def; +struct server; /** * The session statistics structure @@ -176,6 +177,11 @@ typedef struct session bool ses_is_child; /*< this is a child session */ session_trx_state_t trx_state; /*< The current transaction state. */ bool autocommit; /*< Whether autocommit is on. */ + struct + { + GWBUF *buffer; /**< Buffer containing the statement */ + const struct server *target; /**< Where the statement was sent */ + } stmt; /**< Current statement being executed */ skygw_chk_t ses_chk_tail; } SESSION; @@ -254,21 +260,6 @@ session_trx_state_t session_get_trx_state(const SESSION* ses); */ session_trx_state_t session_set_trx_state(SESSION* ses, session_trx_state_t new_state); -/** - * Tells whether an explicit transaction is active. - * - * @see session_get_trx_state - * - * @note The return value is valid only if either a router or a filter - * has declared that it needs RCAP_TYPE_TRANSACTION_TRACKING. - * - * @return True if a transaction is active, false otherwise. - */ -static inline bool session_trx_is_active(const SESSION* ses) -{ - return ses->trx_state & SESSION_TRX_ACTIVE_BIT; -} - /** * Tells whether an explicit READ ONLY transaction is active. * @@ -323,6 +314,21 @@ static inline bool session_is_autocommit(const SESSION* ses) return ses->autocommit; } +/** + * Tells whether a transaction is active. + * + * @see session_get_trx_state + * + * @note The return value is valid only if either a router or a filter + * has declared that it needs RCAP_TYPE_TRANSACTION_TRACKING. + * + * @return True if a transaction is active, false otherwise. + */ +static inline bool session_trx_is_active(const SESSION* ses) +{ + return !session_is_autocommit(ses) || (ses->trx_state & SESSION_TRX_ACTIVE_BIT); +} + /** * Sets the autocommit state of the session. * @@ -370,4 +376,43 @@ SESSION* session_get_ref(SESSION *sessoin); */ void session_put_ref(SESSION *session); +/** + * @brief Store the current statement into session + * + * This creates an additional reference to the buffer. If an old statement is stored, + * it will be replaced with a clone of @c buf. + * + * @param session Session where statement is stored + * @param buf Buffer containing the current statement + * @param server Server where the statement is being executed + * @return True if statement was successfully stored, false if the cloning of @c buf failed. + */ +bool session_store_stmt(SESSION *session, GWBUF *buf, const struct server *server); + +/** + * @brief Fetch stored statement + * + * The value returned by this call must be freed by the caller with gwbuf_free(). + * + * @param session Session with a stored statement + * @return Stored statement or NULL if no statement was stored + */ +GWBUF* session_fetch_stmt(SESSION *session); + +/** + * Fetch the stored target + * + * @param session Session whose target is fetched + * @return The server where the statement is executed or NULL if no statement is + * stored + */ +const struct server* session_fetch_stmt_target(const SESSION *session); + +/** + * Clear the stored statement + * + * @param session Session to clear + */ +void session_clear_stmt(SESSION *session); + MXS_END_DECLS diff --git a/server/core/session.c b/server/core/session.c index 54ab0fe81..15810733b 100644 --- a/server/core/session.c +++ b/server/core/session.c @@ -105,6 +105,8 @@ session_alloc(SERVICE *service, DCB *client_dcb) session->service = service; session->client_dcb = client_dcb; session->stats.connect = time(0); + session->stmt.buffer = NULL; + session->stmt.target = NULL; /*< * Associate the session to the client DCB and set the reference count on * the session to indicate that there is a single reference to the @@ -395,6 +397,7 @@ static void session_free(SESSION *session) static void session_final_free(SESSION *session) { + gwbuf_free(session->stmt.buffer); MXS_FREE(session); } @@ -939,3 +942,43 @@ void session_put_ref(SESSION *session) } } } + +bool session_store_stmt(SESSION *session, GWBUF *buf, const SERVER *server) +{ + bool rval = false; + + if (session->stmt.buffer) + { + /** This should not happen with proper use */ + ss_dassert(false); + gwbuf_free(session->stmt.buffer); + } + + if ((session->stmt.buffer = gwbuf_clone(buf))) + { + session->stmt.target = server; + /** No old statements were stored and we successfully cloned the buffer */ + rval = true; + } + + return rval; +} + +GWBUF *session_fetch_stmt(SESSION *session) +{ + GWBUF *rval = session->stmt.buffer; + session->stmt.buffer = NULL; + return rval; +} + +const SERVER* session_fetch_stmt_target(const SESSION *session) +{ + return session->stmt.target; +} + +void session_clear_stmt(SESSION *session) +{ + gwbuf_free(session->stmt.buffer); + session->stmt.buffer = NULL; + session->stmt.target = NULL; +} diff --git a/server/modules/authenticator/NullAuthAllow/CMakeLists.txt b/server/modules/authenticator/NullAuthAllow/CMakeLists.txt index 2f11fb0f2..23be1cb3e 100644 --- a/server/modules/authenticator/NullAuthAllow/CMakeLists.txt +++ b/server/modules/authenticator/NullAuthAllow/CMakeLists.txt @@ -1,4 +1,4 @@ add_library(NullAuthAllow SHARED null_auth_allow.c) -target_link_libraries(NullAuthAllow maxscale-common) +target_link_libraries(NullAuthAllow maxscale-common MySQLCommon) set_target_properties(NullAuthAllow PROPERTIES VERSION "1.0.0") install_module(NullAuthAllow core)