1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
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 }