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.rule;
19  
20  import com.cedarsoftware.util.CaseInsensitiveMap;
21  import lombok.Getter;
22  import lombok.RequiredArgsConstructor;
23  import org.apache.shardingsphere.sharding.exception.metadata.ActualTableNotFoundException;
24  import org.apache.shardingsphere.sharding.exception.metadata.BindingTableNotFoundException;
25  
26  import java.util.Collection;
27  import java.util.LinkedHashMap;
28  import java.util.Map;
29  import java.util.Optional;
30  
31  /**
32   * Binding table rule.
33   * 
34   * <p>Binding table is same sharding rule with different tables, use one of them can deduce other name of actual tables and data sources.</p>
35   */
36  @RequiredArgsConstructor
37  @Getter
38  public final class BindingTableRule {
39      
40      private final Map<String, ShardingTable> shardingTables = new CaseInsensitiveMap<>();
41      
42      /**
43       * Judge contains this logic table in this rule.
44       * 
45       * @param logicTable logic table name
46       * @return contains this logic table or not
47       */
48      public boolean hasLogicTable(final String logicTable) {
49          return shardingTables.containsKey(logicTable);
50      }
51      
52      /**
53       * Deduce actual table name from other actual table name in same binding table rule.
54       * 
55       * @param dataSource data source name
56       * @param logicTable logic table name
57       * @param otherLogicTable other logic table name in same binding table rule
58       * @param otherActualTable other actual table name in same binding table rule
59       * @return actual table name
60       * @throws ActualTableNotFoundException actual table not found exception
61       * @throws BindingTableNotFoundException binding table not found exception
62       */
63      public String getBindingActualTable(final String dataSource, final String logicTable, final String otherLogicTable, final String otherActualTable) {
64          Optional<ShardingTable> otherShardingTable = Optional.ofNullable(shardingTables.get(otherLogicTable));
65          int index = otherShardingTable.map(optional -> optional.findActualTableIndex(dataSource, otherActualTable)).orElse(-1);
66          if (-1 == index) {
67              throw new ActualTableNotFoundException(dataSource, otherActualTable);
68          }
69          Optional<ShardingTable> shardingTable = Optional.ofNullable(shardingTables.get(logicTable));
70          if (shardingTable.isPresent()) {
71              return shardingTable.get().getActualDataNodes().get(index).getTableName();
72          }
73          throw new BindingTableNotFoundException(dataSource, logicTable, otherActualTable);
74      }
75      
76      /**
77       * Get list of logical table.
78       *
79       * @return logical tables.
80       */
81      public Collection<String> getAllLogicTables() {
82          return shardingTables.keySet();
83      }
84      
85      /**
86       * Get logic and actual tables.
87       * 
88       * @param dataSource data source
89       * @param logicTable logic table
90       * @param actualTable actual table
91       * @param availableLogicBindingTables available logic binding tables
92       * @return logic and actual tables
93       */
94      public Map<String, String> getLogicAndActualTables(final String dataSource, final String logicTable, final String actualTable, final Collection<String> availableLogicBindingTables) {
95          Map<String, String> result = new LinkedHashMap<>(availableLogicBindingTables.size(), 1F);
96          for (String each : availableLogicBindingTables) {
97              if (!each.equalsIgnoreCase(logicTable) && hasLogicTable(each)) {
98                  result.put(each, getBindingActualTable(dataSource, each, logicTable, actualTable));
99              }
100         }
101         return result;
102     }
103 }