需求: 解析sql語句中where字句條件解析生成解析對象(解析對象直接成對象)
實現方式: C++的sql解析可以去mysql,sqllite 等開源軟件中去尋找, 但是這些都是很複雜,並且很難改造,自己通過GDAL的ogr模塊中找到了GDAL基於swq的實現,但是依賴太重,遂做了部分改造完成功能.
首先還是放使用樣例:
#include "stdafx.h"
#include "swq.h"
swq_custom_func_registrar *poCustomFuncRegistrar;
void *pSWQExpr;
int main()
{
//const char* wherestr = "ACOL > 1 AND ACOL < 5 ";
const char* wherestr = "not acol in (1,2,4,9)";
std::vector<char*> fields_list = { "ACOL" ,"ACOL", "CCOL" };
swq_field_type fdtypes[3] = { SWQ_INTEGER ,SWQ_INTEGER64 ,SWQ_STRING };
int book = swq_expr_compile(wherestr, 3, &(fields_list[0]), fdtypes, 1, poCustomFuncRegistrar,
reinterpret_cast<swq_expr_node **>(&pSWQExpr));
swq_expr_node* vvv = static_cast<swq_expr_node*>(pSWQExpr);
FILE* pf = 0;
fopen_s(&pf,"D:\\a.txt", "wb+");
vvv->Dump(pf, 5);
fclose(pf);
return 0;
}
以上接口就是輸入sql,列集合,類型,生成了解析對象,所有解析完成的對象存放於swq_expr_node,此對象有成員 swq_expr_node **papoSubExpr; 存儲子節點.此對象類似一個樹性結構可以將所有where字句的條件內容嵌套分割爲一個node的鏈表, 例如:
const char* wherestr1 = "ACOL > 1 AND ACOL < 5 ";
const char* wherestr = "(acol not in (1,2,4,9)) and CCOL != 'sdf'";
wherestr1: 如下:
wherestr2的sql node 結構如下:
其中每個藍色節點都是一個swq_expr_node對象, 通過swq_expr_compile接口函數獲得的爲根節點, 每個節點都有對應的類型 ,
typedef enum {
SNT_CONSTANT, //常熟值, 需要sql比較的值
SNT_COLUMN, //列 記錄列的節點
SNT_OPERATION //操作類型 ,如 and or not in < > 等
} swq_node_type;
每種類型又可以對應不同的處理, 至此已經可以把SQL完全解析出來, 此庫常見sql都能解析出來. 此庫在nosql 數據庫使用sql查詢,文件類型的數據庫上有一定用,可以把標準的sql轉爲條件比較,至於如何使用這個生成好的對象,這個需要根據具體業務來出來即可,普通比較調用Evaluate方法,特殊對象比較,例如數據庫中BLOB自定義對象需要用戶實現自定義回調 ,創建傳入swq_custom_func_registrar即可.