需求: 解析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即可.
测试代码链接: https://download.csdn.net/download/chijingjing/11212216