该类型是SQLBuffer的灵魂,它用来表示从SQL TYPE到C++ TYPE的相互转变。该类型被定义在type_info.h中。在这个头文件中,其实定义了三个类型,其中前两个都是在mysql_type_info中所使用的utility类型。

1. mysql_ti_sql_type_info

该类型其实更多地保存mapping信息的数据结构,其核心的成员变量是

const char* sql_name_;                          // SQL类型的字符串描述,例如"TINYINT NOT NULL", "SMALLINT NOT NULL"等
const std::type_info* c_type_;              // C++ type,例如typeid(float), typeid(int)
const enum_field_types base_type_;  // SQL type, 被定义在mysql_com.h中的enum_field_types的常量,例如MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE
const unsigned int flags_;                     // 自定义标志,是tf_default、tf_null、tf_unsigned的“或”的结果

另外,该类型还提供了一些查询方法,例如

值得注意的一点是,这个类型在mysql_type_info中被typedef了,

可以看到,types[]是mysql_type_info种的一个静态数组,让我们来看一下对应的cpp文件中的定义。

顺便说一句,sql_tinyint,sql_decimal等都被typedef了(在sql_types.h中),例如sql_tinyint_unsigned其实就是tiny_int<uint8_t>,而sql_int其实就是MYSQL C API所定义的int32_t。

显然,这里的定义与我们刚才所分析的各个成员变量的作用是吻合的。

2. mysql_ti_sql_type_info_lookup

从名字上来看,这个类型是lookup   mysql_ti_sql_type_info类型(该类型在mysql_ti_sql_type_info_lookup和mysql_type_info中都被typedef为sql_type_info类型)。

其实,在这个lookup类型中,核心的东西只有一个,即

这个map说穿了,就是将C++ type(std::type_info*)与其所对应的,在刚才所说的在mysql_ti_sql_type_info中提到的types数组的下标形成对应关系。例如

上面的代码中提到的types[]中的第三个 ”TINYINT  UNSIGNED  NOT  NULL”,则,在这个map_type中,就有这样的对应pair

[ key == typeid(sql_tinyint_unsigned),  values == 2 ]

那么为什么刚才的map定义中value类型是unsigned char而不是unsigned int 呢?节约吧。

那么在mysql_type_info中到底是如何查找的呢?查看一下mysql_type_info的其中的一个构造函数就可以看到,

而lookups是什么?请看mysql_type_info中的成员变量部分,

同时,当我们查看mysql_ti_sql_type_info_lookup的构造函数,我们发现

换言之,在为static lookups进行定义的时候就已经生成了那个map。

最后,回到原来的问题,即怎么lookup法?

从mysql_type_info的上面贴出来的构造函数上来看,貌似用的是index的方法(使用operator [ ] ),的确,看了代码就是overwrite了operator [ ],在其中对这个map进行了查找,然后返回的也正是那个C++ type在表示“所有映射C++类型与SQL类型映射关系”的表(上文中的types数组)的下标索引。

3. mysql_type_info

刚才说了那么多,其实就是为了这个核心类型做准备的,文档上面说,该类型是“Used within MySQL++ for mapping SQL types to C++ types and vice versa”。从刚才的分析上来看,SQL TYPE就是在原生MYSQL C API中所定义的enum_field_types中的内容(被定义在MySQL Connector C 6.1 6.1.2\include\mysql_com.h中),而C++ types就是原生态的C++数据类型(int ,long, short等),还有MYSQL++自己定义的数据结构(struct或者class),比如tiny<T>,NULL<T>等。

具体来说,mysql_type_info如何做到“SQL types to C++ types and vice versa”的?关键在与看构造函数

  • SQL Type –> C++ type

  • C++ type –> SQLType

上面的lookups[t]之前已经介绍过了,现在来看一些type( )的实现

还是遍历types数组(上文中反复提到的表示“所有映射C++类型与SQL类型映射关系”的表)啊!

那么,这种信息到底是怎么被存储的?从构造函数上来看,貌似只是一个num_,也就是只是保存了types数组的下标而已。其实也很容易理解,types数组是一个静态的变量,一直在保存全局变量的section里面(具体叫什么已经忘记了……以前在《程序猿的自我修养》里面有见过),所以保存个下标即可。

再来一个问题,刚才只说了,如果构造这个mysql_type_info,那么还是没有说清楚如何“SQL types to C++ types and vice versa”,下面来说一下当mysql_type_info被构造完成,要开始具体用的时候该如何使用了。

  • SQL type –> C++ type
  1. 先使用构造器mysql_type_info(enum_field_type, …)构造出mysql_type_info
  2. 调用mysql_type_info:: c_type( )

该函数只有一句话,即return  *(types[num_].c_type_)。还记得types是mysql_ti_sql_type_info类型的数组嘛?回到第一点就什么都清楚了。

  • C++ type –> SQL type
  1. 先使用构造器mysql_type_info(const std::type_info& t)构造出mysql_type_info
  2. 调用mysql_type_info:: base_type( )

该函数只有一句话,即return  mysql_type_info(types[num_].base_type_)。为什么又是return一个mysql_type_info?不是说好的SQL type吗?我估计作者的用意是尽可能避免外部知道这个SQL type,所以尽所能隐藏它。同时在这个mysql_type_info:: base_type( )的注释里我们可以看到这样的话。

Returns the type_info for the C++ type inside the mysqlpp::Null type.  If the type is not Null then this is the same as c_type().

