一次C++ SQL解析庫封裝改造

需求: 解析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即可.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章