mysql type class_【原创】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的“或”的结果

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

5e0dc14e81909f52e885c11d4ad289ec.png

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

f513086b12dc81882f4f50940db5fe50.png

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

b966c85102d3ec85c62d5f79bd8b62d1.png

顺便说一句,sql_tinyint,sql_decimal等都被typedef了(在sql_types.h中),例如sql_tinyint_unsigned其实就是tiny_int,而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类型中,核心的东西只有一个,即

9609655e63c0ccde1763f223ce647246.png

这个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的其中的一个构造函数就可以看到,

e40e6d0d5743956f49d105c598b168d6.png

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

914a998c8e21faed52bc61fa6a9f673a.png

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

cf76a1f818060d460885d3ca9323e86a.png

换言之,在为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,NULL等。

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

SQL Type –> C++ type

d84b8e6eeef7bccdadf622fb70ae2bf8.png

C++ type –> SQLType

452a300353119b7ba998ac96565e4ff0.png

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

0aa290083026d74c273d4a7904c5217a.png

还是遍历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的一个构造函数

24f71b3c647760f0d35ee18a985d2b25.png

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

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

9091d3db338dec7b1db5b444cbe3da24.png

4b7b16ae4b8078e0127f7f9c18d770ae.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值