
com.github.javaclub.cdl.client.matrix.router.single.SingleTableRouter Maven / Gradle / Ivy
/**
* Copyright 1999-2015 dangdang.com.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.github.javaclub.cdl.client.matrix.router.single;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import lombok.extern.slf4j.Slf4j;
import com.github.javaclub.cdl.client.matrix.jdbc.ShardingValue;
import com.github.javaclub.cdl.client.matrix.parser.result.router.Condition;
import com.github.javaclub.cdl.client.matrix.parser.result.router.ConditionContext;
import com.github.javaclub.cdl.client.matrix.rule.RouterStrategy;
import com.google.common.base.Optional;
import com.google.common.collect.BoundType;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Range;
/**
* 单逻辑表的库表路由.
*
*/
@Slf4j
public final class SingleTableRouter {
private final RouterStrategy routerStrategy;;
private final String logicTable;
private final ConditionContext conditionContext;
private String shardingColumn;
public SingleTableRouter(final RouterStrategy routerStrategy, final String logicTable, final ConditionContext conditionContext) {
this.routerStrategy = routerStrategy;
this.logicTable = logicTable;
this.conditionContext = conditionContext;
if(routerStrategy.getShardingColumn() != null){
this.shardingColumn = routerStrategy.getShardingColumn().get(logicTable);
}
}
/**
* 路由.
*
* @return 路由结果
*/
public SingleRoutingResult route() {
SingleRoutingResult result = new SingleRoutingResult();
ShardingValue> shardingValue = getShardingValue(shardingColumn);
Multimap routeMap = HashMultimap.create();
if (shardingValue != null) {
switch (shardingValue.getType()) {
case SINGLE:
Map map1 = routerStrategy.getActualTable(logicTable, shardingValue.getValue());
for (String group : map1.keySet()) {
routeMap.put(group, map1.get(group));
}
break;
case LIST:
for (Object value : shardingValue.getValues()) {
Map map2 = routerStrategy.getActualTable(logicTable, value);
for (String group : map2.keySet()) {
routeMap.put(group, map2.get(group));
}
}
break;
case RANGE:
@SuppressWarnings("unchecked")
ShardingValue intValue = (ShardingValue) shardingValue;
for (Integer value = intValue.getValueRange().lowerEndpoint(); value <= intValue.getValueRange().upperEndpoint(); value++) {
Map map3 = routerStrategy.getActualTable(logicTable, value);
for (String group : map3.keySet()) {
routeMap.put(group, map3.get(group));
}
}
break;
default:
throw new UnsupportedOperationException();
}
}
if (routeMap.isEmpty()) { // 走全部分片
log.debug("scan all shards:{}", logicTable);
Map> allTables = routerStrategy.getAllActualTable(logicTable);
for (String group : allTables.keySet()) {
for (String actualTable : allTables.get(group)) {
result.put(group, new SingleRoutingTableFactor(logicTable, actualTable));
}
}
} else {
for (String group : routeMap.keySet()) {
Collection actualTables = routeMap.get(group);
for (String actualTable : actualTables) {
result.put(group, new SingleRoutingTableFactor(logicTable, actualTable));
}
}
}
return result;
}
private ShardingValue> getShardingValue(final String shardingColumn) {
if(StringUtils.isBlank(shardingColumn)){
return null;
}
Optional condition = conditionContext.find(logicTable, shardingColumn);
if (condition.isPresent()) {
return getShardingValue(condition.get());
} else {
log.debug("no found sharding value:{},{}", logicTable, shardingColumn);
}
return null;
}
private ShardingValue> getShardingValue(final Condition condition) {
List> conditionValues = condition.getValues();
switch (condition.getOperator()) {
case EQUAL:
case IN:
if (1 == conditionValues.size()) {
return new ShardingValue>(condition.getColumn().getColumnName(), conditionValues.get(0));
}
return new ShardingValue<>(condition.getColumn().getColumnName(), conditionValues);
case BETWEEN:
return new ShardingValue<>(condition.getColumn().getColumnName(), Range.range(conditionValues.get(0), BoundType.CLOSED,
conditionValues.get(1), BoundType.CLOSED));
default:
throw new UnsupportedOperationException(condition.getOperator().getExpression());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy