polardbxengine/plugin/polarx_rpc/coders/notices.cc

106 lines
2.7 KiB
C++

//
// Created by zzy on 2022/9/5.
//
#include <string>
#include <vector>
#include "callback_command_delegate.h"
#include "protocol_fwd.h"
#include "notices.h"
namespace polarx_rpc {
namespace {
class CwarningResultset final {
private:
using Row = CcallbackCommandDelegate::Row_data;
using Field = CcallbackCommandDelegate::Field_value;
using Field_list = std::vector<Field *>;
CpolarxEncoder &encoder_;
const bool skip_single_error_;
CcallbackCommandDelegate delegate_;
Row row_;
std::string last_error_;
uint32_t num_errors_{0u};
using Warning = ::Polarx::Notice::Warning;
Row *start_row() {
row_.clear();
return &row_;
}
static inline Warning::Level get_warning_level(const std::string &level) {
static const char *const ERROR_STRING = "Error";
static const char *const WARNING_STRING = "Warning";
if (level == WARNING_STRING)
return Warning::WARNING;
if (level == ERROR_STRING)
return Warning::ERROR;
return Warning::NOTE;
}
bool end_row(Row *row) {
if (!last_error_.empty()) {
encoder_.message_encoder().encode_notice(
::Polarx::Notice::Frame_Type_WARNING,
::Polarx::Notice::Frame_Scope_LOCAL, last_error_);
last_error_.clear();
}
Field_list &fields = row->fields;
if (fields.size() != 3)
return false;
const Warning::Level level = get_warning_level(*fields[0]->value.v_string);
Warning warning;
warning.set_level(level);
warning.set_code(
static_cast<google::protobuf::uint32>(fields[1]->value.v_long));
warning.set_msg(*fields[2]->value.v_string);
std::string data;
warning.SerializeToString(&data);
if (level == Warning::ERROR) {
++num_errors_;
if (skip_single_error_ && (num_errors_ <= 1)) {
last_error_ = data;
return true;
}
}
encoder_.message_encoder().encode_notice(
::Polarx::Notice::Frame_Type_WARNING,
::Polarx::Notice::Frame_Scope_LOCAL, data);
return true;
}
public:
CwarningResultset(CpolarxEncoder &encoder, const bool skip_single_error)
: encoder_(encoder), skip_single_error_(skip_single_error),
delegate_(std::bind(&CwarningResultset::start_row, this),
std::bind(&CwarningResultset::end_row, this,
std::placeholders::_1)) {}
inline CcommandDelegate &delegate() { return delegate_; }
};
} // namespace
err_t send_warnings(CsessionBase &session, CpolarxEncoder &encoder,
bool skip_single_error) {
static const std::string q = "SHOW WARNINGS";
CwarningResultset resultset(encoder, skip_single_error);
// send warnings as notices
return session.execute_sql(q.data(), q.length(), resultset.delegate());
}
} // namespace polarx_rpc