实现一套 mysql 于 c++ 和 C# 的辅助代码构建工具及库

因业务须要,又开始折腾 mysql. 由于须要在 c+, c#下面访问它,故但愿实现一些 helper 以简化开发过程。mysql

目标:c++

1.简化开发过程,编码过程当中对于“表”,“字段” 等,具有智能感知的能力sql

2.编译期错误检查数据库

3.c++, c# 具备极其相似的编程体验(语法,函数调用方式及流程大体相同)。编程

4.跨 c++, c# 的数据互通(方便异构平台相互通讯)。c#

5.简单提高硬件利用率(实现相似 IOCP 运做机制的 mysql 执行池,从指令队列获取 sql 任务,执行完后 发起通知/回调,或是将结果输出到某队列容器)windows

 

就目标1来讲,这个应该是须要作一套 mysql 表 到 c++/c# 的代码结构的自动映射机,拿 c# winform 结合一套查 mysql 系统库的语句,拼拼 StringBuilder,转转义,映射些个数据类型,应该没啥问题。感受上难点应该是出如今跨语言的结构设计上。两种语言有各自实现相似效果的方式。api

为实现目标2,这一般要求全部 sql 语句拼接过程当中,凡是出现表名,字段名的地方,都要用 枚举,函数 之类的替代。服务器

目标3就彻底是编码长像设计问题了,须要设计出一套跨这两种语言的,长像差很少的,用起来也差很少的独特语法。而且须要有助于提高工做效率(简化开发过程才是最终目标,不可背离)数据结构

目标4 意味着 须要本身设计各类数据结构的序列化,反序列化(至少须要支持平常开发中最经常使用的那些数据类型),以及一套通用容器(万用查询结果容器)

目标5 是多线程应用,每一个线程有一个本身的数据库链接并保持。线程数应该是可设的。默承认以采起 cpu * 2 之类的公式来获得。

 

先随意设计一下使用效果代码:

c#

var s = Select.Gen( "select ", T1.C1, T2.C1, " from ", Ts.T1, Ts.T2 );
Console.WriteLine( s );

将输出

select t1.c1, t2.c1 from t1, t2  (由于数据库里面有 t1, t2 表,它们有 c1, c2 之类的字段名)

 

c++

Select::Gen gen;
gen, "select ", T1::C1, T2::C1, " from ", Ts::T1, Ts::T2;
cout << gen << endl;

输出同上

 

 

 

看了下 mysql 官方的 Connector c++ ,感受不大好用(文档,示例不够丰富,我更是见不得它用 try 机制)

因此仍是决定本身来简单的封装一些基础类啥的比较好,基于 mysql c api 来作,感受比较靠谱。

粗读了一下 mysql c api 参考手册,试翻译一些看上去可能会用到的东西:

 

mysql c api 函数集:


MYSQL *mysql_real_connect(
    MYSQL *mysql
    , const char *host
    , const char *user
    , const char *passwd
    , const char *db
    , unsigned int port
    , const char *unix_socket
    , unsigned long client_flag
)

该函数试图创建到 host 所在 mysql 数据库的链接。
成立创建链接后,获得一个合法的 mysql 结构体,才能调用其余 API 函数。

第一个参数是经过调用 mysql_init() 初始化一个 MYSQL 结构体而得来的。
而且你还能够经过调用 mysql_options() 来设置一些链接选项。

host 参数: 须传入主机名或 ip 地址。
若是传入空值或 "localhost" 字串,将链接本机
windows 下若是服务器开启了共享内存访问,则连建立将以此做为通讯方式。不然将使用 tcp/ip
unix 下将使用 unix socket file. 
windows 下若是传入 "." 表示使用命名管道(若是此链接方式未开启,将报错)


user 参数:包含用户登陆 id. 若是传 null"", 将使用当前用户.
unix 下,这意味着使用当前的登陆名。
windows ODBC 模式,当前用户名必须显式指定。

password 参数:包含用户登陆密码。
若是传入 空值,除非用户表中用户也具有一个空值密码才能匹配。
如此一来,系统管理员能够根据 是否设置了密码 来设置不一样的权限。
注意:调用该函数前,密码不要加密(该过程经由 client API 自动进行)

user & password 可以使用任何为 mysql 配置的字符集。默认为 latin1。
可是在链接前,能够用 mysql_options( mysql, MYSQL_SET_CHARSET_NAME, "charset_name" ) 来改。

db 参数:库名。若是不为 空,链接将以此做为默认库。

port 参数:若是用的 tcp/ip 链接,传入 非 0 值,将指定所链接的端口号。

unix_socket 参数:若是不为空,该字串用于指定使用 socket 或命名管道。注意, host 参数决定链接类型。

