MXS-1779 Implement the classify REST-API

This commit is contained in:
Johan Wikman 2018-10-17 17:38:06 +03:00
parent 3631388f75
commit a349f0ad0d
4 changed files with 131 additions and 1 deletions

View File

@ -100,6 +100,7 @@ extern const char CN_ADMIN_PORT[];
extern const char CN_ADMIN_SSL_KEY[];
extern const char CN_ADMIN_SSL_CERT[];
extern const char CN_ADMIN_SSL_CA_CERT[];
extern const char CN_ARGUMENTS[];
extern const char CN_ATTRIBUTES[];
extern const char CN_AUTHENTICATOR[];
extern const char CN_AUTHENTICATOR_DIAGNOSTICS[];
@ -118,10 +119,13 @@ extern const char CN_DEFAULT[];
extern const char CN_DESCRIPTION[];
extern const char CN_DISK_SPACE_THRESHOLD[];
extern const char CN_ENABLE_ROOT_USER[];
extern const char CN_FIELDS[];
extern const char CN_FILTERS[];
extern const char CN_FILTER[];
extern const char CN_FILTER_DIAGNOSTICS[];
extern const char CN_FUNCTIONS[];
extern const char CN_GATEWAY[];
extern const char CN_HAS_WHERE_CLAUSE[];
extern const char CN_ID[];
extern const char CN_INET[];
extern const char CN_LISTENER[];
@ -143,8 +147,10 @@ extern const char CN_MONITOR_DIAGNOSTICS[];
extern const char CN_MS_TIMESTAMP[];
extern const char CN_NAME[];
extern const char CN_NON_BLOCKING_POLLS[];
extern const char CN_OPERATION[];
extern const char CN_OPTIONS[];
extern const char CN_PARAMETERS[];
extern const char CN_PARSE_RESULT[];
extern const char CN_PASSIVE[];
extern const char CN_PASSWORD[];
extern const char CN_PEER_HOSTS[];
@ -189,6 +195,7 @@ extern const char CN_THREADS[];
extern const char CN_THREAD_STACK_SIZE[];
extern const char CN_TICKS[];
extern const char CN_TYPE[];
extern const char CN_TYPE_MASK[];
extern const char CN_UNIX[];
extern const char CN_USER[];
extern const char CN_USERS[];

View File

@ -933,4 +933,13 @@ bool qc_get_cache_stats(QC_CACHE_STATS* stats);
*/
json_t* qc_get_cache_stats_as_json();
/**
* String represenation for the parse result.
*
* @param result A parsing result.
*
* @return The corresponding string.
*/
const char* qc_result_to_string(qc_parse_result_t result);
MXS_END_DECLS

View File

@ -81,6 +81,7 @@ const char CN_ADMIN_PORT[] = "admin_port";
const char CN_ADMIN_SSL_KEY[] = "admin_ssl_key";
const char CN_ADMIN_SSL_CERT[] = "admin_ssl_cert";
const char CN_ADMIN_SSL_CA_CERT[] = "admin_ssl_ca_cert";
const char CN_ARGUMENTS[] = "arguments";
const char CN_ATTRIBUTES[] = "attributes";
const char CN_AUTHENTICATOR[] = "authenticator";
const char CN_AUTHENTICATOR_DIAGNOSTICS[] = "authenticator_diagnostics";
@ -99,10 +100,13 @@ const char CN_DESCRIPTION[] = "description";
const char CN_DISK_SPACE_THRESHOLD[] = "disk_space_threshold";
const char CN_DUMP_LAST_STATEMENTS[] = "dump_last_statements";
const char CN_ENABLE_ROOT_USER[] = "enable_root_user";
const char CN_FIELDS[] = "fields";
const char CN_FILTERS[] = "filters";
const char CN_FILTER[] = "filter";
const char CN_FILTER_DIAGNOSTICS[] = "filter_diagnostics";
const char CN_FUNCTIONS[] = "functions";
const char CN_GATEWAY[] = "gateway";
const char CN_HAS_WHERE_CLAUSE[] = "has_where_clause";
const char CN_ID[] = "id";
const char CN_INET[] = "inet";
const char CN_LISTENER[] = "listener";
@ -124,8 +128,10 @@ const char CN_MONITOR_DIAGNOSTICS[] = "monitor_diagnostics";
const char CN_MS_TIMESTAMP[] = "ms_timestamp";
const char CN_NAME[] = "name";
const char CN_NON_BLOCKING_POLLS[] = "non_blocking_polls";
const char CN_OPERATION[] = "operation";
const char CN_OPTIONS[] = "options";
const char CN_PARAMETERS[] = "parameters";
const char CN_PARSE_RESULT[] = "parse_result";
const char CN_PASSIVE[] = "passive";
const char CN_PASSWORD[] = "password";
const char CN_PEER_HOSTS[] = "peer_hosts";
@ -172,6 +178,7 @@ const char CN_THREADS[] = "threads";
const char CN_THREAD_STACK_SIZE[] = "thread_stack_size";
const char CN_TICKS[] = "ticks";
const char CN_TYPE[] = "type";
const char CN_TYPE_MASK[] = "type_mask";
const char CN_UNIX[] = "unix";
const char CN_USER[] = "user";
const char CN_USERS[] = "users";

