MXS-1929: Take ResultSet into use
Replaced the previous RESULTSET with the new implementation. As the new ResultSet doesn't have a JSON streaming capability, the MaxInfo JSON interface has been removed. This should not be a big problem as the REST API offers the same information in a more secure and structured way.
This commit is contained in:
parent
8ababa1d39
commit
ec420332ea
@ -60,7 +60,7 @@
|
||||
#include "internal/maxscale.h"
|
||||
#include "internal/modules.h"
|
||||
#include "internal/monitor.h"
|
||||
#include "internal/poll.h"
|
||||
#include "internal/poll.hh"
|
||||
#include "internal/routingworker.hh"
|
||||
#include "internal/service.hh"
|
||||
#include "internal/statistics.h"
|
||||
|
@ -21,4 +21,4 @@
|
||||
*
|
||||
* @return A Result set
|
||||
*/
|
||||
ResultSet *moduleGetList();
|
||||
std::unique_ptr<ResultSet> moduleGetList();
|
||||
|
@ -20,4 +20,4 @@
|
||||
|
||||
#include <maxscale/resultset.hh>
|
||||
|
||||
ResultSet *monitor_get_list();
|
||||
std::unique_ptr<ResultSet> monitor_get_list();
|
||||
|
@ -13,15 +13,13 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file core/maxscale/poll.h - The private poll interface
|
||||
* The private poll header
|
||||
*/
|
||||
|
||||
#include <maxscale/cppdefs.hh>
|
||||
#include <maxscale/poll.h>
|
||||
|
||||
#include <maxscale/resultset.hh>
|
||||
|
||||
MXS_BEGIN_DECLS
|
||||
|
||||
struct mxs_worker;
|
||||
|
||||
#define MAX_EVENTS 1000
|
||||
@ -42,6 +40,4 @@ void dShowThreads(DCB *dcb);
|
||||
void dShowEventQ(DCB *dcb);
|
||||
void dShowEventStats(DCB *dcb);
|
||||
|
||||
ResultSet *eventTimesGetList();
|
||||
|
||||
MXS_END_DECLS
|
||||
std::unique_ptr<ResultSet> eventTimesGetList();
|
@ -18,4 +18,4 @@
|
||||
|
||||
#include <maxscale/resultset.hh>
|
||||
|
||||
ResultSet* serverGetList();
|
||||
std::unique_ptr<ResultSet> serverGetList();
|
||||
|
@ -353,5 +353,5 @@ json_t* service_relations_to_server(const SERVER* server, const char* host);
|
||||
*/
|
||||
json_t* service_relations_to_filter(const MXS_FILTER_DEF* filter, const char* host);
|
||||
|
||||
ResultSet* serviceGetList(void);
|
||||
ResultSet* serviceGetListenerList(void);
|
||||
std::unique_ptr<ResultSet> serviceGetList(void);
|
||||
std::unique_ptr<ResultSet> serviceGetListenerList(void);
|
||||
|
@ -40,4 +40,4 @@ struct RegistryTraits<MXS_SESSION>
|
||||
|
||||
}
|
||||
|
||||
ResultSet *sessionGetList();
|
||||
std::unique_ptr<ResultSet> sessionGetList();
|
||||
|
@ -15,8 +15,6 @@
|
||||
* @file load_utils.c Utility functions for loading of modules
|
||||
*/
|
||||
|
||||
#include "internal/modules.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -40,7 +38,7 @@
|
||||
#include <maxscale/monitor.h>
|
||||
#include <maxscale/query_classifier.h>
|
||||
|
||||
#include "internal/modules.h"
|
||||
#include "internal/modules.hh"
|
||||
#include "internal/config.hh"
|
||||
|
||||
namespace
|
||||
@ -580,6 +578,29 @@ json_t* module_list_to_json(const char* host)
|
||||
return mxs_json_resource(host, MXS_JSON_API_MODULES, arr);
|
||||
}
|
||||
|
||||
static const char* module_status_to_string(LOADED_MODULE* ptr)
|
||||
{
|
||||
switch (ptr->info->status)
|
||||
{
|
||||
case MXS_MODULE_IN_DEVELOPMENT:
|
||||
return "In Development";
|
||||
|
||||
case MXS_MODULE_ALPHA_RELEASE:
|
||||
return "Alpha";
|
||||
|
||||
case MXS_MODULE_BETA_RELEASE:
|
||||
return "Beta";
|
||||
|
||||
case MXS_MODULE_GA:
|
||||
return "GA";
|
||||
|
||||
case MXS_MODULE_EXPERIMENTAL:
|
||||
return "Experimental";
|
||||
};
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a row to the result set that defines the set of modules
|
||||
*
|
||||
@ -587,70 +608,24 @@ json_t* module_list_to_json(const char* host)
|
||||
* @param data The index of the row to send
|
||||
* @return The next row or NULL
|
||||
*/
|
||||
static RESULT_ROW *
|
||||
moduleRowCallback(RESULTSET *set, void *data)
|
||||
static void moduleRowCallback(std::unique_ptr<ResultSet>& set)
|
||||
{
|
||||
int *rowno = (int *)data;
|
||||
int i = 0;;
|
||||
char *stat, buf[20];
|
||||
RESULT_ROW *row;
|
||||
LOADED_MODULE *ptr;
|
||||
|
||||
ptr = registered;
|
||||
while (i < *rowno && ptr)
|
||||
for (LOADED_MODULE* ptr = registered; ptr; ptr = ptr->next)
|
||||
{
|
||||
i++;
|
||||
ptr = ptr->next;
|
||||
char buf[40];
|
||||
snprintf(buf, sizeof(buf), "%d.%d.%d",
|
||||
ptr->info->api_version.major,
|
||||
ptr->info->api_version.minor,
|
||||
ptr->info->api_version.patch);
|
||||
set->add_row({ptr->module, ptr->type, ptr->version, buf, module_status_to_string(ptr)});
|
||||
}
|
||||
if (ptr == NULL)
|
||||
{
|
||||
MXS_FREE(data);
|
||||
return NULL;
|
||||
}
|
||||
(*rowno)++;
|
||||
row = resultset_make_row(set);
|
||||
resultset_row_set(row, 0, ptr->module);
|
||||
resultset_row_set(row, 1, ptr->type);
|
||||
resultset_row_set(row, 2, ptr->version);
|
||||
snprintf(buf, 19, "%d.%d.%d", ptr->info->api_version.major,
|
||||
ptr->info->api_version.minor,
|
||||
ptr->info->api_version.patch);
|
||||
buf[19] = '\0';
|
||||
resultset_row_set(row, 3, buf);
|
||||
resultset_row_set(row, 4, ptr->info->status == MXS_MODULE_IN_DEVELOPMENT
|
||||
? "In Development"
|
||||
: (ptr->info->status == MXS_MODULE_ALPHA_RELEASE
|
||||
? "Alpha"
|
||||
: (ptr->info->status == MXS_MODULE_BETA_RELEASE
|
||||
? "Beta"
|
||||
: (ptr->info->status == MXS_MODULE_GA
|
||||
? "GA"
|
||||
: (ptr->info->status == MXS_MODULE_EXPERIMENTAL
|
||||
? "Experimental" : "Unknown")))));
|
||||
return row;
|
||||
}
|
||||
|
||||
RESULTSET *moduleGetList()
|
||||
std::unique_ptr<ResultSet> moduleGetList()
|
||||
{
|
||||
RESULTSET *set;
|
||||
int *data;
|
||||
|
||||
if ((data = (int *)MXS_MALLOC(sizeof(int))) == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
*data = 0;
|
||||
if ((set = resultset_create(moduleRowCallback, data)) == NULL)
|
||||
{
|
||||
MXS_FREE(data);
|
||||
return NULL;
|
||||
}
|
||||
resultset_add_column(set, "Module Name", 18, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "Module Type", 12, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "Version", 10, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "API Version", 8, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "Status", 15, COL_TYPE_VARCHAR);
|
||||
|
||||
std::unique_ptr<ResultSet> set = ResultSet::create({"Module Name", "Module Type", "Version", "API Version", "Status"});
|
||||
moduleRowCallback(set);
|
||||
return set;
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@
|
||||
|
||||
#include "internal/config.hh"
|
||||
#include "internal/externcmd.h"
|
||||
#include "internal/monitor.h"
|
||||
#include "internal/monitor.hh"
|
||||
#include "internal/modules.h"
|
||||
|
||||
/** Schema version, journals must have a matching version */
|
||||
@ -750,68 +750,23 @@ bool monitor_set_network_timeout(MXS_MONITOR *mon, int type, int value, const ch
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a row to the result set that defines the set of monitors
|
||||
*
|
||||
* @param set The result set
|
||||
* @param data The index of the row to send
|
||||
* @return The next row or NULL
|
||||
*/
|
||||
static RESULT_ROW *
|
||||
monitorRowCallback(RESULTSET *set, void *data)
|
||||
{
|
||||
int *rowno = (int *)data;
|
||||
int i = 0;;
|
||||
char buf[20];
|
||||
RESULT_ROW *row;
|
||||
MXS_MONITOR *ptr;
|
||||
|
||||
spinlock_acquire(&monLock);
|
||||
ptr = allMonitors;
|
||||
while (i < *rowno && ptr)
|
||||
{
|
||||
i++;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
if (ptr == NULL)
|
||||
{
|
||||
spinlock_release(&monLock);
|
||||
MXS_FREE(data);
|
||||
return NULL;
|
||||
}
|
||||
(*rowno)++;
|
||||
row = resultset_make_row(set);
|
||||
resultset_row_set(row, 0, ptr->name);
|
||||
resultset_row_set(row, 1, ptr->state & MONITOR_STATE_RUNNING
|
||||
? "Running" : "Stopped");
|
||||
spinlock_release(&monLock);
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a resultset that has the current set of monitors in it
|
||||
*
|
||||
* @return A Result set
|
||||
*/
|
||||
RESULTSET *
|
||||
monitor_get_list()
|
||||
std::unique_ptr<ResultSet> monitor_get_list()
|
||||
{
|
||||
RESULTSET *set;
|
||||
int *data;
|
||||
std::unique_ptr<ResultSet> set = ResultSet::create({"Monitor", "Status"});
|
||||
spinlock_acquire(&monLock);
|
||||
|
||||
if ((data = (int *)MXS_MALLOC(sizeof(int))) == NULL)
|
||||
for (MXS_MONITOR* ptr = allMonitors; ptr; ptr = ptr->next)
|
||||
{
|
||||
return NULL;
|
||||
const char* state = ptr->state & MONITOR_STATE_RUNNING ? "Running" : "Stopped";
|
||||
set->add_row({ptr->name, state});
|
||||
}
|
||||
*data = 0;
|
||||
if ((set = resultset_create(monitorRowCallback, data)) == NULL)
|
||||
{
|
||||
MXS_FREE(data);
|
||||
return NULL;
|
||||
}
|
||||
resultset_add_column(set, "Monitor", 20, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "Status", 10, COL_TYPE_VARCHAR);
|
||||
|
||||
spinlock_release(&monLock);
|
||||
return set;
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <maxscale/platform.h>
|
||||
#include <maxscale/server.h>
|
||||
#include <maxscale/statistics.h>
|
||||
#include "internal/poll.h"
|
||||
#include "internal/poll.hh"
|
||||
#include "internal/routingworker.hh"
|
||||
|
||||
using maxscale::Worker;
|
||||
@ -231,92 +231,28 @@ poll_get_stat(POLL_STAT what)
|
||||
return RoutingWorker::get_one_statistic(what);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct EVENT_TIMES_CB_DATA
|
||||
{
|
||||
int rowno;
|
||||
Worker::STATISTICS stats;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a row to the result set that defines the event queue statistics
|
||||
*
|
||||
* @param set The result set
|
||||
* @param data The index of the row to send
|
||||
* @return The next row or NULL
|
||||
*/
|
||||
static RESULT_ROW *
|
||||
eventTimesRowCallback(RESULTSET *set, void *v)
|
||||
{
|
||||
EVENT_TIMES_CB_DATA* data = (EVENT_TIMES_CB_DATA*)v;
|
||||
|
||||
char buf[40];
|
||||
RESULT_ROW *row;
|
||||
|
||||
if (data->rowno >= Worker::STATISTICS::N_QUEUE_TIMES)
|
||||
{
|
||||
MXS_FREE(data);
|
||||
return NULL;
|
||||
}
|
||||
row = resultset_make_row(set);
|
||||
if (data->rowno == 0)
|
||||
{
|
||||
resultset_row_set(row, 0, "< 100ms");
|
||||
}
|
||||
else if (data->rowno == Worker::STATISTICS::N_QUEUE_TIMES - 1)
|
||||
{
|
||||
snprintf(buf, 39, "> %2d00ms", Worker::STATISTICS::N_QUEUE_TIMES);
|
||||
buf[39] = '\0';
|
||||
resultset_row_set(row, 0, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(buf, 39, "%2d00 - %2d00ms", data->rowno, data->rowno + 1);
|
||||
buf[39] = '\0';
|
||||
resultset_row_set(row, 0, buf);
|
||||
}
|
||||
|
||||
snprintf(buf, 39, "%u", data->stats.qtimes[data->rowno]);
|
||||
buf[39] = '\0';
|
||||
resultset_row_set(row, 1, buf);
|
||||
snprintf(buf, 39, "%u", data->stats.exectimes[data->rowno]);
|
||||
buf[39] = '\0';
|
||||
resultset_row_set(row, 2, buf);
|
||||
data->rowno++;
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a result set that has the current set of services in it
|
||||
*
|
||||
* @return A Result set
|
||||
*/
|
||||
RESULTSET *
|
||||
eventTimesGetList()
|
||||
std::unique_ptr<ResultSet> eventTimesGetList()
|
||||
{
|
||||
RESULTSET *set;
|
||||
EVENT_TIMES_CB_DATA *data;
|
||||
std::unique_ptr<ResultSet> set = ResultSet::create({"Duration", "No. Events Queued", "No. Events Executed"});
|
||||
char buf[40];
|
||||
Worker::STATISTICS stats = RoutingWorker::get_statistics();
|
||||
|
||||
if ((data = (EVENT_TIMES_CB_DATA*)MXS_MALLOC(sizeof(EVENT_TIMES_CB_DATA))) == NULL)
|
||||
set->add_row({"< 100ms", std::to_string(stats.qtimes[0]), std::to_string(stats.exectimes[0])});
|
||||
|
||||
for (int i = 1; i < Worker::STATISTICS::N_QUEUE_TIMES - 1; i++)
|
||||
{
|
||||
return NULL;
|
||||
snprintf(buf, sizeof(buf), "%2d00 - %2d00ms", i, i + 1);
|
||||
set->add_row({buf, std::to_string(stats.qtimes[i]), std::to_string(stats.exectimes[i])});
|
||||
}
|
||||
|
||||
data->rowno = 0;
|
||||
data->stats = RoutingWorker::get_statistics();
|
||||
|
||||
if ((set = resultset_create(eventTimesRowCallback, data)) == NULL)
|
||||
{
|
||||
MXS_FREE(data);
|
||||
return NULL;
|
||||
}
|
||||
resultset_add_column(set, "Duration", 20, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "No. Events Queued", 12, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "No. Events Executed", 12, COL_TYPE_VARCHAR);
|
||||
int idx = Worker::STATISTICS::N_QUEUE_TIMES - 1;
|
||||
snprintf(buf, sizeof(buf), "> %2d00ms", Worker::STATISTICS::N_QUEUE_TIMES);
|
||||
set->add_row({buf, std::to_string(stats.qtimes[idx]), std::to_string(stats.exectimes[idx])});
|
||||
|
||||
return set;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
#include "internal/dcb.h"
|
||||
#include "internal/modules.h"
|
||||
#include "internal/poll.h"
|
||||
#include "internal/poll.hh"
|
||||
#include "internal/service.hh"
|
||||
#include "internal/statistics.h"
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include <maxscale/server.hh>
|
||||
|
||||
#include "internal/monitor.h"
|
||||
#include "internal/poll.h"
|
||||
#include "internal/poll.hh"
|
||||
#include "internal/routingworker.hh"
|
||||
#include "internal/config.hh"
|
||||
#include "internal/service.hh"
|
||||
@ -1020,80 +1020,28 @@ size_t server_get_parameter(const SERVER *server, const char *name, char* out, s
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a row to the result set that defines the set of servers
|
||||
*
|
||||
* @param set The result set
|
||||
* @param data The index of the row to send
|
||||
* @return The next row or NULL
|
||||
*/
|
||||
static RESULT_ROW *
|
||||
serverRowCallback(RESULTSET *set, void *data)
|
||||
{
|
||||
int *rowno = (int *)data;
|
||||
int i = 0;
|
||||
char *stat = NULL, buf[20];
|
||||
RESULT_ROW *row = NULL;
|
||||
SERVER *server = NULL;
|
||||
|
||||
spinlock_acquire(&server_spin);
|
||||
server = allServers;
|
||||
while (i < *rowno && server)
|
||||
{
|
||||
i++;
|
||||
server = server->next;
|
||||
}
|
||||
if (server == NULL)
|
||||
{
|
||||
spinlock_release(&server_spin);
|
||||
MXS_FREE(data);
|
||||
return NULL;
|
||||
}
|
||||
(*rowno)++;
|
||||
if (server_is_active(server))
|
||||
{
|
||||
row = resultset_make_row(set);
|
||||
resultset_row_set(row, 0, server->name);
|
||||
resultset_row_set(row, 1, server->address);
|
||||
sprintf(buf, "%d", server->port);
|
||||
resultset_row_set(row, 2, buf);
|
||||
sprintf(buf, "%d", server->stats.n_current);
|
||||
resultset_row_set(row, 3, buf);
|
||||
stat = server_status(server);
|
||||
resultset_row_set(row, 4, stat);
|
||||
MXS_FREE(stat);
|
||||
}
|
||||
spinlock_release(&server_spin);
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a resultset that has the current set of servers in it
|
||||
*
|
||||
* @return A Result set
|
||||
*/
|
||||
RESULTSET *
|
||||
serverGetList()
|
||||
std::unique_ptr<ResultSet> serverGetList()
|
||||
{
|
||||
RESULTSET *set;
|
||||
int *data;
|
||||
std::unique_ptr<ResultSet> set = ResultSet::create({"Server", "Address", "Port", "Connections", "Status"});
|
||||
spinlock_acquire(&server_spin);
|
||||
|
||||
if ((data = (int *)MXS_MALLOC(sizeof(int))) == NULL)
|
||||
for (SERVER* server = allServers; server; server = server->next)
|
||||
{
|
||||
return NULL;
|
||||
if (server_is_active(server))
|
||||
{
|
||||
char* stat = server_status(server);
|
||||
set->add_row({server->name, server->address, std::to_string(server->port),
|
||||
std::to_string(server->stats.n_current), stat});
|
||||
MXS_FREE(stat);
|
||||
}
|
||||
}
|
||||
*data = 0;
|
||||
if ((set = resultset_create(serverRowCallback, data)) == NULL)
|
||||
{
|
||||
MXS_FREE(data);
|
||||
return NULL;
|
||||
}
|
||||
resultset_add_column(set, "Server", 20, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "Address", 15, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "Port", 5, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "Connections", 8, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "Status", 20, COL_TYPE_VARCHAR);
|
||||
|
||||
spinlock_release(&server_spin);
|
||||
return set;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include <maxscale/log_manager.h>
|
||||
#include <maxscale/poll.h>
|
||||
#include <maxscale/protocol.h>
|
||||
#include <maxscale/resultset.h>
|
||||
#include <maxscale/resultset.hh>
|
||||
#include <maxscale/router.h>
|
||||
#include <maxscale/server.h>
|
||||
#include <maxscale/session.h>
|
||||
@ -1741,146 +1741,30 @@ serviceSessionCountAll()
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a row to the result set that defines the set of service
|
||||
* listeners
|
||||
*
|
||||
* TODO: Replace these
|
||||
*
|
||||
* @param set The result set
|
||||
* @param data The index of the row to send
|
||||
* @return The next row or NULL
|
||||
*/
|
||||
static RESULT_ROW *
|
||||
serviceListenerRowCallback(RESULTSET *set, void *data)
|
||||
{
|
||||
int *rowno = (int *)data;
|
||||
int i = 0;;
|
||||
char buf[20];
|
||||
RESULT_ROW *row;
|
||||
/* TODO: Fix this
|
||||
SERVICE *service;
|
||||
SERV_LISTENER *lptr = NULL;
|
||||
|
||||
spinlock_acquire(&service_spin);
|
||||
service = allServices;
|
||||
if (service)
|
||||
{
|
||||
lptr = service->ports;
|
||||
}
|
||||
while (i < *rowno && service)
|
||||
{
|
||||
lptr = service->ports;
|
||||
while (i < *rowno && lptr)
|
||||
{
|
||||
if ((lptr = lptr->next) != NULL)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (i < *rowno)
|
||||
{
|
||||
service = service->next;
|
||||
if (service && (lptr = service->ports) != NULL)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lptr == NULL)
|
||||
{
|
||||
spinlock_release(&service_spin);
|
||||
MXS_FREE(data);
|
||||
return NULL;
|
||||
}
|
||||
(*rowno)++;
|
||||
row = resultset_make_row(set);
|
||||
resultset_row_set(row, 0, service->name);
|
||||
resultset_row_set(row, 1, lptr->protocol);
|
||||
resultset_row_set(row, 2, (lptr && lptr->address) ? lptr->address : "*");
|
||||
sprintf(buf, "%d", lptr->port);
|
||||
resultset_row_set(row, 3, buf);
|
||||
resultset_row_set(row, 4, listener_state_to_string(lptr));
|
||||
spinlock_release(&service_spin);
|
||||
return row;
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a resultset that has the current set of services in it
|
||||
*
|
||||
* @return A Result set
|
||||
*/
|
||||
RESULTSET *
|
||||
serviceGetListenerList()
|
||||
std::unique_ptr<ResultSet> serviceGetListenerList()
|
||||
{
|
||||
RESULTSET *set;
|
||||
/* TODO: Fix this
|
||||
int *data;
|
||||
|
||||
if ((data = (int *)MXS_MALLOC(sizeof(int))) == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
*data = 0;
|
||||
if ((set = resultset_create(serviceListenerRowCallback, data)) == NULL)
|
||||
{
|
||||
MXS_FREE(data);
|
||||
return NULL;
|
||||
}
|
||||
resultset_add_column(set, "Service Name", 25, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "Protocol Module", 20, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "Address", 15, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "Port", 5, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "State", 8, COL_TYPE_VARCHAR);
|
||||
return set;
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a row to the result set that defines the set of services
|
||||
*
|
||||
* @param set The result set
|
||||
* @param data The index of the row to send
|
||||
* @return The next row or NULL
|
||||
*/
|
||||
static RESULT_ROW *
|
||||
serviceRowCallback(RESULTSET *set, void *data)
|
||||
{
|
||||
int *rowno = (int *)data;
|
||||
int i = 0;
|
||||
char buf[20];
|
||||
RESULT_ROW *row;
|
||||
/* TODO: Fix this
|
||||
SERVICE *service;
|
||||
|
||||
std::unique_ptr<ResultSet> set = ResultSet::create({"Service Name", "Protocol Module", "Address", "Port", "State"});
|
||||
spinlock_acquire(&service_spin);
|
||||
service = allServices;
|
||||
while (i < *rowno && service)
|
||||
|
||||
for (Service* service : allServices)
|
||||
{
|
||||
i++;
|
||||
service = service->next;
|
||||
LISTENER_ITERATOR iter;
|
||||
|
||||
for (SERV_LISTENER* lptr = listener_iterator_init(service, &iter);
|
||||
lptr; lptr = listener_iterator_next(&iter))
|
||||
{
|
||||
set->add_row({service->name, lptr->protocol, lptr->address,
|
||||
std::to_string(lptr->port), listener_state_to_string(lptr)});
|
||||
}
|
||||
}
|
||||
if (service == NULL)
|
||||
{
|
||||
spinlock_release(&service_spin);
|
||||
MXS_FREE(data);
|
||||
return NULL;
|
||||
}
|
||||
(*rowno)++;
|
||||
row = resultset_make_row(set);
|
||||
resultset_row_set(row, 0, service->name);
|
||||
resultset_row_set(row, 1, service->routerModule);
|
||||
sprintf(buf, "%d", service->stats.n_current);
|
||||
resultset_row_set(row, 2, buf);
|
||||
sprintf(buf, "%d", service->stats.n_sessions);
|
||||
resultset_row_set(row, 3, buf);
|
||||
|
||||
spinlock_release(&service_spin);
|
||||
return row;
|
||||
*/
|
||||
return NULL;
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1888,27 +1772,18 @@ serviceRowCallback(RESULTSET *set, void *data)
|
||||
*
|
||||
* @return A Result set
|
||||
*/
|
||||
RESULTSET *
|
||||
serviceGetList()
|
||||
std::unique_ptr<ResultSet> serviceGetList()
|
||||
{
|
||||
RESULTSET *set;
|
||||
int *data;
|
||||
std::unique_ptr<ResultSet> set = ResultSet::create({"Service Name", "Router Module", "No. Sessions", "Total Sessions"});
|
||||
spinlock_acquire(&service_spin);
|
||||
|
||||
if ((data = (int *)MXS_MALLOC(sizeof(int))) == NULL)
|
||||
for (Service* s : allServices)
|
||||
{
|
||||
return NULL;
|
||||
set->add_row({s->name, s->routerModule, std::to_string(s->stats.n_current),
|
||||
std::to_string(s->stats.n_sessions)});
|
||||
}
|
||||
*data = 0;
|
||||
if ((set = resultset_create(serviceRowCallback, data)) == NULL)
|
||||
{
|
||||
MXS_FREE(data);
|
||||
return NULL;
|
||||
}
|
||||
resultset_add_column(set, "Service Name", 25, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "Router Module", 20, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "No. Sessions", 10, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "Total Sessions", 10, COL_TYPE_VARCHAR);
|
||||
|
||||
spinlock_release(&service_spin);
|
||||
return set;
|
||||
}
|
||||
|
||||
|
@ -807,79 +807,21 @@ session_get_user(const MXS_SESSION *session)
|
||||
return (session && session->client_dcb) ? session->client_dcb->user : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback structure for the session list extraction
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int index;
|
||||
int current;
|
||||
SESSIONLISTFILTER filter;
|
||||
RESULT_ROW *row;
|
||||
RESULTSET *set;
|
||||
} SESSIONFILTER;
|
||||
|
||||
bool dcb_iter_cb(DCB *dcb, void *data)
|
||||
{
|
||||
SESSIONFILTER *cbdata = (SESSIONFILTER*)data;
|
||||
|
||||
if (cbdata->current < cbdata->index)
|
||||
{
|
||||
if (cbdata->filter == SESSION_LIST_ALL ||
|
||||
(cbdata->filter == SESSION_LIST_CONNECTION &&
|
||||
(dcb->session->state != SESSION_STATE_LISTENER)))
|
||||
{
|
||||
cbdata->current++;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER)
|
||||
{
|
||||
ResultSet* set = static_cast<ResultSet*>(data);
|
||||
MXS_SESSION *ses = dcb->session;
|
||||
char buf[20];
|
||||
MXS_SESSION *list_session = dcb->session;
|
||||
snprintf(buf, sizeof(buf), "%p", ses);
|
||||
|
||||
cbdata->index++;
|
||||
cbdata->row = resultset_make_row(cbdata->set);
|
||||
snprintf(buf, sizeof(buf), "%p", list_session);
|
||||
resultset_row_set(cbdata->row, 0, buf);
|
||||
resultset_row_set(cbdata->row, 1, ((list_session->client_dcb && list_session->client_dcb->remote)
|
||||
? list_session->client_dcb->remote : ""));
|
||||
resultset_row_set(cbdata->row, 2, (list_session->service && list_session->service->name
|
||||
? list_session->service->name : ""));
|
||||
resultset_row_set(cbdata->row, 3, session_state(list_session->state));
|
||||
return false;
|
||||
set->add_row({buf, ses->client_dcb->remote, ses->service->name, session_state(ses->state)});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a row to the result set that defines the set of sessions
|
||||
*
|
||||
* @param set The result set
|
||||
* @param data The index of the row to send
|
||||
* @return The next row or NULL
|
||||
*/
|
||||
static RESULT_ROW *
|
||||
sessionRowCallback(RESULTSET *set, void *data)
|
||||
{
|
||||
SESSIONFILTER *cbdata = (SESSIONFILTER*)data;
|
||||
RESULT_ROW *row = NULL;
|
||||
|
||||
cbdata->current = 0;
|
||||
dcb_foreach(dcb_iter_cb, cbdata);
|
||||
|
||||
if (cbdata->row)
|
||||
{
|
||||
row = cbdata->row;
|
||||
cbdata->row = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_FREE(cbdata);
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a resultset that has the current set of sessions in it
|
||||
*
|
||||
@ -890,38 +832,12 @@ sessionRowCallback(RESULTSET *set, void *data)
|
||||
* so we suppress the warning. In fact, the function call results in return
|
||||
* of the set structure which includes a pointer to data
|
||||
*/
|
||||
|
||||
/*lint -e429 */
|
||||
RESULTSET *
|
||||
sessionGetList(SESSIONLISTFILTER filter)
|
||||
std::unique_ptr<ResultSet> sessionGetList()
|
||||
{
|
||||
RESULTSET *set;
|
||||
SESSIONFILTER *data;
|
||||
|
||||
if ((data = (SESSIONFILTER *)MXS_MALLOC(sizeof(SESSIONFILTER))) == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
data->index = 0;
|
||||
data->filter = filter;
|
||||
data->current = 0;
|
||||
data->row = NULL;
|
||||
|
||||
if ((set = resultset_create(sessionRowCallback, data)) == NULL)
|
||||
{
|
||||
MXS_FREE(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data->set = set;
|
||||
resultset_add_column(set, "Session", 16, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "Client", 15, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "Service", 15, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "State", 15, COL_TYPE_VARCHAR);
|
||||
|
||||
std::unique_ptr<ResultSet> set = ResultSet::create({"Session", "Client", "Service", "State"});
|
||||
dcb_foreach(dcb_iter_cb, set.get());
|
||||
return set;
|
||||
}
|
||||
/*lint +e429 */
|
||||
|
||||
mxs_session_trx_state_t session_get_trx_state(const MXS_SESSION* ses)
|
||||
{
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "../internal/poll.h"
|
||||
#include "../internal/poll.hh"
|
||||
#include "../internal/routingworker.hh"
|
||||
#include "../internal/statistics.h"
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <maxscale/worker.hh>
|
||||
#include "../internal/poll.h"
|
||||
#include "../internal/poll.hh"
|
||||
|
||||
using namespace maxscale;
|
||||
using namespace std;
|
||||
|
@ -35,7 +35,7 @@
|
||||
|
||||
#include "internal/dcb.h"
|
||||
#include "internal/modules.h"
|
||||
#include "internal/poll.h"
|
||||
#include "internal/poll.hh"
|
||||
#include "internal/service.hh"
|
||||
#include "internal/statistics.h"
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#include <maxscale/cppdefs.hh>
|
||||
#include <map>
|
||||
#include <maxscale/resultset.h>
|
||||
#include <maxscale/resultset.hh>
|
||||
#include "routersession.hh"
|
||||
|
||||
namespace maxscale
|
||||
@ -161,10 +161,6 @@ public:
|
||||
|
||||
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;
|
||||
};
|
||||
|
@ -218,13 +218,10 @@ void ResultSetBackend::handle_statement(RouterSession* pSession, GWBUF* pStateme
|
||||
|
||||
if (op == QUERY_OP_SELECT)
|
||||
{
|
||||
RESULTSET* pResult_set = resultset_create(ResultSetBackend::create_row, this);
|
||||
resultset_add_column(pResult_set, "a", 4, COL_TYPE_VARCHAR);
|
||||
|
||||
std::unique_ptr<ResultSet> set = ResultSet::create({"a"});
|
||||
set->add_row({std::to_string(++m_counter)});
|
||||
ResultSetDCB dcb;
|
||||
|
||||
resultset_stream_mysql(pResult_set, &dcb);
|
||||
resultset_free(pResult_set);
|
||||
set->write(&dcb);
|
||||
|
||||
enqueue_response(pSession, dcb.create_response());
|
||||
}
|
||||
@ -234,29 +231,6 @@ void ResultSetBackend::handle_statement(RouterSession* pSession, GWBUF* pStateme
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
} // maxscale
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include <maxscale/protocol.h>
|
||||
#include <maxscale/modinfo.h>
|
||||
#include <maxscale/log_manager.h>
|
||||
#include <maxscale/resultset.h>
|
||||
#include <maxscale/resultset.hh>
|
||||
|
||||
#define ISspace(x) isspace((int)(x))
|
||||
#define HTTP_SERVER_STRING "MaxScale(c) v.1.0.0"
|
||||
@ -285,7 +285,7 @@ static int httpd_read_event(DCB* dcb)
|
||||
}
|
||||
if (strcmp(url, "/services") == 0)
|
||||
{
|
||||
RESULTSET *set, *seviceGetList();
|
||||
ResultSet *set, *seviceGetList();
|
||||
if ((set = serviceGetList()) != NULL)
|
||||
{
|
||||
resultset_stream_json(set, dcb);
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <maxscale/service.h>
|
||||
#include <maxscale/sqlite3.h>
|
||||
#include <maxscale/thread.h>
|
||||
#include <maxscale/mysql_binlog.h>
|
||||
|
||||
MXS_BEGIN_DECLS
|
||||
|
||||
@ -67,9 +68,6 @@ MXS_BEGIN_DECLS
|
||||
#define BLR_REPORT_REP_HEADER 0x02
|
||||
#define BLR_CHECK_ONLY 0x04
|
||||
|
||||
/* MariaDB GTID string len */
|
||||
#define GTID_MAX_LEN 42
|
||||
|
||||
/* GTID slite3 query buffer size */
|
||||
#define GTID_SQL_BUFFER_SIZE 1024
|
||||
|
||||
|
@ -61,7 +61,7 @@
|
||||
#include "../../../core/internal/maxscale.h"
|
||||
#include "../../../core/internal/modules.h"
|
||||
#include "../../../core/internal/monitor.h"
|
||||
#include "../../../core/internal/poll.h"
|
||||
#include "../../../core/internal/poll.hh"
|
||||
#include "../../../core/internal/session.h"
|
||||
#include "../../../core/internal/filter.hh"
|
||||
|
||||
|
@ -45,9 +45,9 @@
|
||||
#include <maxscale/dcb.h>
|
||||
#include <maxscale/maxscale.h>
|
||||
#include <maxscale/log_manager.h>
|
||||
#include <maxscale/resultset.h>
|
||||
#include <maxscale/resultset.hh>
|
||||
#include <maxscale/version.h>
|
||||
#include <maxscale/resultset.h>
|
||||
#include <maxscale/resultset.hh>
|
||||
#include <maxscale/secrets.h>
|
||||
#include <maxscale/users.h>
|
||||
#include <maxscale/protocol/mysql.h>
|
||||
@ -55,14 +55,14 @@
|
||||
#include "../../../core/internal/modules.h"
|
||||
#include "../../../core/internal/monitor.h"
|
||||
#include "../../../core/internal/session.h"
|
||||
#include "../../../core/internal/poll.h"
|
||||
#include "../../../core/internal/session.hh"
|
||||
#include "../../../core/internal/poll.hh"
|
||||
|
||||
extern char *create_hex_sha1_sha1_passwd(char *passwd);
|
||||
|
||||
static int maxinfo_statistics(INFO_INSTANCE *, INFO_SESSION *, GWBUF *);
|
||||
static int maxinfo_ping(INFO_INSTANCE *, INFO_SESSION *, GWBUF *);
|
||||
static int maxinfo_execute_query(INFO_INSTANCE *, INFO_SESSION *, char *);
|
||||
static int handle_url(INFO_INSTANCE *instance, INFO_SESSION *router_session, GWBUF *queue);
|
||||
static int maxinfo_send_ok(DCB *dcb);
|
||||
|
||||
/* The router entry points */
|
||||
@ -310,7 +310,8 @@ execute(MXS_ROUTER *rinstance, MXS_ROUTER_SESSION *router_session, GWBUF *queue)
|
||||
|
||||
if (GWBUF_TYPE(queue) == GWBUF_TYPE_HTTP)
|
||||
{
|
||||
return handle_url(instance, session, queue);
|
||||
gwbuf_free(queue);
|
||||
return 0;
|
||||
}
|
||||
if (session->queue)
|
||||
{
|
||||
@ -461,29 +462,6 @@ maxinfo_ping(INFO_INSTANCE *router, INFO_SESSION *session, GWBUF *queue)
|
||||
return session->dcb->func.write(session->dcb, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the version comment with the MaxScale version
|
||||
*
|
||||
* @param result The result set
|
||||
* @param data Pointer to int which is row count
|
||||
* @return The populated row
|
||||
*/
|
||||
static RESULT_ROW *
|
||||
version_comment(RESULTSET *result, void *data)
|
||||
{
|
||||
int *context = (int *)data;
|
||||
RESULT_ROW *row;
|
||||
|
||||
if (*context == 0)
|
||||
{
|
||||
(*context)++;
|
||||
row = resultset_make_row(result);
|
||||
resultset_row_set(row, 0, MAXSCALE_VERSION);
|
||||
return row;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* The hardwired select @@vercom response
|
||||
*
|
||||
@ -492,43 +470,9 @@ version_comment(RESULTSET *result, void *data)
|
||||
static void
|
||||
respond_vercom(DCB *dcb)
|
||||
{
|
||||
RESULTSET *result;
|
||||
int context = 0;
|
||||
|
||||
if ((result = resultset_create(version_comment, &context)) == NULL)
|
||||
{
|
||||
maxinfo_send_error(dcb, 0, "No resources available");
|
||||
return;
|
||||
}
|
||||
resultset_add_column(result, "@@version_comment", 40, COL_TYPE_VARCHAR);
|
||||
resultset_stream_mysql(result, dcb);
|
||||
resultset_free(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the version comment with the MaxScale version
|
||||
*
|
||||
* @param result The result set
|
||||
* @param data Pointer to int which is row count
|
||||
* @return The populated row
|
||||
*/
|
||||
static RESULT_ROW *
|
||||
starttime_row(RESULTSET *result, void *data)
|
||||
{
|
||||
int *context = (int *)data;
|
||||
RESULT_ROW *row;
|
||||
struct tm tm;
|
||||
static char buf[40];
|
||||
|
||||
if (*context == 0)
|
||||
{
|
||||
(*context)++;
|
||||
row = resultset_make_row(result);
|
||||
sprintf(buf, "%u", (unsigned int)maxscale_started());
|
||||
resultset_row_set(row, 0, buf);
|
||||
return row;
|
||||
}
|
||||
return NULL;
|
||||
std::unique_ptr<ResultSet> set = ResultSet::create({"@@version_comment"});
|
||||
set->add_row({MAXSCALE_VERSION});
|
||||
set->write(dcb);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -539,17 +483,9 @@ starttime_row(RESULTSET *result, void *data)
|
||||
static void
|
||||
respond_starttime(DCB *dcb)
|
||||
{
|
||||
RESULTSET *result;
|
||||
int context = 0;
|
||||
|
||||
if ((result = resultset_create(starttime_row, &context)) == NULL)
|
||||
{
|
||||
maxinfo_send_error(dcb, 0, "No resources available");
|
||||
return;
|
||||
}
|
||||
resultset_add_column(result, "starttime", 40, COL_TYPE_VARCHAR);
|
||||
resultset_stream_mysql(result, dcb);
|
||||
resultset_free(result);
|
||||
std::unique_ptr<ResultSet> set = ResultSet::create({"starttime"});
|
||||
set->add_row({std::to_string(maxscale_started())});
|
||||
set->write(dcb);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -651,72 +587,16 @@ maxinfo_execute_query(INFO_INSTANCE *instance, INFO_SESSION *session, char *sql)
|
||||
* Session all result set
|
||||
* @return A resultset for all sessions
|
||||
*/
|
||||
static RESULTSET *
|
||||
maxinfoSessionsAll()
|
||||
static std::unique_ptr<ResultSet> maxinfoSessionsAll()
|
||||
{
|
||||
return sessionGetList(SESSION_LIST_ALL);
|
||||
return sessionGetList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Client session result set
|
||||
* @return A resultset for all sessions
|
||||
*/
|
||||
static RESULTSET *
|
||||
maxinfoClientSessions()
|
||||
static std::unique_ptr<ResultSet> maxinfoClientSessions()
|
||||
{
|
||||
return sessionGetList(SESSION_LIST_CONNECTION);
|
||||
}
|
||||
|
||||
typedef RESULTSET *(*RESULTSETFUNC)();
|
||||
|
||||
/**
|
||||
* Table that maps a URI to a function to call to
|
||||
* to obtain the result set related to that URI
|
||||
*/
|
||||
static struct uri_table
|
||||
{
|
||||
const char *uri;
|
||||
RESULTSETFUNC func;
|
||||
} supported_uri[] =
|
||||
{
|
||||
{ "/services", serviceGetList },
|
||||
{ "/listeners", serviceGetListenerList },
|
||||
{ "/modules", moduleGetList },
|
||||
{ "/monitors", monitor_get_list },
|
||||
{ "/sessions", maxinfoSessionsAll },
|
||||
{ "/clients", maxinfoClientSessions },
|
||||
{ "/servers", serverGetList },
|
||||
{ "/variables", maxinfo_variables },
|
||||
{ "/status", maxinfo_status },
|
||||
{ "/event/times", eventTimesGetList },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/**
|
||||
* We have data from the client, this is a HTTP URL
|
||||
*
|
||||
* @param instance The router instance
|
||||
* @param session The router session returned from the newSession call
|
||||
* @param queue The queue of data buffers to route
|
||||
* @return The number of bytes sent
|
||||
*/
|
||||
static int
|
||||
handle_url(INFO_INSTANCE *instance, INFO_SESSION *session, GWBUF *queue)
|
||||
{
|
||||
char *uri;
|
||||
int i;
|
||||
RESULTSET *set;
|
||||
|
||||
uri = (char *)GWBUF_DATA(queue);
|
||||
for (i = 0; supported_uri[i].uri; i++)
|
||||
{
|
||||
if (strcmp(uri, supported_uri[i].uri) == 0)
|
||||
{
|
||||
set = (*supported_uri[i].func)();
|
||||
resultset_stream_json(set, session->dcb);
|
||||
resultset_free(set);
|
||||
}
|
||||
}
|
||||
gwbuf_free(queue);
|
||||
return 1;
|
||||
return sessionGetList();
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ extern void maxinfo_free_tree(MAXINFO_TREE *);
|
||||
extern void maxinfo_execute(DCB *, MAXINFO_TREE *);
|
||||
extern void maxinfo_send_error(DCB *, int, const char *);
|
||||
extern void maxinfo_send_parse_error(DCB *, char *, PARSE_ERROR);
|
||||
extern ResultSet *maxinfo_variables();
|
||||
extern ResultSet *maxinfo_status();
|
||||
extern std::unique_ptr<ResultSet> maxinfo_variables();
|
||||
extern std::unique_ptr<ResultSet> maxinfo_status();
|
||||
|
||||
#endif
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include <maxscale/maxscale.h>
|
||||
#include <maxscale/modinfo.h>
|
||||
#include <maxscale/modutil.h>
|
||||
#include <maxscale/resultset.h>
|
||||
#include <maxscale/resultset.hh>
|
||||
#include <maxscale/router.h>
|
||||
#include <maxscale/server.hh>
|
||||
#include <maxscale/service.h>
|
||||
@ -47,10 +47,13 @@
|
||||
#include <maxscale/version.h>
|
||||
|
||||
#include "../../../core/internal/maxscale.h"
|
||||
#include "../../../core/internal/modules.h"
|
||||
#include "../../../core/internal/modules.hh"
|
||||
#include "../../../core/internal/monitor.h"
|
||||
#include "../../../core/internal/poll.h"
|
||||
#include "../../../core/internal/session.h"
|
||||
#include "../../../core/internal/monitor.hh"
|
||||
#include "../../../core/internal/poll.hh"
|
||||
#include "../../../core/internal/session.hh"
|
||||
#include "../../../core/internal/server.hh"
|
||||
#include "../../../core/internal/service.hh"
|
||||
|
||||
static void exec_show(DCB *dcb, MAXINFO_TREE *tree);
|
||||
static void exec_select(DCB *dcb, MAXINFO_TREE *tree);
|
||||
@ -117,15 +120,7 @@ maxinfo_execute(DCB *dcb, MAXINFO_TREE *tree)
|
||||
static void
|
||||
exec_show_services(DCB *dcb, MAXINFO_TREE *tree)
|
||||
{
|
||||
RESULTSET *set;
|
||||
|
||||
if ((set = serviceGetList()) == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
resultset_stream_mysql(set, dcb);
|
||||
resultset_free(set);
|
||||
serviceGetList()->write(dcb);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -137,15 +132,7 @@ exec_show_services(DCB *dcb, MAXINFO_TREE *tree)
|
||||
static void
|
||||
exec_show_listeners(DCB *dcb, MAXINFO_TREE *tree)
|
||||
{
|
||||
RESULTSET *set;
|
||||
|
||||
if ((set = serviceGetListenerList()) == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
resultset_stream_mysql(set, dcb);
|
||||
resultset_free(set);
|
||||
serviceGetListenerList()->write(dcb);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,15 +144,7 @@ exec_show_listeners(DCB *dcb, MAXINFO_TREE *tree)
|
||||
static void
|
||||
exec_show_sessions(DCB *dcb, MAXINFO_TREE *tree)
|
||||
{
|
||||
RESULTSET *set;
|
||||
|
||||
if ((set = sessionGetList(SESSION_LIST_ALL)) == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
resultset_stream_mysql(set, dcb);
|
||||
resultset_free(set);
|
||||
sessionGetList()->write(dcb);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -177,15 +156,7 @@ exec_show_sessions(DCB *dcb, MAXINFO_TREE *tree)
|
||||
static void
|
||||
exec_show_clients(DCB *dcb, MAXINFO_TREE *tree)
|
||||
{
|
||||
RESULTSET *set;
|
||||
|
||||
if ((set = sessionGetList(SESSION_LIST_CONNECTION)) == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
resultset_stream_mysql(set, dcb);
|
||||
resultset_free(set);
|
||||
sessionGetList()->write(dcb);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -197,15 +168,7 @@ exec_show_clients(DCB *dcb, MAXINFO_TREE *tree)
|
||||
static void
|
||||
exec_show_servers(DCB *dcb, MAXINFO_TREE *tree)
|
||||
{
|
||||
RESULTSET *set;
|
||||
|
||||
if ((set = serverGetList()) == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
resultset_stream_mysql(set, dcb);
|
||||
resultset_free(set);
|
||||
serverGetList()->write(dcb);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -217,15 +180,7 @@ exec_show_servers(DCB *dcb, MAXINFO_TREE *tree)
|
||||
static void
|
||||
exec_show_modules(DCB *dcb, MAXINFO_TREE *tree)
|
||||
{
|
||||
RESULTSET *set;
|
||||
|
||||
if ((set = moduleGetList()) == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
resultset_stream_mysql(set, dcb);
|
||||
resultset_free(set);
|
||||
moduleGetList()->write(dcb);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -237,15 +192,7 @@ exec_show_modules(DCB *dcb, MAXINFO_TREE *tree)
|
||||
static void
|
||||
exec_show_monitors(DCB *dcb, MAXINFO_TREE *tree)
|
||||
{
|
||||
RESULTSET *set;
|
||||
|
||||
if ((set = monitor_get_list()) == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
resultset_stream_mysql(set, dcb);
|
||||
resultset_free(set);
|
||||
monitor_get_list()->write(dcb);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -257,15 +204,7 @@ exec_show_monitors(DCB *dcb, MAXINFO_TREE *tree)
|
||||
static void
|
||||
exec_show_eventTimes(DCB *dcb, MAXINFO_TREE *tree)
|
||||
{
|
||||
RESULTSET *set;
|
||||
|
||||
if ((set = eventTimesGetList()) == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
resultset_stream_mysql(set, dcb);
|
||||
resultset_free(set);
|
||||
eventTimesGetList()->write(dcb);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -845,11 +784,25 @@ static struct
|
||||
{ NULL, 0, NULL }
|
||||
};
|
||||
|
||||
typedef struct
|
||||
std::string value_to_string(int type, STATSFUNC func)
|
||||
{
|
||||
int index;
|
||||
const char *like;
|
||||
} VARCONTEXT;
|
||||
std::string value;
|
||||
|
||||
if (type == VT_STRING)
|
||||
{
|
||||
if (char* str = (char*)func())
|
||||
{
|
||||
value = str;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value = std::to_string((int64_t)func());
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function to populate rows of the show variable
|
||||
* command
|
||||
@ -857,44 +810,15 @@ typedef struct
|
||||
* @param data The context point
|
||||
* @return The next row or NULL if end of rows
|
||||
*/
|
||||
static RESULT_ROW *
|
||||
variable_row(RESULTSET *result, void *data)
|
||||
static void variable_row(std::unique_ptr<ResultSet>& set, const char* like)
|
||||
{
|
||||
VARCONTEXT *context = (VARCONTEXT *)data;
|
||||
RESULT_ROW *row;
|
||||
char buf[80];
|
||||
|
||||
if (variables[context->index].name)
|
||||
for (int i = 0; variables[i].name; i++)
|
||||
{
|
||||
if (context->like &&
|
||||
maxinfo_pattern_match(context->like,
|
||||
variables[context->index].name))
|
||||
if (!like || !maxinfo_pattern_match(like, variables[i].name))
|
||||
{
|
||||
context->index++;
|
||||
return variable_row(result, data);
|
||||
set->add_row({variables[i].name, value_to_string(variables[i].type, variables[i].func)});
|
||||
}
|
||||
row = resultset_make_row(result);
|
||||
resultset_row_set(row, 0, variables[context->index].name);
|
||||
switch (variables[context->index].type)
|
||||
{
|
||||
case VT_STRING:
|
||||
resultset_row_set(row, 1,
|
||||
(char *)(*variables[context->index].func)());
|
||||
break;
|
||||
case VT_INT:
|
||||
snprintf(buf, 80, "%ld",
|
||||
(long)(*variables[context->index].func)());
|
||||
resultset_row_set(row, 1, buf);
|
||||
break;
|
||||
default:
|
||||
ss_dassert(!true);
|
||||
}
|
||||
context->index++;
|
||||
return row;
|
||||
}
|
||||
// We only get to this point once all variables have been printed
|
||||
MXS_FREE(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -906,34 +830,9 @@ variable_row(RESULTSET *result, void *data)
|
||||
static void
|
||||
exec_show_variables(DCB *dcb, MAXINFO_TREE *filter)
|
||||
{
|
||||
RESULTSET *result;
|
||||
VARCONTEXT *context;
|
||||
|
||||
if ((context = static_cast<VARCONTEXT*>(MXS_MALLOC(sizeof(VARCONTEXT)))) == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (filter)
|
||||
{
|
||||
context->like = filter->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
context->like = NULL;
|
||||
}
|
||||
context->index = 0;
|
||||
|
||||
if ((result = resultset_create(variable_row, context)) == NULL)
|
||||
{
|
||||
maxinfo_send_error(dcb, 0, "No resources available");
|
||||
MXS_FREE(context);
|
||||
return;
|
||||
}
|
||||
resultset_add_column(result, "Variable_name", 40, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(result, "Value", 40, COL_TYPE_VARCHAR);
|
||||
resultset_stream_mysql(result, dcb);
|
||||
resultset_free(result);
|
||||
std::unique_ptr<ResultSet> set = ResultSet::create({"Variable_name", "Value"});
|
||||
variable_row(set, filter ? filter->value : NULL);
|
||||
set->write(dcb);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -941,26 +840,11 @@ exec_show_variables(DCB *dcb, MAXINFO_TREE *filter)
|
||||
*
|
||||
* @return Variables as a result set
|
||||
*/
|
||||
RESULTSET *
|
||||
maxinfo_variables()
|
||||
std::unique_ptr<ResultSet> maxinfo_variables()
|
||||
{
|
||||
RESULTSET *result;
|
||||
VARCONTEXT *context;
|
||||
if ((context = static_cast<VARCONTEXT*>(MXS_MALLOC(sizeof(VARCONTEXT)))) == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
context->like = NULL;
|
||||
context->index = 0;
|
||||
|
||||
if ((result = resultset_create(variable_row, context)) == NULL)
|
||||
{
|
||||
MXS_FREE(context);
|
||||
return NULL;
|
||||
}
|
||||
resultset_add_column(result, "Variable_name", 40, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(result, "Value", 40, COL_TYPE_VARCHAR);
|
||||
return result;
|
||||
std::unique_ptr<ResultSet> set = ResultSet::create({"Variable_name", "Value"});
|
||||
variable_row(set, NULL);
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1129,44 +1013,15 @@ static struct
|
||||
* @param data The context point
|
||||
* @return The next row or NULL if end of rows
|
||||
*/
|
||||
static RESULT_ROW *
|
||||
status_row(RESULTSET *result, void *data)
|
||||
static void status_row(std::unique_ptr<ResultSet>& set, const char* like)
|
||||
{
|
||||
VARCONTEXT *context = (VARCONTEXT *)data;
|
||||
RESULT_ROW *row;
|
||||
char buf[80];
|
||||
|
||||
if (status[context->index].name)
|
||||
for (int i = 0; status[i].name; i++)
|
||||
{
|
||||
if (context->like &&
|
||||
maxinfo_pattern_match(context->like,
|
||||
status[context->index].name))
|
||||
if (!like || !maxinfo_pattern_match(like, status[i].name))
|
||||
{
|
||||
context->index++;
|
||||
return status_row(result, data);
|
||||
set->add_row({status[i].name, value_to_string(status[i].type, status[i].func)});
|
||||
}
|
||||
row = resultset_make_row(result);
|
||||
resultset_row_set(row, 0, status[context->index].name);
|
||||
switch (status[context->index].type)
|
||||
{
|
||||
case VT_STRING:
|
||||
resultset_row_set(row, 1,
|
||||
(char *)(*status[context->index].func)());
|
||||
break;
|
||||
case VT_INT:
|
||||
snprintf(buf, 80, "%" PRId64,
|
||||
(int64_t)(*status[context->index].func)());
|
||||
resultset_row_set(row, 1, buf);
|
||||
break;
|
||||
default:
|
||||
ss_dassert(!true);
|
||||
}
|
||||
context->index++;
|
||||
return row;
|
||||
}
|
||||
// We only get to this point once all status elements have been printed
|
||||
MXS_FREE(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1175,37 +1030,11 @@ status_row(RESULTSET *result, void *data)
|
||||
* @param dcb The DCB connected to the client
|
||||
* @param filter A potential like clause or NULL
|
||||
*/
|
||||
static void
|
||||
exec_show_status(DCB *dcb, MAXINFO_TREE *filter)
|
||||
static void exec_show_status(DCB *dcb, MAXINFO_TREE *filter)
|
||||
{
|
||||
RESULTSET *result;
|
||||
VARCONTEXT *context;
|
||||
|
||||
if ((context = static_cast<VARCONTEXT*>(MXS_MALLOC(sizeof(VARCONTEXT)))) == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (filter)
|
||||
{
|
||||
context->like = filter->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
context->like = NULL;
|
||||
}
|
||||
context->index = 0;
|
||||
|
||||
if ((result = resultset_create(status_row, context)) == NULL)
|
||||
{
|
||||
maxinfo_send_error(dcb, 0, "No resources available");
|
||||
MXS_FREE(context);
|
||||
return;
|
||||
}
|
||||
resultset_add_column(result, "Variable_name", 40, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(result, "Value", 40, COL_TYPE_VARCHAR);
|
||||
resultset_stream_mysql(result, dcb);
|
||||
resultset_free(result);
|
||||
std::unique_ptr<ResultSet> set = ResultSet::create({"Variable_name", "Value"});
|
||||
status_row(set, filter ? filter->value : NULL);
|
||||
set->write(dcb);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1213,29 +1042,13 @@ exec_show_status(DCB *dcb, MAXINFO_TREE *filter)
|
||||
*
|
||||
* @return The show status data as a result set
|
||||
*/
|
||||
RESULTSET *
|
||||
maxinfo_status()
|
||||
std::unique_ptr<ResultSet> maxinfo_status()
|
||||
{
|
||||
RESULTSET *result;
|
||||
VARCONTEXT *context;
|
||||
if ((context = static_cast<VARCONTEXT*>(MXS_MALLOC(sizeof(VARCONTEXT)))) == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
context->like = NULL;
|
||||
context->index = 0;
|
||||
|
||||
if ((result = resultset_create(status_row, context)) == NULL)
|
||||
{
|
||||
MXS_FREE(context);
|
||||
return NULL;
|
||||
}
|
||||
resultset_add_column(result, "Variable_name", 40, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(result, "Value", 40, COL_TYPE_VARCHAR);
|
||||
return result;
|
||||
std::unique_ptr<ResultSet> set = ResultSet::create({"Variable_name", "Value"});
|
||||
status_row(set, NULL);
|
||||
return set;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute a select command parse tree and return the result set
|
||||
* or runtime error
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <maxscale/modutil.h>
|
||||
#include <maxscale/poll.h>
|
||||
#include <maxscale/query_classifier.h>
|
||||
#include <maxscale/resultset.hh>
|
||||
|
||||
namespace schemarouter
|
||||
{
|
||||
@ -883,24 +884,6 @@ bool detect_show_shards(GWBUF* query)
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the shard list result set creation
|
||||
*/
|
||||
RESULT_ROW* shard_list_cb(struct resultset* rset, void* data)
|
||||
{
|
||||
ServerMap* pContent = (ServerMap*)data;
|
||||
RESULT_ROW* rval = resultset_make_row(rset);
|
||||
|
||||
if (rval)
|
||||
{
|
||||
resultset_row_set(rval, 0, pContent->begin()->first.c_str());
|
||||
resultset_row_set(rval, 1, pContent->begin()->second->name);
|
||||
pContent->erase(pContent->begin());
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a result set of all shards and their locations to the client.
|
||||
* @param rses Router client session
|
||||
@ -908,22 +891,18 @@ RESULT_ROW* shard_list_cb(struct resultset* rset, void* data)
|
||||
*/
|
||||
bool SchemaRouterSession::send_shards()
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
std::unique_ptr<ResultSet> set = ResultSet::create({"Database", "Server"});
|
||||
ServerMap pContent;
|
||||
m_shard.get_content(pContent);
|
||||
RESULTSET* rset = resultset_create(shard_list_cb, &pContent);
|
||||
|
||||
if (rset)
|
||||
for (auto&& a : pContent)
|
||||
{
|
||||
resultset_add_column(rset, "Database", MYSQL_DATABASE_MAXLEN, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(rset, "Server", MYSQL_DATABASE_MAXLEN, COL_TYPE_VARCHAR);
|
||||
resultset_stream_mysql(rset, m_client);
|
||||
resultset_free(rset);
|
||||
rval = true;
|
||||
set->add_row({a.first, a.second->name});
|
||||
}
|
||||
|
||||
return rval;
|
||||
set->write(m_client);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1677,34 +1656,6 @@ enum route_target get_shard_route_target(uint32_t qtype)
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the database list streaming.
|
||||
* @param rset Result set which is being processed
|
||||
* @param data Pointer to struct string_array containing the database names
|
||||
* @return New resultset row or NULL if no more data is available. If memory allocation
|
||||
* failed, NULL is returned.
|
||||
*/
|
||||
RESULT_ROW *result_set_cb(struct resultset * rset, void *data)
|
||||
{
|
||||
RESULT_ROW *row = resultset_make_row(rset);
|
||||
std::list<std::string>* arr = (std::list<std::string>*) data;
|
||||
|
||||
if (row)
|
||||
{
|
||||
if (arr->size() > 0 && resultset_row_set(row, 0, arr->begin()->c_str()))
|
||||
{
|
||||
arr->erase(arr->begin());
|
||||
}
|
||||
else
|
||||
{
|
||||
resultset_free_row(row);
|
||||
row = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a custom SHOW DATABASES result set from all the databases in the
|
||||
* hashtable. Only backend servers that are up and in a proper state are listed
|
||||
@ -1727,15 +1678,15 @@ bool SchemaRouterSession::send_databases()
|
||||
list.push_back(db);
|
||||
}
|
||||
}
|
||||
RESULTSET* resultset = resultset_create(result_set_cb, &list);
|
||||
|
||||
if (resultset_add_column(resultset, "Database", MYSQL_DATABASE_MAXLEN,
|
||||
COL_TYPE_VARCHAR))
|
||||
std::unique_ptr<ResultSet> set = ResultSet::create({"Table"});
|
||||
|
||||
for (auto&& a : list)
|
||||
{
|
||||
resultset_stream_mysql(resultset, m_client);
|
||||
rval = true;
|
||||
set->add_row({a});
|
||||
}
|
||||
resultset_free(resultset);
|
||||
|
||||
set->write(m_client);
|
||||
|
||||
return rval;
|
||||
}
|
||||
@ -1779,18 +1730,19 @@ bool SchemaRouterSession::send_tables(GWBUF* pPacket)
|
||||
list.push_back(table);
|
||||
}
|
||||
}
|
||||
|
||||
if (!list.empty())
|
||||
{
|
||||
RESULTSET* resultset = resultset_create(result_set_cb, &list);
|
||||
std::unique_ptr<ResultSet> set = ResultSet::create({"Table"});
|
||||
|
||||
if (resultset_add_column(resultset, "Table", MYSQL_DATABASE_MAXLEN,
|
||||
COL_TYPE_VARCHAR))
|
||||
for (auto&& a : list)
|
||||
{
|
||||
resultset_stream_mysql(resultset, m_client);
|
||||
rval = true;
|
||||
set->add_row({a});
|
||||
}
|
||||
resultset_free(resultset);
|
||||
|
||||
set->write(m_client);
|
||||
}
|
||||
|
||||
MXS_FREE(query);
|
||||
return rval;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user