提供关系数据库查询服务,独立于关系数据库,只提供查询服务。
基本原理
- 按
tables.json文件的配置内容,把需要查询的数据加载到内存中。 - 按
tables.json文件配置的对象关系,在内存中建立关联关系。 - 执行
query目录下*.path文件的查询过程。
快速上手
tables.json文件
tables.json文件用于配置从数据库中加载的内容,说明如下:
path查询
query目录下存放查询内容,查询在path.yaml文件中注册。path语言的查询说明如下:
// 客户端传过来的参数声明,客户端参数按json串提供
p
// 这里`g.`表示由rust语言提供的函数,这些函数怎么提供,在设计文档里有说明
// `p.`说明取参数值。
// year函数也是rust提供的
let y = g.year
// 根据开始时间取得每个月开始及结束时间
// 前面定义的变量可以直接用,不用加前缀
let start1 = g.date_start
let end1 = g.date_end
let start2 = g.date_start
let end2 = g.date_end
// path语言的核心,沿对象路径查询
// 从t_userinfo开始,中括号里内容是过滤过程,可多次过滤
// [1..100]是取过滤后第1到100条数据,用于处理翻页
// `address.f_residential_area`就是沿一对一对象关系进行过滤了
// 点加小括号,是取过滤后的内容
// 最上层表加`db`前缀,表示取数据库表。
// p.s_address: 表示参数address的原始字符串形式,转换后的内容为p.address
// 抽取汇总及分页的公共部分, path支持把公共部分进行抽取
let search = db.t_userinfo
// path支持if语句,page_total是系统传过来的标志,看是否求汇总
if page_total else
编译并启动服务
每次修改配置文件及path程序后,都必须重新编译。为了迫使rust编译,把main程序随便改变下。运行如下命令编译:
cargo build --release
编译完成后,启动服务,把target release下的内容添加到系统path环境下,就可以运行如下命令启动服务了:
search
访问服务内容
服务通过支持post发送的postman等工具进行访问,服务内容有:
http://127.0.0.1:8000/monthgas.path:直接执行查询。http://127.0.0.1:8000/monthgas.path/n:求总和,将调用path的求总和部分。http://127.0.0.1:8000/monthgas.path/1/5:求分页内容,结构为:/查询名/页号-从1开始/每页数据
测试
为了测试不受数据库环境影响,提供了数据生成过程,测试用例编写过程如下:
tests下的数据生成文件
在tests下建立json格式的数据生成文件,说明如下:
在`src/bin.rs下添加测试用例
每个测试用例内容如下:
// 所有测试用例,统一创建一遍测试数据
initialize;
// 启动服务
let client = tracked.expect;
// 从外部传给查询的参数
let str = "{\"start\":\"2021-01-01T00:00:00\", \"end\":\"2021-12-31T23:59:59\"}");
// 执行某个查询
let response = client.post.body.dispatch;
// 检查返回状态
assert_eq!;
// 执行快照检查,如果没有快照,或者快照有问题,将产生后缀名为`.new`的快照文件。
// 检查没问题后,把`.new`后缀去掉,在运行测试过程,就通过了。
assert_snapshot!;
运行测试
命令如下:
cargo test --release
性能测试
可以对查询性能优化进行测试,测试代码在benches目录下,运行下面命令进行性能测试:
cargo bench
并发测试
bin.rs中test_update和test_update_search用来进行并发测试,正常测试不会执行,用下面命令执行。
cargo test -- --ignored
添加自己的rust函数
下一版将尝试在path程序里定义函数,形式如下:
let f x = x + 3
f
对于一些基础函数,应该在rust语言中进行添加,具体位置是src/search/database.rs文件,自己定义的函数建议添加在文件末尾。添加好后,在path程序里通过g.函数调用的方式进行调用。
支持的数据库
目前只提供了sqlserver的支持。path语言与数据库无关,数据库只用于初始数据的加载过程。这段代码在src/search/table.rs中。
数据变化处理
数据库的每个表增加s_timestamp,字段类型必须是timestamp。这种字段,在数据发生变化后,会自动增加。系统根据这个字段内容决定数据是否变化。
读写过程没有加任何锁,rust对基本数据及集合提供了线程安全的读写操作,不用加锁。
几个可能影响查询性能的考虑
- 一对一关系可能有空值,目前在选择及条件判断时,均加了空值判断,不知是否影响性能。
- 条件中的空值,转换成了默认值。字符串默认值为空串,数字型为0,日期型为0。
- 选择中的空值,返回了json的null。
- 枚举型,比如记录是否有效等,考虑按
u8形式存放,在字段声明时,把枚举的字符串列出来即可。
查询注册
所有查询全部写在query目录下,查询在path.yaml中进行注册,path.yaml中有注释说明。