接上篇,本篇说下SQL转换
// where 实现没那么智能
select 5,max(8) from a where 5 not like '%css%' group by 5 order by 1 desc
SQL拆单词有点复杂这里就不说了
接着说下初始代码,目的是把sql变为上面的链式
//关键词节点的链式(类似状态机)
//默认是start->select(from where group ...)-from(where group ...)
private StatusNode currentStatus = null;
//SQL语句解析词放在list里面
private Iterator<String> words = null;
public void start() throws Exception {
while(words.hasNext()) {
String word = null;
//给状态节点一直喂word
//当前节点是否完成了,默认第一次start不走
while (words.hasNext() && !currentStatus.isSaturated()) {
word = words.next();
try {
log.info("feed :" + currentStatus + " with '" + word + "'");
//feed里有数据校验的
//然后设置到对应的链式中
currentStatus.feed(word, this);
} catch (FeedException e) {
String error = ExceptionUtil.makeLQLErrorMsgForStateMachine(lql, word, e.getMessage());
throw new InvalidLQLException(error);
}
}
//喂饱之后 指的是当前的节点 切换到下一个节点
if (words.hasNext()) {
if (!currentStatus.isWordOverflow()) {
word = words.next();
}
//当前的关键字语句;完成一个后获取下一个关键字语句
currentStatus = currentStatus.next(word);
log.info("switch by '" + word + "' to :" + currentStatus);
if(currentStatus==null){
throw new InvalidLQLException("unexpected '"+word+"'");
}
}
}
//结束解析
currentStatus.endup(this);
//判断节点完整性 例如必须有 select from
if(!currentStatus.isSaturated()){
throw new InvalidLQLException("uncompleted value for " + currentStatus);
}
if(!this.getResult().isSaturated()){
throw new InvalidLQLException("uncompleted lql!");
}
}
分析下select关键字
public class SelectNode extends AbstractNode<LogQueryLanguageParserStateMachine> {
static Logger log = Logger.getLogger(SelectNode.class.getName());
public SelectNode() {
super("select");
}
@Override
public void feed(String word, StateMachine<LogQueryLanguageParserStateMachine> stateMachine) throws FeedException {
LogQueryLanguageParserStateMachine machine = stateMachine.get();
//得到数据并且校验内容
word = getInnerString(word);
for(String prop : word.split(",")){
prop = getInnerString(prop);
//assertNumber(prop);
}
//格式OK,将select的字段设置到解析结果中
//设置到链式中
machine.getResult().setSelect(word);
//表明当前节点已经处理完毕
saturated = true;
log.info("set SELECT as " + word);
}
}