mysql_communicator.h 2.6 KB
Newer Older
羽飞's avatar
羽飞 已提交
1
/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved.
羽飞's avatar
羽飞 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */

//
// Created by Wangyunlai on 2022/11/22.
//

#pragma once

#include "net/communicator.h"

class SqlResult;
class BasePacket;

/**
 * 与客户端通讯
 * 实现MySQL通讯协议
 * 可以参考 https://dev.mysql.com/doc/dev/mysql-server/latest/PAGE_PROTOCOL.html
 * 或 mariadb文档 https://mariadb.com/kb/en/clientserver-protocol/
 */
class MysqlCommunicator : public Communicator {
public:
  /**
   * 连接刚开始建立时,进行一些初始化
   * 参考MySQL或MariaDB的手册,服务端要首先向客户端发送一个握手包,等客户端回复后,
   * 再回复一个OkPacket或ErrPacket
   */
  virtual RC init(int fd, Session *session, const std::string &addr) override;

  /**
   * 有新的消息到达时,接收消息
   * 因为MySQL协议的特殊性,收到数据后不一定需要向后流转,比如握手包
   */
  virtual RC read_event(SessionEvent *&event) override;

  /**
   * 将处理结果返回给客户端
   */
  virtual RC write_result(SessionEvent *event, bool &need_disconnect) override;

private:
  RC send_packet(const BasePacket &packet);
  RC write_state(SessionEvent *event, bool &need_disconnect);

  /**
   * 根据MySQL text protocol 描述,普通的结果分为列信息描述和行数据
   * 这里就分为两个函数
   */
  RC send_column_definition(SqlResult *sql_result, bool &need_disconnect);
羽飞's avatar
羽飞 已提交
57
  RC send_result_rows(SqlResult *sql_result, bool no_column_def, bool &need_disconnect);
羽飞's avatar
羽飞 已提交
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

  /**
   * 根据实际测试,客户端在连接上来时,会发起一个 version_comment的查询
   * 这里就针对这个查询返回一个结果
   */
  RC handle_version_comment(bool &need_disconnect);

private:
  //! 握手阶段(鉴权),需要做一些特殊处理,所以加个字段单独标记
  bool authed_ = false;

  //! 有时需要根据握手包中capabilities字段值的不同,而发送或接收不同的包
  uint32_t client_capabilities_flag_ = 0;

  //! 在一次通讯过程中(一个任务的请求与处理),每个包(packet)都有一个sequence id
  //! 这个sequence id是递增的
  int8_t sequence_id_ = 0;
};