MaxScale/server/modules/routing/schemarouter/schemaroutersession.hh
2019-11-13 08:37:17 +02:00

173 lines
5.8 KiB
C++

/*
* Copyright (c) 2018 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
*
* Change Date: 2023-11-12
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#pragma once
#include "schemarouter.hh"
#include <string>
#include <list>
#include <maxscale/protocol/mysql.hh>
#include <maxscale/router.hh>
#include <maxscale/session_command.hh>
#include "shard_map.hh"
namespace schemarouter
{
/**
* Bitmask values for the router session's initialization. These values are used
* to prevent responses from internal commands being forwarded to the client.
*/
enum init_mask
{
INIT_READY = 0x00,
INIT_MAPPING = 0x01,
INIT_USE_DB = 0x02,
INIT_UNINT = 0x04,
INIT_FAILED = 0x08
};
enum showdb_response
{
SHOWDB_FULL_RESPONSE,
SHOWDB_PARTIAL_RESPONSE,
SHOWDB_DUPLICATE_DATABASES,
SHOWDB_FATAL_ERROR
};
#define SCHEMA_ERR_DUPLICATEDB 5000
#define SCHEMA_ERRSTR_DUPLICATEDB "DUPDB"
#define SCHEMA_ERR_DBNOTFOUND 1049
#define SCHEMA_ERRSTR_DBNOTFOUND "42000"
/**
* Route target types
*/
enum route_target
{
TARGET_UNDEFINED,
TARGET_NAMED_SERVER,
TARGET_ALL,
TARGET_ANY
};
/** Helper macros for route target type */
#define TARGET_IS_UNDEFINED(t) (t == TARGET_UNDEFINED)
#define TARGET_IS_NAMED_SERVER(t) (t == TARGET_NAMED_SERVER)
#define TARGET_IS_ALL(t) (t == TARGET_ALL)
#define TARGET_IS_ANY(t) (t == TARGET_ANY)
class SchemaRouter;
/**
* The client session structure used within this router.
*/
class SchemaRouterSession : public mxs::RouterSession
{
public:
SchemaRouterSession(MXS_SESSION* session, SchemaRouter* router, SSRBackendList& backends);
/**
* The RouterSession instance will be deleted when a client session
* has terminated. Will be called only after @c close() has been called.
*/
~SchemaRouterSession();
/**
* Called when a client session has been closed.
*/
void close();
/**
* Called when a packet being is routed to the backend. The router should
* forward the packet to the appropriate server(s).
*
* @param pPacket A client packet.
*/
int32_t routeQuery(GWBUF* pPacket);
/**
* Called when a packet is routed to the client. The router should
* forward the packet to the client using `MXS_SESSION_ROUTE_REPLY`.
*
* @param pPacket A client packet.
* @param pBackend The backend the packet is coming from.
*/
void clientReply(GWBUF* pPacket, DCB* pBackend);
/**
*
* @param pMessage The error message.
* @param pProblem The DCB on which the error occurred.
* @param action The context.
* @param pSuccess On output, if false, the session will be terminated.
*/
void handleError(GWBUF* pMessage,
DCB* pProblem,
mxs_error_action_t action,
bool* pSuccess);
private:
/**
* Internal functions
*/
/** Helper functions */
SERVER* get_shard_target(GWBUF* buffer, uint32_t qtype);
SSRBackend get_bref_from_dcb(DCB* dcb);
bool get_shard_dcb(DCB** dcb, const char* name);
bool have_servers();
bool handle_default_db();
bool ignore_duplicate_table(const std::string& data);
SERVER* get_query_target(GWBUF* buffer);
SERVER* get_ps_target(GWBUF* buffer, uint32_t qtype, qc_query_op_t op);
/** Routing functions */
bool route_session_write(GWBUF* querybuf, uint8_t command);
void process_sescmd_response(SSRBackend& bref, GWBUF** ppPacket);
SERVER* resolve_query_target(GWBUF* pPacket,
uint32_t type,
uint8_t command,
enum route_target& route_target);
/** Shard mapping functions */
void send_databases();
bool send_shards();
void query_databases();
int inspect_mapping_states(SSRBackend& bref, GWBUF** wbuf);
enum showdb_response parse_mapping_response(SSRBackend& bref, GWBUF** buffer);
void route_queued_query();
void synchronize_shards();
void handle_mapping_reply(SSRBackend& bref, GWBUF** pPacket);
bool handle_statement(GWBUF* querybuf, SSRBackend& bref, uint8_t command, uint32_t type);
/** Member variables */
bool m_closed; /**< True if session closed */
DCB* m_client; /**< The client DCB */
MYSQL_session* m_mysql_session; /**< Session client data (username, password, SHA1). */
SSRBackendList m_backends; /**< Backend references */
SConfig m_config; /**< Session specific configuration */
SchemaRouter* m_router; /**< The router instance */
Shard m_shard; /**< Database to server mapping */
std::string m_connect_db; /**< Database the user was trying to connect to */
std::string m_current_db; /**< Current active database */
int m_state; /**< Initialization state bitmask */
std::list<mxs::Buffer> m_queue; /**< Query that was received before the session was ready */
Stats m_stats; /**< Statistics for this router */
uint64_t m_sent_sescmd; /**< The latest session command being executed */
uint64_t m_replied_sescmd;/**< The last session command reply that was sent to the client */
SERVER* m_load_target; /**< Target for LOAD DATA LOCAL INFILE */
};
}