一次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即可.

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