package com.taobao.tddl.optimizer.parse.cobar; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; import com.alibaba.cobar.parser.ast.stmt.SQLStatement; import com.alibaba.cobar.parser.recognizer.SQLParserDelegate; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.taobao.tddl.common.TddlConstants; import com.taobao.tddl.common.model.lifecycle.AbstractLifecycle; import com.taobao.tddl.optimizer.exceptions.SqlParserException; import com.taobao.tddl.optimizer.parse.SqlAnalysisResult; import com.taobao.tddl.optimizer.parse.SqlParseManager; /** * 基于cobar解析器实现parse */ public class CobarSqlParseManager extends AbstractLifecycle implements SqlParseManager { private int cacheSize = 1000; private long expireTime = TddlConstants.DEFAULT_OPTIMIZER_EXPIRE_TIME; private static Cache<String, SQLStatement> cache = null; @Override protected void doInit() { cache = CacheBuilder.newBuilder() .maximumSize(cacheSize) .expireAfterWrite(expireTime, TimeUnit.MILLISECONDS) .build(); } @Override protected void doDestory() { cache.invalidateAll(); } @Override public SqlAnalysisResult parse(final String sql, boolean cached) throws SqlParserException { SQLStatement statement = null; try { // 只缓存sql的解析结果 if (cached) { statement = cache.get(sql, new Callable<SQLStatement>() { @Override public SQLStatement call() throws Exception { return SQLParserDelegate.parse(sql); } }); } else { statement = SQLParserDelegate.parse(sql); } } catch (Exception e) { if (e.getCause() instanceof RuntimeException) { throw (RuntimeException) e.getCause(); } else { throw new SqlParserException("You have an error in your SQL syntax,the sql is:" + sql, e); } } // AstNode visitor结果不能做缓存 CobarSqlAnalysisResult result = new CobarSqlAnalysisResult(); result.build(sql, statement); return result; } public void setCacheSize(int cacheSize) { this.cacheSize = cacheSize; } public void setExpireTime(long expireTime) { this.expireTime = expireTime; } }