package com.taobao.tddl.rule;
import java.util.Map;
import java.util.Set;
import com.taobao.tddl.rule.model.sqljep.Comparative;
/**
* <pre>
* 若分库有两条规则:
* 规则一:columnA、columnB?,若columnB没有,则取columnB的所有值域(由描点信息获得)全表扫描
* 规则二:columnA、columnC。
* 若sql只包含columnA,则走规则一
* 若sql只包含columnA、columnC,则走规则二
*
* 顺序+优先最大匹配,先匹配所有列,找不到再按去除可选列之后匹配
* </pre>
*
* @author linxuan
*/
public interface Rule<T> {
public class RuleColumn {
/**
* 是否为可选列,若optional==true,则选择rule时,sql可以不包含该列。到时对该列值域做遍历
*/
public final boolean optional; //
/**
* sql中的列名,必须是大写,这里在setter显示的设置成大写了
*/
public final String key;
public RuleColumn(String name, boolean optional){
this.key = name.toUpperCase();
this.optional = optional;
}
}
/**
* @return 规则计算需要的列
*/
public Map<String, RuleColumn> getRuleColumns();
/**
* @return 规则计算需要的列
*/
public Set<RuleColumn> getRuleColumnSet();
/**
* 列值对进行rule表达式求值
*
* @param columnValues 列值对。个数与getRuleColumns相同。
* @param outerContext 动态的额外参数。比如从ThreadLocal中传入的表名前缀
* @return 根据一组列值对计算结果
*/
public T eval(Map<String/* 列名 */, Object/* 列值 */> columnValues, Object outerContext);
/**
* 比较树匹配
*
* @param sqlArgs 从SQL提取出来的比较树
*
* <pre>
* getRuleColumns包含的必选列(optional=false)必须在sqlArgs里面有。可选列可以没有
* key: String列名
* value: sql中按该列提取出的比较树Comparative,已经绑定了参数
* </pre>
* @param ctx 规则执行的上下文。用于关联规则执行时,规则间必要信息的传递。对于EnumerativeRule来说。在库表规则有公共列时,
* 会在每一个库规则的值下面,执行表规则;执行时库规则产生该值的描点信息将以该参数传入。
* @param outerContext 动态的额外参数。比如从ThreadLocal中传入的表名前缀
* @return 规则计算结果,和得到这个结果的所有数据。
*/
public Map<T, ? extends Object> calculate(Map<String/* 列名 */, Comparative> sqlArgs, Object ctx, Object outerContext);
/**
* 不反回每个结果对应的得到该结果的输入值(描点)集合
*/
public Set<T> calculateNoTrace(Map<String/* 列名 */, Comparative/* 比较树 */> sqlArgs, Object ctx, Object outerContext);
public T calculateVnodeNoTrace(String key, Object ctx, Object outerContext);
}