From b8702b8d95f702a8028b5bb0c8a8fda1639718a9 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Fri, 16 Jun 2017 15:36:13 +0300 Subject: [PATCH] MXS-1249: Add function for getting the "version" of a service The behaviour of the query classifier needs to change depending on the version of the servers of a service. With this function "some" version of the service can be obtained. --- include/maxscale/service.h | 25 +++++++++++ server/core/service.cc | 87 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) diff --git a/include/maxscale/service.h b/include/maxscale/service.h index b641ebe2d..3437ba841 100644 --- a/include/maxscale/service.h +++ b/include/maxscale/service.h @@ -355,4 +355,29 @@ static inline uint64_t service_get_capabilities(const SERVICE *service) return service->capabilities; } +typedef enum service_version_which_t +{ + SERVICE_VERSION_ANY, /*< Any version of the servers of a service. */ + SERVICE_VERSION_MIN, /*< The minimum version. */ + SERVICE_VERSION_MAX, /*< The maximum version. */ +} service_version_which_t; + +/** + * Return the version of the service. The returned version can be + * + * - the version of any (in practice the first) server associated + * with the service, + * - the smallest version of any of the servers associated with + * the service, or + * - the largest version of any of the servers associated with + * the service. + * + * @param service The service. + * @param which Which version. + * @param version On output contains the version of the service. + */ +void service_get_version(const SERVICE *service, + service_version_which_t which, + SERVER_VERSION* version); + MXS_END_DECLS diff --git a/server/core/service.cc b/server/core/service.cc index e7ced7df0..545420286 100644 --- a/server/core/service.cc +++ b/server/core/service.cc @@ -2673,3 +2673,90 @@ json_t* service_relations_to_server(const SERVER* server, const char* host) return rel; } + +void service_get_version(const SERVICE *service, + service_version_which_t which, + SERVER_VERSION* version) +{ + if (which == SERVICE_VERSION_ANY) + { + SERVER_REF* sref = service->dbref; + + while (sref && !sref->active) + { + sref = sref->next; + } + + if (sref) + { + *version = sref->server->version; + } + else + { + version->major = version->minor = version->patch = 0; + } + } + else + { + size_t n = 0; + + SERVER_VERSION v; + + if (which == SERVICE_VERSION_MIN) + { + v.major = UINT32_MAX; + v.minor = UINT32_MAX; + v.patch = UINT32_MAX; + } + else + { + ss_dassert(which == SERVICE_VERSION_MAX); + + v.major = 0; + v.minor = 0; + v.patch = 0; + } + + SERVER_REF* sref = service->dbref; + + while (sref) + { + if (sref->active) + { + ++n; + + SERVER* s = sref->server; + + if (which == SERVICE_VERSION_MIN) + { + if ((s->version.major < v.major) || + ((s->version.major == v.major) && (s->version.minor < v.minor)) || + ((s->version.major == v.major) && (s->version.minor == v.minor) && + (s->version.patch < v.patch))) + { + v = s->version; + } + } + else + { + if ((s->version.major > v.major) || + ((s->version.major == v.major) && (s->version.minor > v.minor)) || + ((s->version.major == v.major) && (s->version.minor == v.minor) && + (s->version.patch > v.patch))) + { + v = s->version; + } + } + } + + sref = sref->next; + } + + if (n == 0) + { + v.major = v.minor = v.patch = 0; + } + + *version = v; + } +}