abstractqueryrouter.java
来自「mysql集群」· Java 代码 · 共 963 行 · 第 1/3 页
JAVA
963 行
/*
* This program is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either version 3 of the License,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package com.meidusa.amoeba.route;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.commons.collections.map.LRUMap;
import org.apache.log4j.Logger;
import org.apache.log4j.helpers.LogLog;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import com.meidusa.amoeba.parser.dbobject.Column;
import com.meidusa.amoeba.parser.statment.CommitStatment;
import com.meidusa.amoeba.parser.statment.DMLStatment;
import com.meidusa.amoeba.parser.statment.PropertyStatment;
import com.meidusa.amoeba.parser.statment.RollbackStatment;
import com.meidusa.amoeba.parser.statment.StartTansactionStatment;
import com.meidusa.amoeba.parser.function.Function;
import com.meidusa.amoeba.parser.dbobject.Schema;
import com.meidusa.amoeba.parser.statment.Statment;
import com.meidusa.amoeba.parser.dbobject.Table;
import com.meidusa.amoeba.parser.expression.Expression;
import com.meidusa.amoeba.sqljep.function.Abs;
import com.meidusa.amoeba.sqljep.function.AddDate;
import com.meidusa.amoeba.sqljep.function.AddMonths;
import com.meidusa.amoeba.sqljep.function.AddTime;
import com.meidusa.amoeba.sqljep.function.Case;
import com.meidusa.amoeba.sqljep.function.Ceil;
import com.meidusa.amoeba.sqljep.function.Comparative;
import com.meidusa.amoeba.sqljep.function.ComparativeBaseList;
import com.meidusa.amoeba.sqljep.function.Concat;
import com.meidusa.amoeba.sqljep.function.Datediff;
import com.meidusa.amoeba.sqljep.function.Day;
import com.meidusa.amoeba.sqljep.function.DayName;
import com.meidusa.amoeba.sqljep.function.DayOfWeek;
import com.meidusa.amoeba.sqljep.function.DayOfYear;
import com.meidusa.amoeba.sqljep.function.Decode;
import com.meidusa.amoeba.sqljep.function.Floor;
import com.meidusa.amoeba.sqljep.function.Hash;
import com.meidusa.amoeba.sqljep.function.Hour;
import com.meidusa.amoeba.sqljep.function.IndistinctMatching;
import com.meidusa.amoeba.sqljep.function.Initcap;
import com.meidusa.amoeba.sqljep.function.Instr;
import com.meidusa.amoeba.sqljep.function.LastDay;
import com.meidusa.amoeba.sqljep.function.Length;
import com.meidusa.amoeba.sqljep.function.Lower;
import com.meidusa.amoeba.sqljep.function.Lpad;
import com.meidusa.amoeba.sqljep.function.Ltrim;
import com.meidusa.amoeba.sqljep.function.MakeDate;
import com.meidusa.amoeba.sqljep.function.MakeTime;
import com.meidusa.amoeba.sqljep.function.Microsecond;
import com.meidusa.amoeba.sqljep.function.Minute;
import com.meidusa.amoeba.sqljep.function.Modulus;
import com.meidusa.amoeba.sqljep.function.Month;
import com.meidusa.amoeba.sqljep.function.MonthName;
import com.meidusa.amoeba.sqljep.function.MonthsBetween;
import com.meidusa.amoeba.sqljep.function.NextDay;
import com.meidusa.amoeba.sqljep.function.Nvl;
import com.meidusa.amoeba.sqljep.function.PostfixCommand;
import com.meidusa.amoeba.sqljep.function.Power;
import com.meidusa.amoeba.sqljep.function.Replace;
import com.meidusa.amoeba.sqljep.function.Round;
import com.meidusa.amoeba.sqljep.function.Rpad;
import com.meidusa.amoeba.sqljep.function.Rtrim;
import com.meidusa.amoeba.sqljep.function.Second;
import com.meidusa.amoeba.sqljep.function.Sign;
import com.meidusa.amoeba.sqljep.function.SubDate;
import com.meidusa.amoeba.sqljep.function.SubTime;
import com.meidusa.amoeba.sqljep.function.Substring;
import com.meidusa.amoeba.sqljep.function.ToChar;
import com.meidusa.amoeba.sqljep.function.ToDate;
import com.meidusa.amoeba.sqljep.function.ToNumber;
import com.meidusa.amoeba.sqljep.function.Translate;
import com.meidusa.amoeba.sqljep.function.Trim;
import com.meidusa.amoeba.sqljep.function.Trunc;
import com.meidusa.amoeba.sqljep.function.Upper;
import com.meidusa.amoeba.sqljep.function.WeekOfYear;
import com.meidusa.amoeba.sqljep.function.Year;
import com.meidusa.amoeba.sqljep.variable.Variable;
import com.meidusa.amoeba.config.BeanObjectEntityConfig;
import com.meidusa.amoeba.config.ConfigurationException;
import com.meidusa.amoeba.config.DocumentUtil;
import com.meidusa.amoeba.context.ProxyRuntimeContext;
import com.meidusa.amoeba.net.DatabaseConnection;
import com.meidusa.amoeba.net.poolable.ObjectPool;
import com.meidusa.amoeba.parser.ParseException;
import com.meidusa.amoeba.parser.Parser;
import com.meidusa.amoeba.sqljep.RowJEP;
import com.meidusa.amoeba.util.Initialisable;
import com.meidusa.amoeba.util.InitialisationException;
import com.meidusa.amoeba.util.StringUtil;
/**
*
* @author struct
*
*/
public abstract class AbstractQueryRouter implements QueryRouter, Initialisable{
private static Logger logger = Logger.getLogger(AbstractQueryRouter.class);
final public static Map<String, PostfixCommand> ruleFunTab = new HashMap<String,PostfixCommand>();
static{
ruleFunTab.put("abs", new Abs());
ruleFunTab.put("power", new Power());
ruleFunTab.put("mod", new Modulus());
ruleFunTab.put("substr", new Substring());
ruleFunTab.put("sign", new Sign());
ruleFunTab.put("ceil", new Ceil());
ruleFunTab.put("floor", new Floor());
ruleFunTab.put("trunc", new Trunc());
ruleFunTab.put("round", new Round());
ruleFunTab.put("length", new Length());
ruleFunTab.put("concat", new Concat());
ruleFunTab.put("instr", new Instr());
ruleFunTab.put("trim", new Trim());
ruleFunTab.put("rtrim", new Rtrim());
ruleFunTab.put("ltrim", new Ltrim());
ruleFunTab.put("rpad", new Rpad());
ruleFunTab.put("lpad", new Lpad());
ruleFunTab.put("lower", new Lower());
ruleFunTab.put("upper", new Upper());
ruleFunTab.put("translate", new Translate());
ruleFunTab.put("replace", new Replace());
ruleFunTab.put("initcap", new Initcap());
ruleFunTab.put("value", new Nvl());
ruleFunTab.put("decode", new Decode());
ruleFunTab.put("to_char", new ToChar());
ruleFunTab.put("to_number", new ToNumber());
ruleFunTab.put("imatch", new IndistinctMatching()); // replacement for of Oracle's SOUNDEX
ruleFunTab.put("months_between", new MonthsBetween());
ruleFunTab.put("add_months", new AddMonths());
ruleFunTab.put("last_day", new LastDay());
ruleFunTab.put("next_day", new NextDay());
ruleFunTab.put("to_date", new ToDate());
ruleFunTab.put("case", new Case()); // replacement for CASE WHEN digit = 0 THEN ...;WHEN digit = 1 THEN ...;ELSE ... END CASE
ruleFunTab.put("index", new Instr()); // maxdb
ruleFunTab.put("num", new ToNumber()); // maxdb
ruleFunTab.put("chr", new ToChar()); // maxdb
ruleFunTab.put("dayname", new DayName()); // maxdb
ruleFunTab.put("adddate", new AddDate()); // maxdb
ruleFunTab.put("subdate", new SubDate()); // maxdb
ruleFunTab.put("addtime", new AddTime()); // maxdb
ruleFunTab.put("subtime", new SubTime()); // maxdb
ruleFunTab.put("year", new Year()); // maxdb
ruleFunTab.put("month", new Month()); // maxdb
ruleFunTab.put("day", new Day()); // maxdb
ruleFunTab.put("dayofmonth", new Day()); // maxdb
ruleFunTab.put("hour", new Hour()); // maxdb
ruleFunTab.put("minute", new Minute()); // maxdb
ruleFunTab.put("second", new Second()); // maxdb
ruleFunTab.put("microsecond", new Microsecond()); // maxdb
ruleFunTab.put("datediff", new Datediff()); // maxdb
ruleFunTab.put("dayofweek", new DayOfWeek()); // maxdb
ruleFunTab.put("weekofyear", new WeekOfYear()); // maxdb
ruleFunTab.put("dayofyear", new DayOfYear()); // maxdb
ruleFunTab.put("dayname", new DayName()); // maxdb
ruleFunTab.put("monthname", new MonthName()); // maxdb
ruleFunTab.put("makedate", new MakeDate()); // maxdb
ruleFunTab.put("maketime", new MakeTime()); // maxdb
ruleFunTab.put("hash", new Hash()); //
}
/* 默认1000 */
private LRUMap map;
private Lock mapLock = new ReentrantLock(false);
private int LRUMapSize = 10000;
private Map<Table,TableRule> tableRuleMap = new HashMap<Table,TableRule>();
private Map<String,Function> functionMap = new HashMap<String,Function>();
private Map<String,PostfixCommand> ruleFunctionMap = new HashMap<String,PostfixCommand>();
protected ObjectPool[] defaultPools;
protected ObjectPool[] readPools;
protected ObjectPool[] writePools;
private String ruleConfig;
private String functionConfig;
private String ruleFunctionConfig;
private String defaultPool;
private String readPool;
private String writePool;
private boolean needParse = true;
private boolean needEvaluate = true;
public AbstractQueryRouter(){
ruleFunctionMap.putAll(ruleFunTab);
}
public String getRuleConfig() {
return ruleConfig;
}
/**
* 创建一个新的sql parser
* @param connection
* @param sql
* @return Parser
*/
public abstract Parser newParser(String sql);
public void setRuleConfig(String ruleConfig) {
this.ruleConfig = ruleConfig;
}
public void setReadPool(String readPool) {
this.readPool = readPool;
}
public String getReadPool() {
return readPool;
}
public String getWritePool() {
return writePool;
}
public void setWritePool(String writePool) {
this.writePool = writePool;
}
public ObjectPool[] doRoute(DatabaseConnection connection,String sql,boolean ispreparedStatment, Object[] parameters) {
if(sql == null) return defaultPools;
if(needParse){
return selectPool(connection, sql,ispreparedStatment,parameters);
}else{
return this.defaultPools;
}
}
/**
* 返回Query 被route到目标地址 ObjectPool集合
* 如果返回null,则是属于DatabaseConnection 自身属性设置的请求。
* @param connection
* @param sql
* @param parameters
* @return
*/
@SuppressWarnings("unchecked")
protected ObjectPool[] selectPool(DatabaseConnection connection,String sql,boolean ispreparedStatment,Object[] parameters){
List<String> poolNames = new ArrayList<String>();
Statment statment = parseSql(connection,sql);
if(statment != null){
if(logger.isDebugEnabled()){
Expression expression = statment.getExpression();
logger.debug("Sql:["+sql +"] Expression=["+expression+"]");
}
}
Map<Table,Map<Column,Comparative>> tables = null;
DMLStatment dmlStatment = null;
if(statment instanceof DMLStatment){
dmlStatment = ((DMLStatment)statment);
if(needEvaluate){
tables = dmlStatment.evaluate(parameters);
}
}else if(statment instanceof PropertyStatment){
setProperty(connection,(PropertyStatment)statment,parameters);
return null;
}else if(statment instanceof StartTansactionStatment){
return null;
}else if(statment instanceof CommitStatment){
return null;
}else if(statment instanceof RollbackStatment){
return null;
}
if(tables != null && tables.size() >0){
Set<Map.Entry<Table,Map<Column,Comparative>>> entrySet = tables.entrySet();
for(Map.Entry<Table,Map<Column,Comparative>> entry : entrySet){
Map<Column,Comparative> columnMap = entry.getValue();
TableRule tableRule = this.tableRuleMap.get(entry.getKey());
/**
* 如果存在table Rule 则需要看是否有Rule
*/
if(tableRule != null){
if(columnMap == null || ispreparedStatment){
String[] pools = dmlStatment.isReadStatment()?tableRule.readPools:tableRule.writePools;
if(pools == null){
pools = tableRule.defaultPools;
}
for(String poolName : pools){
if(!poolNames.contains(poolName)){
poolNames.add(poolName);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?