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 lombok.Setter;
21 import org.apache.shardingsphere.distsql.handler.engine.update.rdl.rule.spi.database.DatabaseRuleCreateExecutor;
22 import org.apache.shardingsphere.distsql.segment.AlgorithmSegment;
23 import org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration;
24 import org.apache.shardingsphere.infra.algorithm.core.exception.MissingRequiredAlgorithmException;
25 import org.apache.shardingsphere.infra.algorithm.core.exception.InvalidAlgorithmConfigurationException;
26 import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
27 import org.apache.shardingsphere.infra.exception.core.external.sql.identifier.SQLExceptionIdentifier;
28 import org.apache.shardingsphere.infra.exception.kernel.metadata.rule.DuplicateRuleException;
29 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
30 import org.apache.shardingsphere.sharding.api.config.ShardingRuleConfiguration;
31 import org.apache.shardingsphere.sharding.api.config.strategy.sharding.NoneShardingStrategyConfiguration;
32 import org.apache.shardingsphere.sharding.api.config.strategy.sharding.ShardingStrategyConfiguration;
33 import org.apache.shardingsphere.sharding.distsql.handler.converter.ShardingTableRuleStatementConverter;
34 import org.apache.shardingsphere.sharding.distsql.handler.enums.ShardingStrategyLevelType;
35 import org.apache.shardingsphere.sharding.distsql.handler.enums.ShardingStrategyType;
36 import org.apache.shardingsphere.sharding.distsql.statement.CreateDefaultShardingStrategyStatement;
37 import org.apache.shardingsphere.sharding.rule.ShardingRule;
38
39 import java.util.Optional;
40
41
42
43
44 @Setter
45 public final class CreateDefaultShardingStrategyExecutor implements DatabaseRuleCreateExecutor<CreateDefaultShardingStrategyStatement, ShardingRule, ShardingRuleConfiguration> {
46
47 private ShardingSphereDatabase database;
48
49 private ShardingRule rule;
50
51 @Override
52 public void checkBeforeUpdate(final CreateDefaultShardingStrategyStatement sqlStatement) {
53 if (!"none".equalsIgnoreCase(sqlStatement.getStrategyType())) {
54 checkAlgorithm(sqlStatement);
55 }
56 if (!sqlStatement.isIfNotExists()) {
57 checkExist(sqlStatement);
58 }
59 }
60
61 private void checkAlgorithm(final CreateDefaultShardingStrategyStatement sqlStatement) {
62 ShardingSpherePreconditions.checkState(ShardingStrategyType.isValidType(sqlStatement.getStrategyType()), () -> new InvalidAlgorithmConfigurationException(sqlStatement.getStrategyType()));
63 ShardingSpherePreconditions.checkState(ShardingStrategyType.getValueOf(sqlStatement.getStrategyType())
64 .isValid(sqlStatement.getShardingColumn()), () -> new InvalidAlgorithmConfigurationException(sqlStatement.getStrategyType()));
65 ShardingSpherePreconditions.checkNotNull(sqlStatement.getAlgorithmSegment(), () -> new MissingRequiredAlgorithmException("Sharding", new SQLExceptionIdentifier("")));
66 }
67
68 private void checkExist(final CreateDefaultShardingStrategyStatement sqlStatement) {
69 if (null == rule) {
70 return;
71 }
72 ShardingSpherePreconditions.checkState(!getStrategyConfiguration(sqlStatement.getDefaultType()).isPresent(),
73 () -> new DuplicateRuleException(String.format("default sharding %s strategy", sqlStatement.getDefaultType().toLowerCase()), database.getName()));
74 }
75
76 private Optional<ShardingStrategyConfiguration> getStrategyConfiguration(final String type) {
77 ShardingStrategyConfiguration result = type.equalsIgnoreCase(ShardingStrategyLevelType.TABLE.name())
78 ? rule.getConfiguration().getDefaultTableShardingStrategy()
79 : rule.getConfiguration().getDefaultDatabaseShardingStrategy();
80 return Optional.ofNullable(result);
81 }
82
83 @Override
84 public ShardingRuleConfiguration buildToBeCreatedRuleConfiguration(final CreateDefaultShardingStrategyStatement sqlStatement) {
85 ShardingRuleConfiguration result = new ShardingRuleConfiguration();
86 if ("none".equalsIgnoreCase(sqlStatement.getStrategyType())) {
87 setStrategyConfiguration(result, sqlStatement.getDefaultType(), new NoneShardingStrategyConfiguration());
88 } else {
89 String shardingAlgorithmName = getShardingAlgorithmName(sqlStatement, result);
90 ShardingStrategyConfiguration strategyConfig = ShardingTableRuleStatementConverter.createStrategyConfiguration(
91 sqlStatement.getStrategyType(), sqlStatement.getShardingColumn(), shardingAlgorithmName);
92 setStrategyConfiguration(result, sqlStatement.getDefaultType(), strategyConfig);
93 }
94 return result;
95 }
96
97 private String getShardingAlgorithmName(final CreateDefaultShardingStrategyStatement sqlStatement, final ShardingRuleConfiguration ruleConfig) {
98 return createDefaultAlgorithm(sqlStatement, ruleConfig);
99 }
100
101 private String createDefaultAlgorithm(final CreateDefaultShardingStrategyStatement sqlStatement, final ShardingRuleConfiguration ruleConfig) {
102 String result = getDefaultShardingAlgorithmName(sqlStatement.getDefaultType(), sqlStatement.getAlgorithmSegment().getName());
103 ruleConfig.getShardingAlgorithms().put(result, createAlgorithmConfiguration(sqlStatement.getAlgorithmSegment()));
104 return result;
105 }
106
107 private AlgorithmConfiguration createAlgorithmConfiguration(final AlgorithmSegment segment) {
108 return new AlgorithmConfiguration(segment.getName(), segment.getProps());
109 }
110
111 private String getDefaultShardingAlgorithmName(final String defaultType, final String algorithmType) {
112 return String.format("default_%s_%s", defaultType, algorithmType).toLowerCase();
113 }
114
115 private void setStrategyConfiguration(final ShardingRuleConfiguration ruleConfig, final String type, final ShardingStrategyConfiguration shardingStrategyConfig) {
116 if (type.equalsIgnoreCase(ShardingStrategyLevelType.TABLE.name())) {
117 ruleConfig.setDefaultTableShardingStrategy(shardingStrategyConfig);
118 } else {
119 ruleConfig.setDefaultDatabaseShardingStrategy(shardingStrategyConfig);
120 }
121 }
122
123 @Override
124 public Class<ShardingRule> getRuleClass() {
125 return ShardingRule.class;
126 }
127
128 @Override
129 public Class<CreateDefaultShardingStrategyStatement> getType() {
130 return CreateDefaultShardingStrategyStatement.class;
131 }
132 }