View File

@ -775,6 +775,28 @@ GWBUF* qc_get_preparable_stmt(GWBUF* stmt)
return preparable_stmt;
}
const char* qc_result_to_string(qc_parse_result_t result)
{
switch (result)
{
case QC_QUERY_INVALID:
return "QC_QUERY_INVALID";
case QC_QUERY_TOKENIZED:
return "QC_QUERY_TOKENIZED";
case QC_QUERY_PARTIALLY_PARSED:
return "QC_QUERY_PARTIALLY_PARSED";
case QC_QUERY_PARSED:
return "QC_QUERY_PARSED";
default:
mxb_assert(!true);
return "Unknown";
}
}
const char* qc_op_to_string(qc_query_op_t op)
{
switch (op)
@ -1377,12 +1399,97 @@ bool qc_alter_from_json(json_t* pJson)
return rv;
}
namespace
{
void append_field_info(json_t* pParent,
const char* zName,
const QC_FIELD_INFO* begin, const QC_FIELD_INFO* end)
{
json_t* pFields = json_array();
std::for_each(begin, end, [pFields](const QC_FIELD_INFO& info) {
std::string name;
if (info.database)
{
name += info.database;
name += '.';
mxb_assert(info.table);
}
if (info.table)
{
name += info.table;
name += '.';
}
mxb_assert(info.column);
name += info.column;
json_array_append_new(pFields, json_string(name.c_str()));
});
json_object_set_new(pParent, zName, pFields);
}
void append_field_info(json_t* pParams, GWBUF* pBuffer)
{
const QC_FIELD_INFO* begin;
size_t n;
qc_get_field_info(pBuffer, &begin, &n);
append_field_info(pParams, CN_FIELDS, begin, begin + n);
}
void append_function_info(json_t* pParams, GWBUF* pBuffer)
{
json_t* pFunctions = json_array();
const QC_FUNCTION_INFO* begin;
size_t n;
qc_get_function_info(pBuffer, &begin, &n);
std::for_each(begin, begin + n, [pFunctions](const QC_FUNCTION_INFO& info) {
json_t* pFunction = json_object();
json_object_set_new(pFunction, CN_NAME, json_string(info.name));
append_field_info(pFunction, CN_ARGUMENTS, info.fields, info.fields + info.n_fields);
json_array_append_new(pFunctions, pFunction);
});
json_object_set_new(pParams, CN_FUNCTIONS, pFunctions);
}
}
std::unique_ptr<json_t> qc_classify_as_json(const char* zHost, const std::string& statement)
{
json_t* pParams = json_object();
// TODO: Fill object with classification information.
std::unique_ptr<GWBUF> sBuffer(modutil_create_query(statement.c_str()));
GWBUF* pBuffer = sBuffer.get();
qc_parse_result result = qc_parse(pBuffer, QC_COLLECT_ALL);
json_object_set_new(pParams, CN_PARSE_RESULT, json_string(qc_result_to_string(result)));
if (result != QC_QUERY_INVALID)
{
char* zType_mask = qc_typemask_to_string(qc_get_type_mask(pBuffer));
json_object_set_new(pParams, CN_TYPE_MASK, json_string(zType_mask));
MXS_FREE(zType_mask);
json_object_set_new(pParams, CN_OPERATION, json_string(qc_op_to_string(qc_get_operation(pBuffer))));
bool has_clause = qc_query_has_clause(pBuffer);
json_object_set_new(pParams, CN_HAS_WHERE_CLAUSE, json_boolean(has_clause));
append_field_info(pParams, pBuffer);
append_function_info(pParams, pBuffer);
}
json_t* pAttributes = json_object();
json_object_set_new(pAttributes, CN_PARAMETERS, pParams);