【原创】5. MYSQL++ mysql_type_info类型
该类型是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
- 先使用构造器mysql_type_info(enum_field_type, …)构造出mysql_type_info
- 调用mysql_type_info:: c_type( )
该函数只有一句话,即return *(types[num_].c_type_)。还记得types是mysql_ti_sql_type_info类型的数组嘛?回到第一点就什么都清楚了。
- C++ type –> SQL type
- 先使用构造器mysql_type_info(const std::type_info& t)构造出mysql_type_info
- 调用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类型的更多相关文章
- 【原创】MYSQL++源码剖析——前言与目录
终于完成了! 从第一次想写到现在真的写好大概花了我3个月时间.原来一直读人家的系列文章,总感慨作者的用心良苦和无私奉献,自己在心里总是会觉得有那么些冲动也来写一个. 最开始的麻烦是犹豫该选哪个主题.其 ...
- 数据库索引原理,及MySQL索引类型(转)
在数据库表中,对字段建立索引可以大大提高查询速度.假如我们创建了一个 mytable表: CREATE TABLE mytable( ID INT NOT NULL, username ) NOT N ...
- MySQL索引类型总结和使用技巧以及注意事项
索引是快速搜索的关键.MySQL索引的建立对于MySQL的高效运行是很重要的.下面介绍几种常见的MySQL索引类型 在数据库表中,对字段建立索引可以大大提高查询速度.假如我们创建了一个 mytable ...
- 详解mysql int类型的长度值问题【转】
mysql在建表的时候int类型后的长度代表什么? 是该列允许存储值的最大宽度吗? 为什么我设置成int(1), 也一样能存10,100,1000呢. 当时我虽然知道int(1),这个长度1并不代表允 ...
- MySQL数据类型 int(M) 表示什么意思?详解mysql int类型的长度值问题
MySQL 数据类型中的 integer types 有点奇怪.你可能会见到诸如:int(3).int(4).int(8) 之类的 int 数据类型.刚接触 MySQL 的时候,我还以为 int(3) ...
- MySQL服务 - MySQL列类型、SQL模式、数据字典
MySQL列类型的作用: 列类型可以简单理解为用来对用户往列种存储数据时做某种范围"限定",它可以定义数据的有效值(字符.数字等).所能占据的最大存储空间.字符长度(定长或变长). ...
- MySQL服务 - MySQL变量类型及变量设置
一.MySQL变量类型: MySQL通过变量来定义当前服务器的特性,保存状态信息等.我们可以通过手动更改变量的值来配置MySQL,也可以通过变量获得MySQL的当前状态信息.MySQL的变量类型可以从 ...
- MySQL表类型和存储引擎版本不一致解决方法
使用的是老版本的mysql客户端Navicate 8 ,mysql 服务端用的是mysql5.6的版本,在修改版本引擎的时候出现版本不对; mysql error ‘TYPE=MyISAM’ 解决办法 ...
- mysql 日期类型比较
MySQL 日期类型:日期格式.所占存储空间.日期范围 比较. 日期类型 存储空间 日期格式 日期范围 ------------ ------ ...
随机推荐
- js实现把中文、英文标点转换
所有英文符号转换成中文的符号 <SCRIPT LANGUAGE="JavaScript"> <!-- function meizz(str) { var tmp ...
- 重读tcp-ip详解三卷:1
应用层 Http.Telnet.FTP和e-mail等 负责把数据传输到传输层或接收从传输层返回的数据传输层 TCP和UDP 主要为两台主机上的应用程序提供端到端的通信,TCP为两台主机提供高可靠性的 ...
- struts2.5框架使用通配符指定方法,某一个匹配不到
在学习struts框架时经常会使用到通配符调用方法,如下:但奇怪的是,在validateName请求老报404,其他的都是ok的,开始以为是配置错了,检查好久才知道: <action name= ...
- 设计模式之桥接(bridge)模式
在现实生活中,我们常常会用到两种或多种类型的笔,比如毛笔和蜡笔.假设我们需要大.中.小三种类型的画笔来绘制12中不同的颜色,如果我们使用蜡笔,需要准备3*12=36支.但如果使用毛笔的话,只需要提供3 ...
- CSS书写格式
转自: https://segmentfault.com/a/1190000005046830 CSS书写格式 1.格式化代码 1.1文件 [建议]:CSS文件使用无BOM的UTF-8编码 1.2缩进 ...
- LibreOJ β Round #2 题解
LibreOJ β Round #2 题解 模拟只会猜题意 题目: 给定一个长为 \(n\) 的序列,有 \(m\) 次询问,每次问所有长度大于 \(x\) 的区间的元素和的最大值. \(1 \leq ...
- jQuery火箭图标返回顶部代码
在网上找来段使用jQuery火箭图标返回顶部代码,感觉比较酷,比较炫,大概样式如下, 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1. ...
- 自定义标签2.x
2.x只需要继承SimpleTagSupport 1.x 输出流 JspWriter out = pageContext.getOut(); 2.x 输出流 JspWriter out = get ...
- erlang 应用获取系统参数
很多时候,我们的程序需要一些预定义的参数,比如上次说的tcp_server的例子 一般参数有几种途径,具体参考这里http://blog.yufeng.info/archives/2852 app里面 ...
- ISO模型的七个分层
要想理解socket首先得熟悉一下TCP/IP协议族, TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,定义了主 ...