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.infra.connection.refresher.type.view;
19  
20  import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
21  import org.apache.shardingsphere.infra.connection.refresher.MetaDataRefresher;
22  import org.apache.shardingsphere.infra.connection.refresher.util.TableRefreshUtils;
23  import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
24  import org.apache.shardingsphere.infra.instance.mode.ModeContextManager;
25  import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
26  import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
27  import org.apache.shardingsphere.infra.metadata.database.schema.builder.GenericSchemaBuilder;
28  import org.apache.shardingsphere.infra.metadata.database.schema.builder.GenericSchemaBuilderMaterial;
29  import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
30  import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
31  import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereView;
32  import org.apache.shardingsphere.infra.metadata.database.schema.pojo.AlterSchemaMetaDataPOJO;
33  import org.apache.shardingsphere.infra.rule.attribute.datanode.MutableDataNodeRuleAttribute;
34  import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
35  import org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.AlterViewStatement;
36  import org.apache.shardingsphere.sql.parser.sql.dialect.handler.ddl.AlterViewStatementHandler;
37  
38  import java.sql.SQLException;
39  import java.util.Collection;
40  import java.util.Collections;
41  import java.util.LinkedList;
42  import java.util.Map;
43  import java.util.Optional;
44  
45  /**
46   * Schema refresher for alter view statement.
47   */
48  public final class AlterViewStatementSchemaRefresher implements MetaDataRefresher<AlterViewStatement> {
49      
50      @Override
51      public void refresh(final ModeContextManager modeContextManager, final ShardingSphereDatabase database, final Collection<String> logicDataSourceNames,
52                          final String schemaName, final DatabaseType databaseType, final AlterViewStatement sqlStatement, final ConfigurationProperties props) throws SQLException {
53          String viewName = TableRefreshUtils.getTableName(databaseType, sqlStatement.getView().getTableName().getIdentifier());
54          AlterSchemaMetaDataPOJO alterSchemaMetaDataPOJO = new AlterSchemaMetaDataPOJO(database.getName(), schemaName, logicDataSourceNames);
55          Optional<SimpleTableSegment> renameView = AlterViewStatementHandler.getRenameView(sqlStatement);
56          if (renameView.isPresent()) {
57              String renameViewName = renameView.get().getTableName().getIdentifier().getValue();
58              String originalView = database.getSchema(schemaName).getView(viewName).getViewDefinition();
59              ShardingSphereSchema schema = getSchema(database, logicDataSourceNames, schemaName, renameViewName, originalView, props);
60              alterSchemaMetaDataPOJO.getAlteredTables().add(schema.getTable(renameViewName));
61              alterSchemaMetaDataPOJO.getAlteredViews().add(schema.getView(renameViewName));
62              alterSchemaMetaDataPOJO.getDroppedTables().add(viewName);
63              alterSchemaMetaDataPOJO.getDroppedViews().add(viewName);
64          }
65          Optional<String> viewDefinition = AlterViewStatementHandler.getViewDefinition(sqlStatement);
66          if (viewDefinition.isPresent()) {
67              ShardingSphereSchema schema = getSchema(database, logicDataSourceNames, schemaName, viewName, viewDefinition.get(), props);
68              alterSchemaMetaDataPOJO.getAlteredTables().add(schema.getTable(viewName));
69              alterSchemaMetaDataPOJO.getAlteredViews().add(schema.getView(viewName));
70          }
71          modeContextManager.alterSchemaMetaData(alterSchemaMetaDataPOJO);
72      }
73      
74      private ShardingSphereSchema getSchema(final ShardingSphereDatabase database, final Collection<String> logicDataSourceNames,
75                                             final String schemaName, final String viewName, final String viewDefinition, final ConfigurationProperties props) throws SQLException {
76          RuleMetaData ruleMetaData = new RuleMetaData(new LinkedList<>(database.getRuleMetaData().getRules()));
77          if (TableRefreshUtils.isSingleTable(viewName, database)) {
78              ruleMetaData.getAttributes(MutableDataNodeRuleAttribute.class).forEach(each -> each.put(logicDataSourceNames.iterator().next(), schemaName, viewName));
79          }
80          GenericSchemaBuilderMaterial material = new GenericSchemaBuilderMaterial(
81                  database.getProtocolType(), database.getResourceMetaData().getStorageUnits(), ruleMetaData.getRules(), props, schemaName);
82          Map<String, ShardingSphereSchema> schemaMap = GenericSchemaBuilder.build(Collections.singletonList(viewName), material);
83          Optional<ShardingSphereTable> actualViewMetaData = Optional.ofNullable(schemaMap.get(schemaName)).map(optional -> optional.getTable(viewName));
84          ShardingSphereSchema result = new ShardingSphereSchema();
85          actualViewMetaData.ifPresent(optional -> result.putTable(viewName, optional));
86          result.putView(viewName, new ShardingSphereView(viewName, viewDefinition));
87          return result;
88      }
89      
90      @Override
91      public Class<AlterViewStatement> getType() {
92          return AlterViewStatement.class;
93      }
94  }