From ec420332ea513af9c1ced27acbfaf9a5ce1045bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 31 Jul 2018 10:03:07 +0300 Subject: [PATCH] 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. --- server/core/gateway.cc | 2 +- server/core/internal/modules.hh | 2 +- server/core/internal/monitor.hh | 2 +- server/core/internal/{poll.h => poll.hh} | 10 +- server/core/internal/server.hh | 2 +- server/core/internal/service.hh | 4 +- server/core/internal/session.hh | 2 +- server/core/load_utils.cc | 95 ++---- server/core/monitor.cc | 61 +--- server/core/poll.cc | 90 +----- server/core/routingworker.cc | 2 +- server/core/server.cc | 78 +---- server/core/service.cc | 169 ++-------- server/core/session.cc | 102 +----- server/core/test/test_utils.h | 2 +- server/core/test/test_worker.cc | 2 +- server/core/worker.cc | 2 +- .../filter/test/maxscale/mock/backend.hh | 6 +- server/modules/filter/test/mock_backend.cc | 32 +- server/modules/protocol/HTTPD/httpd.cc | 4 +- server/modules/routing/binlogrouter/blr.h | 4 +- server/modules/routing/debugcli/debugcmd.cc | 2 +- server/modules/routing/maxinfo/maxinfo.cc | 152 +-------- server/modules/routing/maxinfo/maxinfo.h | 4 +- .../modules/routing/maxinfo/maxinfo_exec.cc | 299 ++++-------------- .../schemarouter/schemaroutersession.cc | 88 ++---- 26 files changed, 216 insertions(+), 1002 deletions(-) rename server/core/internal/{poll.h => poll.hh} (87%) diff --git a/server/core/gateway.cc b/server/core/gateway.cc index f8f984e95..8046c1d91 100644 --- a/server/core/gateway.cc +++ b/server/core/gateway.cc @@ -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" diff --git a/server/core/internal/modules.hh b/server/core/internal/modules.hh index 40ca2efd5..32e41bd4a 100644 --- a/server/core/internal/modules.hh +++ b/server/core/internal/modules.hh @@ -21,4 +21,4 @@ * * @return A Result set */ -ResultSet *moduleGetList(); +std::unique_ptr moduleGetList(); diff --git a/server/core/internal/monitor.hh b/server/core/internal/monitor.hh index e8f579047..5bc96a358 100644 --- a/server/core/internal/monitor.hh +++ b/server/core/internal/monitor.hh @@ -20,4 +20,4 @@ #include -ResultSet *monitor_get_list(); +std::unique_ptr monitor_get_list(); diff --git a/server/core/internal/poll.h b/server/core/internal/poll.hh similarity index 87% rename from server/core/internal/poll.h rename to server/core/internal/poll.hh index 64dd9db56..aa2c316f1 100644 --- a/server/core/internal/poll.h +++ b/server/core/internal/poll.hh @@ -13,15 +13,13 @@ */ /** - * @file core/maxscale/poll.h - The private poll interface + * The private poll header */ +#include #include - #include -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 eventTimesGetList(); diff --git a/server/core/internal/server.hh b/server/core/internal/server.hh index 35e8d5bda..379f2a700 100644 --- a/server/core/internal/server.hh +++ b/server/core/internal/server.hh @@ -18,4 +18,4 @@ #include -ResultSet* serverGetList(); +std::unique_ptr serverGetList(); diff --git a/server/core/internal/service.hh b/server/core/internal/service.hh index 40b727ed6..b53aa38ce 100644 --- a/server/core/internal/service.hh +++ b/server/core/internal/service.hh @@ -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 serviceGetList(void); +std::unique_ptr serviceGetListenerList(void); diff --git a/server/core/internal/session.hh b/server/core/internal/session.hh index 25039941d..fe87f2459 100644 --- a/server/core/internal/session.hh +++ b/server/core/internal/session.hh @@ -40,4 +40,4 @@ struct RegistryTraits } -ResultSet *sessionGetList(); +std::unique_ptr sessionGetList(); diff --git a/server/core/load_utils.cc b/server/core/load_utils.cc index 0fe49eef0..4268c9f7d 100644 --- a/server/core/load_utils.cc +++ b/server/core/load_utils.cc @@ -15,8 +15,6 @@ * @file load_utils.c Utility functions for loading of modules */ -#include "internal/modules.h" - #include #include #include @@ -40,7 +38,7 @@ #include #include -#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& 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 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 set = ResultSet::create({"Module Name", "Module Type", "Version", "API Version", "Status"}); + moduleRowCallback(set); return set; } diff --git a/server/core/monitor.cc b/server/core/monitor.cc index e426dc8f6..30731e224 100644 --- a/server/core/monitor.cc +++ b/server/core/monitor.cc @@ -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 monitor_get_list() { - RESULTSET *set; - int *data; + std::unique_ptr 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; } diff --git a/server/core/poll.cc b/server/core/poll.cc index 4ef27c06b..1e9982f1c 100644 --- a/server/core/poll.cc +++ b/server/core/poll.cc @@ -35,7 +35,7 @@ #include #include #include -#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 eventTimesGetList() { - RESULTSET *set; - EVENT_TIMES_CB_DATA *data; + std::unique_ptr 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; } diff --git a/server/core/routingworker.cc b/server/core/routingworker.cc index 843d6964c..3aa33b56b 100644 --- a/server/core/routingworker.cc +++ b/server/core/routingworker.cc @@ -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" diff --git a/server/core/server.cc b/server/core/server.cc index 6e3345eb9..6e8cc685f 100644 --- a/server/core/server.cc +++ b/server/core/server.cc @@ -42,7 +42,7 @@ #include #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 serverGetList() { - RESULTSET *set; - int *data; + std::unique_ptr 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; } diff --git a/server/core/service.cc b/server/core/service.cc index 011366cde..a80322397 100644 --- a/server/core/service.cc +++ b/server/core/service.cc @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include #include #include @@ -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 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 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 serviceGetList() { - RESULTSET *set; - int *data; + std::unique_ptr 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; } diff --git a/server/core/session.cc b/server/core/session.cc index 4dc8d7a69..feb9b065e 100644 --- a/server/core/session.cc +++ b/server/core/session.cc @@ -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(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 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 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) { diff --git a/server/core/test/test_utils.h b/server/core/test/test_utils.h index 2f54ee436..b60cd128f 100644 --- a/server/core/test/test_utils.h +++ b/server/core/test/test_utils.h @@ -26,7 +26,7 @@ #include -#include "../internal/poll.h" +#include "../internal/poll.hh" #include "../internal/routingworker.hh" #include "../internal/statistics.h" diff --git a/server/core/test/test_worker.cc b/server/core/test/test_worker.cc index ceecbd573..b354d47c3 100644 --- a/server/core/test/test_worker.cc +++ b/server/core/test/test_worker.cc @@ -13,7 +13,7 @@ #include #include -#include "../internal/poll.h" +#include "../internal/poll.hh" using namespace maxscale; using namespace std; diff --git a/server/core/worker.cc b/server/core/worker.cc index 06b8f4057..61cb58201 100644 --- a/server/core/worker.cc +++ b/server/core/worker.cc @@ -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" diff --git a/server/modules/filter/test/maxscale/mock/backend.hh b/server/modules/filter/test/maxscale/mock/backend.hh index f5b4099ec..d77439479 100644 --- a/server/modules/filter/test/maxscale/mock/backend.hh +++ b/server/modules/filter/test/maxscale/mock/backend.hh @@ -14,7 +14,7 @@ #include #include -#include +#include #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; }; diff --git a/server/modules/filter/test/mock_backend.cc b/server/modules/filter/test/mock_backend.cc index fc624b64e..50986decb 100644 --- a/server/modules/filter/test/mock_backend.cc +++ b/server/modules/filter/test/mock_backend.cc @@ -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 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(pThis)->create_row(pResult_set); -} - } // mock } // maxscale diff --git a/server/modules/protocol/HTTPD/httpd.cc b/server/modules/protocol/HTTPD/httpd.cc index 19e074d39..f1367ac7f 100644 --- a/server/modules/protocol/HTTPD/httpd.cc +++ b/server/modules/protocol/HTTPD/httpd.cc @@ -40,7 +40,7 @@ #include #include #include -#include +#include #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); diff --git a/server/modules/routing/binlogrouter/blr.h b/server/modules/routing/binlogrouter/blr.h index cf836fd02..f80794723 100644 --- a/server/modules/routing/binlogrouter/blr.h +++ b/server/modules/routing/binlogrouter/blr.h @@ -35,6 +35,7 @@ #include #include #include +#include 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 diff --git a/server/modules/routing/debugcli/debugcmd.cc b/server/modules/routing/debugcli/debugcmd.cc index f884ae3c1..6776a9baa 100644 --- a/server/modules/routing/debugcli/debugcmd.cc +++ b/server/modules/routing/debugcli/debugcmd.cc @@ -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" diff --git a/server/modules/routing/maxinfo/maxinfo.cc b/server/modules/routing/maxinfo/maxinfo.cc index 2cbdeb19c..43fa9d56b 100644 --- a/server/modules/routing/maxinfo/maxinfo.cc +++ b/server/modules/routing/maxinfo/maxinfo.cc @@ -45,9 +45,9 @@ #include #include #include -#include +#include #include -#include +#include #include #include #include @@ -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 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 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 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 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(); } diff --git a/server/modules/routing/maxinfo/maxinfo.h b/server/modules/routing/maxinfo/maxinfo.h index ea27c7757..f410380f7 100644 --- a/server/modules/routing/maxinfo/maxinfo.h +++ b/server/modules/routing/maxinfo/maxinfo.h @@ -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 maxinfo_variables(); +extern std::unique_ptr maxinfo_status(); #endif diff --git a/server/modules/routing/maxinfo/maxinfo_exec.cc b/server/modules/routing/maxinfo/maxinfo_exec.cc index 2ebb43fd2..24d615b3f 100644 --- a/server/modules/routing/maxinfo/maxinfo_exec.cc +++ b/server/modules/routing/maxinfo/maxinfo_exec.cc @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include #include @@ -47,10 +47,13 @@ #include #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& 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(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 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 maxinfo_variables() { - RESULTSET *result; - VARCONTEXT *context; - if ((context = static_cast(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 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& 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(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 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 maxinfo_status() { - RESULTSET *result; - VARCONTEXT *context; - if ((context = static_cast(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 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 diff --git a/server/modules/routing/schemarouter/schemaroutersession.cc b/server/modules/routing/schemarouter/schemaroutersession.cc index d8064d397..435d524d7 100644 --- a/server/modules/routing/schemarouter/schemaroutersession.cc +++ b/server/modules/routing/schemarouter/schemaroutersession.cc @@ -21,6 +21,7 @@ #include #include #include +#include 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 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* arr = (std::list*) 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 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 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; }