现在的位置: 首页 > 综合 > 正文

MySQL复制数据时判断是否要做字符集转换函数

2014年01月24日 ⁄ 综合 ⁄ 共 2142字 ⁄ 字号 评论关闭

在服务器和客户端设置相同的字符集对程序运行的影响如下:

bool Protocol::net_store_data(const
uchar *from,
size_t length,

                              CHARSET_INFO *from_cs,
CHARSET_INFO *to_cs)

{

  uint dummy_errors;

  /* Calculate
maxumum possible result length */

  uint conv_length= to_cs->mbmaxlen * length
/ from_cs->mbminlen;

  if (conv_length > 250)

  {

    /*

      For strings with conv_length greater than
250 bytes

      we don't know how many bytes we will need
to store length: one or two,

      because we don't know result length until
conversion is done.

      For example, when converting from utf8
(mbmaxlen=3) to latin1,

      conv_length=300 means that the result
length can vary between 100 to 300.

      length=100 needs one byte, length=300
needs to bytes.

     

      Thus conversion directly to
"packet" is not worthy.

      Let's use "convert" as a temporary
buffer.

    */

    return (convert->copy((const char*) from, length, from_cs,

                          to_cs, &dummy_errors)
||

            net_store_data((const uchar*) convert->ptr(),
convert->length()));

  }

Copy函数如下:

bool String::copy(const char *str, uint32 arg_length,

               
CHARSET_INFO *from_cs, CHARSET_INFO *to_cs, uint *errors)

{

  uint32 offset;

 

  DBUG_ASSERT(!str || str != Ptr);

 

  if (!needs_conversion(arg_length,
from_cs, to_cs,
&offset))//
判断是否需要转换,哪种情况不需要转换呢,稍后显示

  {

    *errors=
0;//
复制数据到目标缓冲区

    return copy(str, arg_length, to_cs);

  }

  if ((from_cs == &my_charset_bin)
&& offset)//
如果不能直接复制,下面就是要对字符进行转换后重新复制,这中间当然会浪费时间,为什么不能够复制呢,因为不同的字符集之间同一字符占用的字节数都是不一样的,如果强制复制当然会造成乱码的了。

  {

    *errors=
0;

    return copy_aligned(str,
arg_length, offset,
to_cs);

  }

  uint32 new_length= to_cs->mbmaxlen*arg_length;

  if (alloc(new_length))

    return TRUE;

  str_length=copy_and_convert((char*)
Ptr, new_length,
to_cs,

                              str, arg_length,
from_cs, errors);

  str_charset=to_cs;

  return FALSE;

}

 

下面的用于判断是否需要转换的函数

bool String::needs_conversion(uint32
arg_length,

                           CHARSET_INFO
*from_cs,

                           CHARSET_INFO
*to_cs,

                           uint32
*offset)

{

  *offset=
0;

  if (!to_cs ||

      (to_cs
== &my_charset_bin) ||

      (to_cs
== from_cs) ||

      my_charset_same(from_cs, to_cs)
||

      ((from_cs
== &my_charset_bin) &&

       (!(*offset=(arg_length % to_cs->mbminlen)))))

    return FALSE;

  return TRUE;

}


下班了 MySQL自己封装的字符串应该要好好看看,在文件sql_string.hsql_string.cc

抱歉!评论已关闭.