这句话什么意思?让我们再来看看base_type( )中所调用的mysql_type_info的一个构造函数

这样我就懂作者那句英文的意思了。

最后一个问题,在escape和quote中,如何判断一个mysql_type_info类型是需要quote还是需要escape?

【原创】5. MYSQL++ mysql_type_info类型的更多相关文章

  1. 【原创】MYSQL++源码剖析——前言与目录

    终于完成了! 从第一次想写到现在真的写好大概花了我3个月时间.原来一直读人家的系列文章,总感慨作者的用心良苦和无私奉献,自己在心里总是会觉得有那么些冲动也来写一个. 最开始的麻烦是犹豫该选哪个主题.其 ...

  2. 数据库索引原理,及MySQL索引类型(转)

    在数据库表中,对字段建立索引可以大大提高查询速度.假如我们创建了一个 mytable表: CREATE TABLE mytable( ID INT NOT NULL, username ) NOT N ...

  3. MySQL索引类型总结和使用技巧以及注意事项

    索引是快速搜索的关键.MySQL索引的建立对于MySQL的高效运行是很重要的.下面介绍几种常见的MySQL索引类型 在数据库表中,对字段建立索引可以大大提高查询速度.假如我们创建了一个 mytable ...

  4. 详解mysql int类型的长度值问题【转】

    mysql在建表的时候int类型后的长度代表什么? 是该列允许存储值的最大宽度吗? 为什么我设置成int(1), 也一样能存10,100,1000呢. 当时我虽然知道int(1),这个长度1并不代表允 ...

  5. MySQL数据类型 int(M) 表示什么意思?详解mysql int类型的长度值问题

    MySQL 数据类型中的 integer types 有点奇怪.你可能会见到诸如:int(3).int(4).int(8) 之类的 int 数据类型.刚接触 MySQL 的时候,我还以为 int(3) ...

  6. MySQL服务 - MySQL列类型、SQL模式、数据字典

    MySQL列类型的作用: 列类型可以简单理解为用来对用户往列种存储数据时做某种范围"限定",它可以定义数据的有效值(字符.数字等).所能占据的最大存储空间.字符长度(定长或变长). ...

  7. MySQL服务 - MySQL变量类型及变量设置

    一.MySQL变量类型: MySQL通过变量来定义当前服务器的特性,保存状态信息等.我们可以通过手动更改变量的值来配置MySQL,也可以通过变量获得MySQL的当前状态信息.MySQL的变量类型可以从 ...

  8. MySQL表类型和存储引擎版本不一致解决方法

    使用的是老版本的mysql客户端Navicate 8 ,mysql 服务端用的是mysql5.6的版本,在修改版本引擎的时候出现版本不对; mysql error ‘TYPE=MyISAM’ 解决办法 ...

  9. mysql 日期类型比较

    MySQL 日期类型:日期格式.所占存储空间.日期范围 比较. 日期类型        存储空间       日期格式                 日期范围 ------------ ------ ...

随机推荐

  1. WWDC 2017, 让我们看看 iTunesConnect 有了哪些不同

    距离 WWDC 2017 过去已经有 7 天了,小伙伴们是不是已经发现我们的苹果后台和之前的界面有些略微的不同,如果有心的朋友下了 iOS 11 beta 版就会发现设备上的 App Store 界面 ...

  2. Delphi for Android (aka Delphi XE5 aka RAD Studio XE5) has appeared

    Delphi for Android (aka Delphi XE5 aka RAD Studio XE5) has appeared   Blimey, that took me by surpri ...

  3. 为什么选择MpVue进行小程序的开发

    前言 mpvue是一款使用Vue.js开发微信小程序的前端框架.使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为H5和小程序提供了代码复用的能力.如果想将 H5 项目改造为小程序,或开发 ...

  4. myeclipse三个地方的java版本统一

    1 java build path 2 java compiler 3 Myeclipse -> project facets

  5. 迭代器.NET实现—IEnumerable和IEnumerator (foreach实现)

    能用foreach遍历访问的对象需要实现什么接口或声明什么方法的类型? 答案:能用foreach遍历访问的对象必须是集合或数组对象,而这些都是靠实现超级接口IEnumerable或被声明 GetEnu ...

  6. throw、try 和 catch

    try 语句允许我们定义在执行时进行错误测试的代码块. catch 语句允许我们定义当 try 代码块发生错误时,所执行的代码块. JavaScript 语句 try 和 catch 是成对出现的. ...

  7. 【ASP.NET Web API2】Digest认证

    Digest摘要认证 对于Basic认证方案来说,被传输的认证凭证仅仅采用Base64编码,所以包含密码的认证凭证基本上可以视为明文传输.Digest认证在此基础上进行了改善,在一定程度上提高了安全系 ...

  8. Spring AOP声明式事务异常回滚

    近日测试用例,发现这样一个现象:在业务代码中,有如下两种情况,比如:throw new RuntimeException("xxxxxxxxxxxx"); 事物回滚throw ne ...

  9. Ctrl+H 浪潮Raid配置文档

    说明 本手册适用于LSI芯片Raid卡 包括但不限于Inspur 2008/2108 Raid卡.LSI 9240/9260/9261/9271 等Raid卡. 不同型号的Raid卡在某些功能上的支持 ...

  10. ui-router 1.0以上的 $stateChangeStart

    ui-router transitionhooks 统一控制路由跳转, 前台控制如果没有登录就跳转到登录页面, 当然也可以在后台控制, 如果没有登录就返回对应的错误码, 然后在response中直接跳 ...