View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shardingsphere.sharding.route.engine.type.complex;
19  
20  import lombok.RequiredArgsConstructor;
21  import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
22  import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
23  import org.apache.shardingsphere.infra.hint.HintValueContext;
24  import org.apache.shardingsphere.infra.route.context.RouteContext;
25  import org.apache.shardingsphere.sharding.exception.metadata.ShardingTableRuleNotFoundException;
26  import org.apache.shardingsphere.sharding.route.engine.condition.ShardingConditions;
27  import org.apache.shardingsphere.sharding.route.engine.type.ShardingRouteEngine;
28  import org.apache.shardingsphere.sharding.route.engine.type.standard.ShardingStandardRoutingEngine;
29  import org.apache.shardingsphere.sharding.rule.ShardingRule;
30  import org.apache.shardingsphere.sharding.rule.ShardingTable;
31  
32  import java.util.Collection;
33  import java.util.LinkedList;
34  import java.util.Optional;
35  import java.util.TreeSet;
36  
37  /**
38   * Sharding complex routing engine.
39   */
40  @RequiredArgsConstructor
41  public final class ShardingComplexRoutingEngine implements ShardingRouteEngine {
42      
43      private final ShardingConditions shardingConditions;
44      
45      private final SQLStatementContext sqlStatementContext;
46      
47      private final HintValueContext hintValueContext;
48      
49      private final ConfigurationProperties props;
50      
51      private final Collection<String> logicTables;
52      
53      @Override
54      public RouteContext route(final ShardingRule shardingRule) {
55          Collection<String> bindingTableNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
56          Collection<RouteContext> routeContexts = new LinkedList<>();
57          for (String each : logicTables) {
58              Optional<ShardingTable> shardingTable = shardingRule.findShardingTable(each);
59              if (shardingTable.isPresent()) {
60                  if (!bindingTableNames.contains(each)) {
61                      routeContexts.add(new ShardingStandardRoutingEngine(shardingTable.get().getLogicTable(), shardingConditions, sqlStatementContext, hintValueContext, props).route(shardingRule));
62                  }
63                  shardingRule.findBindingTableRule(each).ifPresent(optional -> bindingTableNames.addAll(optional.getShardingTables().keySet()));
64              }
65          }
66          if (routeContexts.isEmpty()) {
67              throw new ShardingTableRuleNotFoundException(logicTables);
68          }
69          RouteContext result = new RouteContext();
70          if (1 == routeContexts.size()) {
71              RouteContext newRouteContext = routeContexts.iterator().next();
72              result.getOriginalDataNodes().addAll(newRouteContext.getOriginalDataNodes());
73              result.getRouteUnits().addAll(newRouteContext.getRouteUnits());
74          } else {
75              RouteContext routeContext = new ShardingCartesianRoutingEngine(routeContexts).route(shardingRule);
76              result.getOriginalDataNodes().addAll(routeContext.getOriginalDataNodes());
77              result.getRouteUnits().addAll(routeContext.getRouteUnits());
78          }
79          return result;
80      }
81  }