實現一套 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. 大小寫敏感。
相關文章
相關標籤/搜索