client_flag 参数:一般为 0, 可是能够设置组合标记位来启用某些特性/功能。
    CAN_HANDLE_EXPIRED_PASSWORDS    客户端能够处理过时密码
    CLIENT_COMPRESS                 使用压缩协议
    CLIENT_FOUND_ROWS               返回 “匹配行数” 而非 “受影响行数”
    CLIENT_IGNORE_SIGPIPE           阻止客户端库安装 SIGPIPE 处理器,以免和已安装的发生冲突。
    CLIENT_IGNORE_SPACE             容许函数名后面加空格。全部函数名能够预留字。
    CLIENT_INTERACTIVE              容许关闭链接前使用 不活动超时秒数 (代替等待超时秒数)。客户端会话的 等待超时秒数 值设置为 不活动超时秒数。
    CLIENT_LOCAL_FILES              启用 载入本地文件数据 处理(高速批量导入数据用)。
    CLIENT_MULTI_RESULTS            告诉服务器 客户端能够处理 多语句 或 存储过程 返回的 多数据集结果。若是 CLIENT_MULTI_STATEMENTS 标志位启用,这个标志位也自动启用。
    CLIENT_MULTI_STATEMENTS         告诉服务器 客户端 可能会 一次性发送 由 ";" 分号分割开的 多条语句。若是不设置该标志位,一次执行多条语句功能 将被禁用。
    CLIENT_NO_SCHEMA                不容许使用 数据库名.表名.列名 语法。这是关于 ODBC 的设置。若是这样用,会报错,这样有助于某些 odbc 程序找 bug。
    CLIENT_SSL                      使用 SSL 加密协议。此设置不该该在程序里设置。它应该在客户端库内设置。能够在调用 mysql_real_connect 前调用 mysql_ssl_set 来代替。
    CLIENT_REMEMBER_OPTIONS         记住经过调用 mysql_options 设置的选项。若是不设置这个标志位, mysql_real_connect 建立链接失败的话,就得从新调用 mysql_options 来从新设置那些选项。若是设置了这个标志位,那就没必要再调用 mysql_options 了。




MYSQL *mysql_init( MYSQL *mysql )

为建立链接而 分配, 初始化 一个 mysql 结构体。
若是参数 "mysql" 为 空值,将返回一个新对象;
不然初始化 mysql 指向的对象并返回。

注意:当返回一个新对象时,调用 mysql_close() 函数关闭链接时将致使该对象释放。





void mysql_close( MYSQL *mysql )

关闭一个已打开的链接。若是 mysql 结构体经由 mysql_init() 建立(返回新对象),
该对象将被释放。





int mysql_options( MYSQL *mysql, enum mysql_option option, const void *arg )

用来设置额外的链接选项和影响行为。能够屡次调用以实现多项设置。
调用时机:mysql_init 以后,mysql_real_connect 以前。
返回 0 表示操做成功,非 0 表示未知选项。

常见参数列表:
    MYSQL_INIT_COMMAND (argument type: char *) 
        SQL 指令段落会于链接建立成功后自动执行(当从新链接事件发生时也会自动执行)
        可指定使用哪一张网卡来链接服务器(多网卡环境)。
        参数为 主机名 或 IP 地址 字串(mysql 5.6.1. 起开始支持)

    MYSQL_OPT_COMPRESS (argument: not used) 
        使用压缩的客户端/服务器协议。

    MYSQL_OPT_CONNECT_TIMEOUT (argument type: unsigned int *) 
        设置链接超时秒数

    MYSQL_OPT_NAMED_PIPE (argument: not used) 
        使用 命名管道 来连服务器(Windows),若是服务器容许的话。

    MYSQL_OPT_PROTOCOL (argument type: unsigned int *) 
        指定使用的协议(枚举:位于 mysql.h 中的 mysql_protocol_type)
        当前有下列几个:
        MYSQL_PROTOCOL_DEFAULT, 
        MYSQL_PROTOCOL_TCP, 
        MYSQL_PROTOCOL_SOCKET,
        MYSQL_PROTOCOL_PIPE, 
        MYSQL_PROTOCOL_MEMORY

    MYSQL_OPT_READ_TIMEOUT (argument type: unsigned int *) 
        设置从服务器读等待超时时间。每次尝试使用这个超时值,若是有必要的话,可能会重试 net_retry_count 次。故总等待时间会 net_retry_count 倍于设置值。
        你能够设置这个值,以便获得一个比 TCP/IP Close_Wait_Timeout 的 10 分钟更提早的超时检测。

        这个超时机制可能并不能在全部平台上实施。有些读取操做不会致使客户端读取超时。例如,服务器一直在等待 “磁盘满” 状态消失。

    MYSQL_OPT_RECONNECT (argument type: my_bool *) 
        设置启用或禁用自动重连(若是发现链接断开)。默认禁用。该选项提供一个明确设置该行为的渠道。

    MYSQL_OPT_WRITE_TIMEOUT (argument type: unsigned int *) 
        大致同 MYSQL_OPT_READ_TIMEOUT,读变写
    
    MYSQL_SET_CHARSET_NAME (argument type: char *) 
        设置默认字符集. 参数能够是 MYSQL_AUTODETECT_CHARSET_NAME 从而使用与当前操做系统相同的设定.

    MYSQL_SHARED_MEMORY_BASE_NAME (argument type: char *) 
        windows 下, 设置 用于链接到 服务器的 共享内存的 “名字”(若是服务器支持共享内存方式链接的话)
        服务器端使用 --shared-memory-base-name 选项来指定。默认值为 MYSQL. 大小写敏感。
相关文章
相关标签/搜索