在mysql中添加新源文件,以及 如何…

本文主要介绍如何在mysql 中添加新的源文件以及如何在客户端打印列表信息。 这两个内容没有必然的联系,这里放在一起介绍主要是因为这两个功能我是一起尝试的。

 

1. 添加新源文件

mysql5.5的编译是基于cmake来进行的, 所以当添加新的源文件的时候,需要在对应源码目录的cmake配置文件CMakeList.txt中添加新源文件的信息。

本例中添加的新文件是gaoshow.h 和gaoshow.cc, 它们都在sql源码目录下。

编辑sql源码目录下的CMakeList.txt,大约第39行处找到变量定义 “SET(SQL_SHARED_SOURCES” 在其后的列表的末尾添加gaoshow.cc (cmake中只需要添加.cc文件,不需要添加.h头文件)。

 

2. 添加“客户端打印列表信息”的功能

这个功能基于之前的博文 《如何在修改mysql代码添加新命令》:http://hi.baidu.com/gao1738/blog/item/716e1aeb3e0a5a0b6c22eb46.html。

在《如何在修改mysql代码添加新命令》中我添加了一条新的命令"DISPATCH ADD", 现在在该命令的命令处理代码处:

sql_parse.cc中的 “mysql_execute_command”函数中的“case SQLCOM_DISPATCH_ADD:”。具体修改后的处理代码如下:

if (!strcmp(lex->dispatch_message, "gao"))
     
       global_system_variables.node_type=1;
       show_dispatch_info(thd,lex->dispatch_message);
       //my_ok(thd);
       my_eof(thd);                              //注:这里一定要用
my_eof(thd)来结束, 而不能用my_ok(thd),否则执行该命令的过程中

                                                          // mysql会卡死在哪

                                                         // 但如果这条命令没有向客户端发送数据的话  就用 my_ok(thd)

                                                          // 具体的解释可以查看sql/sql_class.cc的3111行。 当服务端发送数据的metadata到客户端之后

                                                          // 客户端总是期待服务端发送的数据集以 "eof" 或 “error packet” 结尾。

     

show_dispatch_info” 函数定义在新填的源文件中:

这个头文件需要在sql_parse.cc中被include

#ifndef GAO_SHOW
#define GAO_SHOW
bool show_dispatch_info(THD *thd, char *message);
#endif

#include "sql_parse.h"
#include "gaoshow.h"
#include <my_dir.h>

bool show_dispatch_info(THD *thd, char *message)
{
  Protocol *protocol= thd->protocol;
  DBUG_ENTER("show_dispatch_info");

  List<Item> field_list;

  field_list.push_back(new Item_empty_string("message", 255));   //注:这里是设置表头
  field_list.push_back(new Item_return_int("num",20,MYSQL_TYPE_LONGLONG));
//注:这里是设置表头
  if (protocol->send_result_set_metadata(&field_list,
                                         Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
    DBUG_RETURN(TRUE);
  protocol->prepare_for_resend();
  protocol->store(message,&my_charset_bin);  
//注:这里是设置表头对应的值, 按顺序一一对应
  protocol->store((ulonglong)10);                         //注:这里是设置表头对应的值, 按顺序一一对应
  if (protocol->write())
    DBUG_RETURN(TRUE);
  else
    DBUG_RETURN(FALSE);

}

 

3.  测试:

这里我们直接使用《如何在修改mysql代码添加新命令》中定义的测试用例, 执行结果如下:

==============================================================================

TEST                                                                          RESULT    TIME (ms) or COMMENT
--------------------------------------------------------------------------

worker[1] Using MTR_BUILD_THREAD 300, with reserved ports 13000..13009
DISPATCH ADD gao;
message      num
gao      10
show variables like 'node_type';
Variable_name      Value
node_type      1
main.gao                                                                [ pass ]          1
 

4. 打印多行数据

打印多行的过程和打印一行很类似, 也是通过protocol对象, 也是先设置并发送数据的metadata, 然后一行一行发送,发送具体一行的代码可以参考sql/sql_class.cc中1895行的send_data函数。 下面是一个简单的实例:

bool show_dispatch_info(THD *thd, const char *message)
{
  Protocol *protocol= thd->protocol; 
  DBUG_ENTER("show_dispatch_info");
  List<Item> field_list;                          //用这个list存放metadata
  field_list.push_back(new Item_empty_string("message", 255));                                                            //这里是设置metadata
  field_list.push_back(new Item_return_int("Position",20,MYSQL_TYPE_LONGLONG)); //这里是设置metadata
  if (protocol->send_result_set_metadata(&field_list,                                                                                                              //向客户端发送要显示的metadata
                                                                                Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
      DBUG_RETURN(TRUE);

  List<Item> items;                                           //这个list用来存放每一行的数据

  items.push_back(new Item_string(message, strlen(message), system_charset_info));   //放第一个数据项

                                                                 //注这里的message中的值 如果你不是在这个命令使用,而是要保存到以后的命令中使用,

                                                            //那么需要把它深拷贝到 另一块new的内存中。 因为lex中的对象在这条语句结束后就释放了。

  items.push_back(new Item_int(10));                                                                                          //放第二个数据项
  send_row_data(items, protocol, thd);                                                          //这个函数在下面定义了
  items.delete_elements();                                                                                              //清空以发送的数据,以便存下一条数据
  items.push_back(new Item_string("end", strlen("end"), system_charset_info));
  items.push_back(new Item_int(0));
  send_row_data(items, protocol, thd);
  items.delete_elements();
  items.push_back(new Item_string("end", strlen("end"), system_charset_info));
  items.push_back(new Item_int(0));
  send_row_data(items, protocol, thd);
  DBUG_RETURN(TRUE);
}

bool send_row_data(List<Item> l, Protocol *p, THD *thd)
{

  DBUG_ENTER("show_row_data");                //对于每个函数这个必须放在第一行, 它告诉debuger进入了一个新的用户函数,并且在栈中

                                                                        //分配空间保存之前的调用信息, 如果没有这句话后面的DBUG_RETURN 会有问题

  p->prepare_for_resend();                                                      //准备发送数据
  if (p->send_result_set_row(&l))                                    //设置要送发的数据
{
      p->remove_last_row();
      DBUG_RETURN(TRUE);
  }
  thd->sent_row_count++;                                                       
  if (p->write())                                                                                          //向客户端发送数据
      DBUG_RETURN(TRUE);
  else
      DBUG_RETURN(FALSE);
}

 

5. 多行数据的测试

DISPATCH ADD gao;                      //这个是执行的命令
message      Position
gao      10
end      0
end      0
DISPATCH ADD xiao;                  //这个是执行的命令
message      Position
delete      10
end      0
end      0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值