Reorganize MariaDBServer code

The server-class keeps growing, so the additional classes are moved out of
the main class file.
This commit is contained in:
Esa Korhonen
2018-10-04 17:56:49 +03:00
parent 7e7ee3e180
commit 68d65682b5
10 changed files with 548 additions and 547 deletions

View File

@ -26,15 +26,6 @@ using maxscale::string_printf;
using maxbase::Duration;
using maxbase::StopWatch;
namespace
{
// Used for Slave_IO_Running
const char YES[] = "Yes";
const char PREPARING[] = "Preparing";
const char CONNECTING[] = "Connecting";
const char NO[] = "No";
}
class MariaDBServer::EventInfo
{
public:
@ -2046,190 +2037,3 @@ bool MariaDBServer::redirect_existing_slave_conn(ClusterOperation& op)
} // 'stop_slave_conn' prints its own errors
return success;
}
string SlaveStatus::to_string() const
{
// Print all of this on the same line to make things compact. Are the widths reasonable? The format is
// not quite array-like since usually there is just one row. May be changed later.
// Form the components of the line.
string host_port = string_printf("[%s]:%d", master_host.c_str(), master_port);
string running_states = string_printf("%s/%s",
slave_io_to_string(slave_io_running).c_str(),
slave_sql_running ? "Yes" : "No");
string rval = string_printf(
" Host: %22s, IO/SQL running: %7s, Master ID: %4" PRId64 ", Gtid_IO_Pos: %s, R.Lag: %d",
host_port.c_str(),
running_states.c_str(),
master_server_id,
gtid_io_pos.to_string().c_str(),
seconds_behind_master);
return rval;
}
string SlaveStatus::to_short_string(const string& owner) const
{
if (name.empty())
{
return string_printf("Slave connection from %s to [%s]:%i",
owner.c_str(), master_host.c_str(), master_port);
}
else
{
return string_printf("Slave connection '%s' from %s to [%s]:%i",
name.c_str(), owner.c_str(), master_host.c_str(), master_port);
}
}
json_t* SlaveStatus::to_json() const
{
json_t* result = json_object();
json_object_set_new(result, "connection_name", json_string(name.c_str()));
json_object_set_new(result, "master_host", json_string(master_host.c_str()));
json_object_set_new(result, "master_port", json_integer(master_port));
json_object_set_new(result,
"slave_io_running",
json_string(slave_io_to_string(slave_io_running).c_str()));
json_object_set_new(result, "slave_sql_running", json_string(slave_sql_running ? "Yes" : "No"));
json_object_set_new(result,
"seconds_behing_master",
seconds_behind_master == MXS_RLAG_UNDEFINED ? json_null() :
json_integer(seconds_behind_master));
json_object_set_new(result, "master_server_id", json_integer(master_server_id));
json_object_set_new(result, "last_io_or_sql_error", json_string(last_error.c_str()));
json_object_set_new(result, "gtid_io_pos", json_string(gtid_io_pos.to_string().c_str()));
return result;
}
SlaveStatus::slave_io_running_t SlaveStatus::slave_io_from_string(const std::string& str)
{
slave_io_running_t rval = SLAVE_IO_NO;
if (str == YES)
{
rval = SLAVE_IO_YES;
}
// Interpret "Preparing" as "Connecting". It's not quite clear if the master server id has been read
// or if server versions between master and slave have been checked, so better be on the safe side.
else if (str == CONNECTING || str == PREPARING)
{
rval = SLAVE_IO_CONNECTING;
}
else if (str != NO)
{
MXS_ERROR("Unexpected value for Slave_IO_Running: '%s'.", str.c_str());
}
return rval;
}
string SlaveStatus::slave_io_to_string(SlaveStatus::slave_io_running_t slave_io)
{
string rval;
switch (slave_io)
{
case SlaveStatus::SLAVE_IO_YES:
rval = YES;
break;
case SlaveStatus::SLAVE_IO_CONNECTING:
rval = CONNECTING;
break;
case SlaveStatus::SLAVE_IO_NO:
rval = NO;
break;
default:
mxb_assert(!false);
}
return rval;
}
QueryResult::QueryResult(MYSQL_RES* resultset)
: m_resultset(resultset)
{
if (m_resultset)
{
auto columns = mysql_num_fields(m_resultset);
MYSQL_FIELD* field_info = mysql_fetch_fields(m_resultset);
for (int64_t column_index = 0; column_index < columns; column_index++)
{
string key(field_info[column_index].name);
// TODO: Think of a way to handle duplicate names nicely. Currently this should only be used
// for known queries.
mxb_assert(m_col_indexes.count(key) == 0);
m_col_indexes[key] = column_index;
}
}
}
QueryResult::~QueryResult()
{
if (m_resultset)
{
mysql_free_result(m_resultset);
}
}
bool QueryResult::next_row()
{
mxb_assert(m_resultset);
m_rowdata = mysql_fetch_row(m_resultset);
if (m_rowdata)
{
m_current_row_ind++;
return true;
}
return false;
}
int64_t QueryResult::get_current_row_index() const
{
return m_current_row_ind;
}
int64_t QueryResult::get_col_count() const
{
return m_resultset ? mysql_num_fields(m_resultset) : -1;
}
int64_t QueryResult::get_row_count() const
{
return m_resultset ? mysql_num_rows(m_resultset) : -1;
}
int64_t QueryResult::get_col_index(const string& col_name) const
{
auto iter = m_col_indexes.find(col_name);
return (iter != m_col_indexes.end()) ? iter->second : -1;
}
string QueryResult::get_string(int64_t column_ind) const
{
mxb_assert(column_ind < get_col_count() && column_ind >= 0);
char* data = m_rowdata[column_ind];
return data ? data : "";
}
int64_t QueryResult::get_uint(int64_t column_ind) const
{
mxb_assert(column_ind < get_col_count() && column_ind >= 0);
char* data = m_rowdata[column_ind];
int64_t rval = -1;
if (data && *data)
{
errno = 0; // strtoll sets this
char* endptr = NULL;
auto parsed = strtoll(data, &endptr, 10);
if (parsed >= 0 && errno == 0 && *endptr == '\0')
{
rval = parsed;
}
}
return rval;
}
bool QueryResult::get_bool(int64_t column_ind) const
{
mxb_assert(column_ind < get_col_count() && column_ind >= 0);
char* data = m_rowdata[column_ind];
return data ? (strcmp(data, "Y") == 0 || strcmp(data, "1") == 0) : false;
}