1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.mode.metadata;
19
20 import lombok.Getter;
21 import lombok.SneakyThrows;
22 import org.apache.shardingsphere.infra.database.core.metadata.database.DialectDatabaseMetaData;
23 import org.apache.shardingsphere.infra.database.core.spi.DatabaseTypedSPILoader;
24 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
25 import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
26 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
27 import org.apache.shardingsphere.infra.metadata.statistics.ShardingSphereDatabaseData;
28 import org.apache.shardingsphere.infra.metadata.statistics.ShardingSphereSchemaData;
29 import org.apache.shardingsphere.infra.metadata.statistics.ShardingSphereStatistics;
30 import org.apache.shardingsphere.infra.metadata.statistics.ShardingSphereTableData;
31 import org.apache.shardingsphere.infra.metadata.statistics.builder.ShardingSphereStatisticsBuilder;
32 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
33 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
34 import org.apache.shardingsphere.metadata.persist.MetaDataBasedPersistService;
35
36 import java.util.Collection;
37 import java.util.LinkedList;
38 import java.util.Map.Entry;
39 import java.util.Optional;
40
41
42
43
44 @Getter
45 public final class MetaDataContexts implements AutoCloseable {
46
47 private final MetaDataBasedPersistService persistService;
48
49 private final ShardingSphereMetaData metaData;
50
51 private final ShardingSphereStatistics statistics;
52
53 public MetaDataContexts(final MetaDataBasedPersistService persistService, final ShardingSphereMetaData metaData) {
54 this.persistService = persistService;
55 this.metaData = metaData;
56 this.statistics = initStatistics(metaData);
57 }
58
59 private ShardingSphereStatistics initStatistics(final ShardingSphereMetaData metaData) {
60 if (metaData.getDatabases().isEmpty()) {
61 return new ShardingSphereStatistics();
62 }
63 DatabaseType protocolType = metaData.getDatabases().values().iterator().next().getProtocolType();
64 DialectDatabaseMetaData dialectDatabaseMetaData = new DatabaseTypeRegistry(protocolType).getDialectDatabaseMetaData();
65
66 DatabaseType databaseType = dialectDatabaseMetaData.getDefaultSchema().isPresent() ? TypedSPILoader.getService(DatabaseType.class, "PostgreSQL") : protocolType;
67 Optional<ShardingSphereStatisticsBuilder> statisticsBuilder = DatabaseTypedSPILoader.findService(ShardingSphereStatisticsBuilder.class, databaseType);
68 if (!statisticsBuilder.isPresent()) {
69 return new ShardingSphereStatistics();
70 }
71 ShardingSphereStatistics result = statisticsBuilder.get().build(metaData);
72 Optional<ShardingSphereStatistics> loadedStatistics = persistService.getShardingSphereDataPersistService().load(metaData);
73 loadedStatistics.ifPresent(optional -> useLoadedToReplaceInit(result, optional));
74 return result;
75 }
76
77 private void useLoadedToReplaceInit(final ShardingSphereStatistics initStatistics, final ShardingSphereStatistics loadedStatistics) {
78 for (Entry<String, ShardingSphereDatabaseData> entry : initStatistics.getDatabaseData().entrySet()) {
79 if (loadedStatistics.getDatabaseData().containsKey(entry.getKey())) {
80 useLoadedToReplaceInitByDatabaseData(entry.getValue(), loadedStatistics.getDatabaseData().get(entry.getKey()));
81 }
82 }
83 }
84
85 private void useLoadedToReplaceInitByDatabaseData(final ShardingSphereDatabaseData initDatabaseData, final ShardingSphereDatabaseData loadedDatabaseData) {
86 for (Entry<String, ShardingSphereSchemaData> entry : initDatabaseData.getSchemaData().entrySet()) {
87 if (loadedDatabaseData.getSchemaData().containsKey(entry.getKey())) {
88 useLoadedToReplaceInitBySchemaData(entry.getValue(), loadedDatabaseData.getSchemaData().get(entry.getKey()));
89 }
90 }
91 }
92
93 private void useLoadedToReplaceInitBySchemaData(final ShardingSphereSchemaData initSchemaData, final ShardingSphereSchemaData loadedSchemaData) {
94 for (Entry<String, ShardingSphereTableData> entry : initSchemaData.getTableData().entrySet()) {
95 if (loadedSchemaData.getTableData().containsKey(entry.getKey())) {
96 entry.setValue(loadedSchemaData.getTableData().get(entry.getKey()));
97 }
98 }
99 }
100
101 @SneakyThrows(Exception.class)
102 @Override
103 public void close() {
104 persistService.getRepository().close();
105 for (ShardingSphereRule each : getAllRules()) {
106 if (each instanceof AutoCloseable) {
107 ((AutoCloseable) each).close();
108 }
109 }
110 }
111
112 private Collection<ShardingSphereRule> getAllRules() {
113 Collection<ShardingSphereRule> result = new LinkedList<>(metaData.getGlobalRuleMetaData().getRules());
114 metaData.getDatabases().values().stream().map(each -> each.getRuleMetaData().getRules()).forEach(result::addAll);
115 return result;
116 }
117 }