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.distsql.handler.update;
19  
20  import com.cedarsoftware.util.CaseInsensitiveSet;
21  import com.google.common.base.Splitter;
22  import lombok.Setter;
23  import org.apache.shardingsphere.distsql.handler.engine.update.rdl.rule.spi.database.DatabaseRuleDropExecutor;
24  import org.apache.shardingsphere.infra.exception.kernel.metadata.rule.MissingRequiredRuleException;
25  import org.apache.shardingsphere.infra.exception.kernel.metadata.rule.InUsedRuleException;
26  import org.apache.shardingsphere.distsql.handler.required.DistSQLExecutorCurrentRuleRequired;
27  import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
28  import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
29  import org.apache.shardingsphere.sharding.api.config.ShardingRuleConfiguration;
30  import org.apache.shardingsphere.sharding.api.config.rule.ShardingAutoTableRuleConfiguration;
31  import org.apache.shardingsphere.sharding.api.config.rule.ShardingTableRuleConfiguration;
32  import org.apache.shardingsphere.sharding.distsql.statement.DropShardingTableRuleStatement;
33  import org.apache.shardingsphere.sharding.rule.ShardingRule;
34  
35  import java.util.Collection;
36  import java.util.Collections;
37  import java.util.LinkedList;
38  import java.util.stream.Collectors;
39  
40  /**
41   * Drop sharding table rule executor.
42   */
43  @DistSQLExecutorCurrentRuleRequired(ShardingRule.class)
44  @Setter
45  public final class DropShardingTableRuleExecutor implements DatabaseRuleDropExecutor<DropShardingTableRuleStatement, ShardingRule, ShardingRuleConfiguration> {
46      
47      private ShardingSphereDatabase database;
48      
49      private ShardingRule rule;
50      
51      @Override
52      public void checkBeforeUpdate(final DropShardingTableRuleStatement sqlStatement) {
53          if (!sqlStatement.isIfExists()) {
54              checkToBeDroppedShardingTableNames(sqlStatement);
55          }
56          if (null != rule) {
57              checkBindingTables(sqlStatement);
58          }
59      }
60      
61      private void checkToBeDroppedShardingTableNames(final DropShardingTableRuleStatement sqlStatement) {
62          Collection<String> currentShardingTableNames = getCurrentShardingTableNames();
63          Collection<String> notExistedTableNames = getToBeDroppedShardingTableNames(sqlStatement).stream().filter(each -> !currentShardingTableNames.contains(each)).collect(Collectors.toList());
64          ShardingSpherePreconditions.checkMustEmpty(notExistedTableNames, () -> new MissingRequiredRuleException("sharding", database.getName(), notExistedTableNames));
65      }
66      
67      private Collection<String> getToBeDroppedShardingTableNames(final DropShardingTableRuleStatement sqlStatement) {
68          return sqlStatement.getTableNames().stream().map(each -> each.getIdentifier().getValue()).collect(Collectors.toList());
69      }
70      
71      private Collection<String> getCurrentShardingTableNames() {
72          Collection<String> result = new CaseInsensitiveSet<>();
73          result.addAll(rule.getConfiguration().getTables().stream().map(ShardingTableRuleConfiguration::getLogicTable).collect(Collectors.toList()));
74          result.addAll(rule.getConfiguration().getAutoTables().stream().map(ShardingAutoTableRuleConfiguration::getLogicTable).collect(Collectors.toList()));
75          return result;
76      }
77      
78      private void checkBindingTables(final DropShardingTableRuleStatement sqlStatement) {
79          Collection<String> bindingTables = getBindingTables();
80          Collection<String> usedTableNames = getToBeDroppedShardingTableNames(sqlStatement).stream().filter(bindingTables::contains).collect(Collectors.toList());
81          if (!usedTableNames.isEmpty()) {
82              throw new InUsedRuleException("Sharding", database.getName(), usedTableNames, "sharding table reference");
83          }
84      }
85      
86      private Collection<String> getBindingTables() {
87          Collection<String> result = new CaseInsensitiveSet<>();
88          rule.getConfiguration().getBindingTableGroups().forEach(each -> result.addAll(Splitter.on(",").splitToList(each.getReference())));
89          return result;
90      }
91      
92      @Override
93      public boolean hasAnyOneToBeDropped(final DropShardingTableRuleStatement sqlStatement) {
94          Collection<String> currentTableNames = new LinkedList<>();
95          currentTableNames.addAll(rule.getConfiguration().getTables().stream().map(ShardingTableRuleConfiguration::getLogicTable).collect(Collectors.toSet()));
96          currentTableNames.addAll(rule.getConfiguration().getAutoTables().stream().map(ShardingAutoTableRuleConfiguration::getLogicTable).collect(Collectors.toSet()));
97          return !Collections.disjoint(currentTableNames, sqlStatement.getTableNames().stream().map(each -> each.getIdentifier().getValue()).collect(Collectors.toSet()));
98      }
99      
100     @Override
101     public ShardingRuleConfiguration buildToBeDroppedRuleConfiguration(final DropShardingTableRuleStatement sqlStatement) {
102         ShardingRuleConfiguration result = new ShardingRuleConfiguration();
103         Collection<String> toBeDroppedShardingTableNames = getToBeDroppedShardingTableNames(sqlStatement);
104         for (String each : toBeDroppedShardingTableNames) {
105             result.getTables().addAll(rule.getConfiguration().getTables().stream().filter(table -> each.equalsIgnoreCase(table.getLogicTable())).collect(Collectors.toList()));
106             result.getAutoTables().addAll(rule.getConfiguration().getAutoTables().stream().filter(table -> each.equalsIgnoreCase(table.getLogicTable())).collect(Collectors.toList()));
107             dropShardingTable(rule.getConfiguration(), each);
108         }
109         UnusedAlgorithmFinder.findUnusedShardingAlgorithm(
110                 rule.getConfiguration()).forEach(each -> result.getShardingAlgorithms().put(each, rule.getConfiguration().getShardingAlgorithms().get(each)));
111         UnusedAlgorithmFinder.findUnusedKeyGenerator(rule.getConfiguration()).forEach(each -> result.getKeyGenerators().put(each, rule.getConfiguration().getKeyGenerators().get(each)));
112         UnusedAlgorithmFinder.findUnusedAuditor(rule.getConfiguration()).forEach(each -> result.getAuditors().put(each, rule.getConfiguration().getAuditors().get(each)));
113         return result;
114     }
115     
116     private void dropShardingTable(final ShardingRuleConfiguration currentRuleConfig, final String tableName) {
117         currentRuleConfig.getTables().removeAll(currentRuleConfig.getTables().stream().filter(each -> tableName.equalsIgnoreCase(each.getLogicTable())).collect(Collectors.toList()));
118         currentRuleConfig.getAutoTables().removeAll(currentRuleConfig.getAutoTables().stream().filter(each -> tableName.equalsIgnoreCase(each.getLogicTable())).collect(Collectors.toList()));
119     }
120     
121     @Override
122     public Class<ShardingRule> getRuleClass() {
123         return ShardingRule.class;
124     }
125     
126     @Override
127     public Class<DropShardingTableRuleStatement> getType() {
128         return DropShardingTableRuleStatement.class;
129     }
130 }