MXS-1512 Add mock Backend class that can generate resultsets
This commit is contained in:
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include <maxscale/cppdefs.hh>
|
#include <maxscale/cppdefs.hh>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <maxscale/resultset.h>
|
||||||
#include "routersession.hh"
|
#include "routersession.hh"
|
||||||
|
|
||||||
namespace maxscale
|
namespace maxscale
|
||||||
@ -33,6 +34,13 @@ class Backend
|
|||||||
public:
|
public:
|
||||||
virtual ~Backend();
|
virtual ~Backend();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an OK response.
|
||||||
|
*
|
||||||
|
* @return A GWBUF containing an OK response packet.
|
||||||
|
*/
|
||||||
|
static GWBUF* create_ok_response();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to handle a statement from a "client".
|
* Called to handle a statement from a "client".
|
||||||
*
|
*
|
||||||
@ -135,6 +143,31 @@ public:
|
|||||||
void handle_statement(RouterSession* pSession, GWBUF* pStatement);
|
void handle_statement(RouterSession* pSession, GWBUF* pStatement);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ResultsetBackend
|
||||||
|
*/
|
||||||
|
class ResultSetBackend : public BufferBackend
|
||||||
|
{
|
||||||
|
ResultSetBackend(const ResultSetBackend&);
|
||||||
|
ResultSetBackend& operator = (const ResultSetBackend&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
ResultSetBackend();
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
m_created = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_statement(RouterSession* pSession, GWBUF* pStatement);
|
||||||
|
|
||||||
|
virtual RESULT_ROW* create_row(RESULTSET* pResult_set);
|
||||||
|
|
||||||
|
static RESULT_ROW* create_row(RESULTSET* pResult_set, void* pThis);
|
||||||
|
|
||||||
|
int m_counter;
|
||||||
|
bool m_created;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "maxscale/mock/backend.hh"
|
#include "maxscale/mock/backend.hh"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <maxscale/query_classifier.h>
|
||||||
#include <maxscale/protocol/mysql.h>
|
#include <maxscale/protocol/mysql.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@ -36,6 +37,19 @@ Backend::~Backend()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
GWBUF* Backend::create_ok_response()
|
||||||
|
{
|
||||||
|
/* Note: sequence id is always 01 (4th byte) */
|
||||||
|
const static uint8_t ok[MYSQL_OK_PACKET_MIN_LEN] =
|
||||||
|
{ 07, 00, 00, 01, 00, 00, 00, 02, 00, 00, 00 };
|
||||||
|
|
||||||
|
GWBUF* pResponse = gwbuf_alloc_and_load(sizeof(ok), &ok);
|
||||||
|
ss_dassert(pResponse);
|
||||||
|
|
||||||
|
return pResponse;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// BufferBackend
|
// BufferBackend
|
||||||
//
|
//
|
||||||
@ -138,18 +152,108 @@ OkBackend::OkBackend()
|
|||||||
|
|
||||||
void OkBackend::handle_statement(RouterSession* pSession, GWBUF* pStatement)
|
void OkBackend::handle_statement(RouterSession* pSession, GWBUF* pStatement)
|
||||||
{
|
{
|
||||||
/* Note: sequence id is always 01 (4th byte) */
|
enqueue_response(pSession, create_ok_response());
|
||||||
const static uint8_t ok[MYSQL_OK_PACKET_MIN_LEN] =
|
|
||||||
{ 07, 00, 00, 01, 00, 00, 00, 02, 00, 00, 00 };
|
|
||||||
|
|
||||||
GWBUF* pResponse = gwbuf_alloc_and_load(sizeof(ok), &ok);
|
|
||||||
ss_dassert(pResponse);
|
|
||||||
|
|
||||||
enqueue_response(pSession, pResponse);
|
|
||||||
|
|
||||||
gwbuf_free(pStatement);
|
gwbuf_free(pStatement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ResultSetBackend
|
||||||
|
//
|
||||||
|
ResultSetBackend::ResultSetBackend()
|
||||||
|
: m_counter(0)
|
||||||
|
, m_created(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
class ResultSetDCB : public DCB
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ResultSetDCB()
|
||||||
|
{
|
||||||
|
DCB* pDcb = this;
|
||||||
|
memset(pDcb, 0, sizeof(*pDcb));
|
||||||
|
|
||||||
|
pDcb->func.write = &ResultSetDCB::write;
|
||||||
|
}
|
||||||
|
|
||||||
|
GWBUF* create_response() const
|
||||||
|
{
|
||||||
|
return gwbuf_alloc_and_load(m_response.size(), &m_response.front());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32_t write(GWBUF* pBuffer)
|
||||||
|
{
|
||||||
|
pBuffer = gwbuf_make_contiguous(pBuffer);
|
||||||
|
ss_dassert(pBuffer);
|
||||||
|
|
||||||
|
unsigned char* begin = GWBUF_DATA(pBuffer);
|
||||||
|
unsigned char* end = begin + GWBUF_LENGTH(pBuffer);
|
||||||
|
|
||||||
|
m_response.insert(m_response.end(), begin, end);
|
||||||
|
|
||||||
|
gwbuf_free(pBuffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t write(DCB* pDcb, GWBUF* pBuffer)
|
||||||
|
{
|
||||||
|
return static_cast<ResultSetDCB*>(pDcb)->write(pBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> m_response;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResultSetBackend::handle_statement(RouterSession* pSession, GWBUF* pStatement)
|
||||||
|
{
|
||||||
|
qc_query_op_t op = qc_get_operation(pStatement);
|
||||||
|
|
||||||
|
if (op == QUERY_OP_SELECT)
|
||||||
|
{
|
||||||
|
RESULTSET* pResult_set = resultset_create(ResultSetBackend::create_row, this);
|
||||||
|
resultset_add_column(pResult_set, "a", 4, COL_TYPE_VARCHAR);
|
||||||
|
|
||||||
|
ResultSetDCB dcb;
|
||||||
|
|
||||||
|
resultset_stream_mysql(pResult_set, &dcb);
|
||||||
|
|
||||||
|
enqueue_response(pSession, dcb.create_response());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enqueue_response(pSession, create_ok_response());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RESULT_ROW* ResultSetBackend::create_row(RESULTSET* pResult_set)
|
||||||
|
{
|
||||||
|
RESULT_ROW* pRow = NULL;
|
||||||
|
|
||||||
|
if (!m_created)
|
||||||
|
{
|
||||||
|
pRow = resultset_make_row(pResult_set);
|
||||||
|
char buffer[32];
|
||||||
|
sprintf(buffer, "%d", ++m_counter);
|
||||||
|
resultset_row_set(pRow, 0, buffer);
|
||||||
|
|
||||||
|
m_created = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
RESULT_ROW* ResultSetBackend::create_row(RESULTSET* pResult_set, void* pThis)
|
||||||
|
{
|
||||||
|
return static_cast<ResultSetBackend*>(pThis)->create_row(pResult_set);
|
||||||
|
}
|
||||||
|
|
||||||
} // mock
|
} // mock
|
||||||
|
|
||||||
} // maxscale
|
} // maxscale
|
||||||
|
Reference in New Issue
Block a user