1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.infra.datanode;
19
20 import com.google.common.base.Objects;
21 import com.google.common.base.Splitter;
22 import lombok.Getter;
23 import lombok.RequiredArgsConstructor;
24 import lombok.Setter;
25 import lombok.ToString;
26 import org.apache.shardingsphere.infra.database.core.metadata.database.metadata.DialectDatabaseMetaData;
27 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
28 import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
29 import org.apache.shardingsphere.infra.exception.kernel.metadata.datanode.InvalidDataNodeFormatException;
30 import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
31
32 import java.util.List;
33
34
35
36
37 @RequiredArgsConstructor
38 @Getter
39 @Setter
40 @ToString
41 public final class DataNode {
42
43 private static final String DELIMITER = ".";
44
45 private static final String ASTERISK = "*";
46
47 private final String dataSourceName;
48
49 private final String tableName;
50
51
52 private String schemaName;
53
54
55
56
57
58
59 public DataNode(final String dataNode) {
60
61 boolean isIncludeInstance = isActualDataNodesIncludedDataSourceInstance(dataNode);
62 if (!isIncludeInstance && !isValidDataNode(dataNode, 2)) {
63 throw new InvalidDataNodeFormatException(dataNode);
64 }
65 if (isIncludeInstance && !isValidDataNode(dataNode, 3)) {
66 throw new InvalidDataNodeFormatException(dataNode);
67 }
68 List<String> segments = Splitter.on(DELIMITER).splitToList(dataNode);
69 dataSourceName = isIncludeInstance ? segments.get(0) + DELIMITER + segments.get(1) : segments.get(0);
70 tableName = segments.get(isIncludeInstance ? 2 : 1);
71 }
72
73
74
75
76
77
78
79
80 public DataNode(final String databaseName, final DatabaseType databaseType, final String dataNode) {
81 ShardingSpherePreconditions.checkState(dataNode.contains(DELIMITER), () -> new InvalidDataNodeFormatException(dataNode));
82 boolean containsSchema = isSchemaAvailable(databaseType) && isValidDataNode(dataNode, 3);
83 List<String> segments = Splitter.on(DELIMITER).limit(containsSchema ? 3 : 2).splitToList(dataNode);
84 dataSourceName = segments.get(0);
85 schemaName = getSchemaName(databaseName, databaseType, containsSchema, segments);
86 tableName = containsSchema ? segments.get(2).toLowerCase() : segments.get(1).toLowerCase();
87 }
88
89 private boolean isSchemaAvailable(final DatabaseType databaseType) {
90 return new DatabaseTypeRegistry(databaseType).getDialectDatabaseMetaData().getSchemaOption().isSchemaAvailable();
91 }
92
93 private String getSchemaName(final String databaseName, final DatabaseType databaseType, final boolean containsSchema, final List<String> segments) {
94 DialectDatabaseMetaData dialectDatabaseMetaData = new DatabaseTypeRegistry(databaseType).getDialectDatabaseMetaData();
95 if (dialectDatabaseMetaData.getSchemaOption().getDefaultSchema().isPresent()) {
96 return containsSchema ? segments.get(1) : ASTERISK;
97 }
98 return databaseName;
99 }
100
101 private boolean isValidDataNode(final String dataNodeStr, final Integer tier) {
102 return dataNodeStr.contains(DELIMITER) && tier == Splitter.on(DELIMITER).omitEmptyStrings().splitToList(dataNodeStr).size();
103 }
104
105 private boolean isActualDataNodesIncludedDataSourceInstance(final String actualDataNodes) {
106 return isValidDataNode(actualDataNodes, 3);
107 }
108
109
110
111
112
113
114 public String format() {
115 return null == schemaName ? String.join(DELIMITER, dataSourceName, tableName) : String.join(DELIMITER, dataSourceName, schemaName, tableName);
116 }
117
118
119
120
121
122
123
124 public String format(final DatabaseType databaseType) {
125 return null != schemaName && new DatabaseTypeRegistry(databaseType).getDialectDatabaseMetaData().getSchemaOption().getDefaultSchema().isPresent()
126 ? String.join(DELIMITER, dataSourceName, schemaName, tableName)
127 : String.join(DELIMITER, dataSourceName, tableName);
128 }
129
130 @Override
131 public boolean equals(final Object object) {
132 if (this == object) {
133 return true;
134 }
135 if (null == object || getClass() != object.getClass()) {
136 return false;
137 }
138 DataNode dataNode = (DataNode) object;
139 return Objects.equal(dataSourceName.toUpperCase(), dataNode.dataSourceName.toUpperCase())
140 && Objects.equal(tableName.toUpperCase(), dataNode.tableName.toUpperCase())
141 && Objects.equal(null == schemaName ? null : schemaName.toUpperCase(), null == dataNode.schemaName ? null : dataNode.schemaName.toUpperCase());
142 }
143
144 @Override
145 public int hashCode() {
146 return Objects.hashCode(dataSourceName.toUpperCase(), tableName.toUpperCase(), null == schemaName ? null : schemaName.toUpperCase());
147 }
148 }