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.proxy.backend.mysql.response.header.query;
19  
20  import org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
21  import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
22  import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereColumn;
23  import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
24  import org.apache.shardingsphere.infra.rule.attribute.datanode.DataNodeRuleAttribute;
25  import org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeader;
26  import org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeaderBuilder;
27  
28  import java.sql.SQLException;
29  import java.util.Optional;
30  
31  /**
32   * Query header builder for MySQL.
33   */
34  public final class MySQLQueryHeaderBuilder implements QueryHeaderBuilder {
35      
36      @Override
37      public QueryHeader build(final QueryResultMetaData queryResultMetaData,
38                               final ShardingSphereDatabase database, final String columnName, final String columnLabel, final int columnIndex) throws SQLException {
39          String schemaName = null == database ? "" : database.getName();
40          String actualTableName = queryResultMetaData.getTableName(columnIndex);
41          String tableName;
42          boolean primaryKey;
43          if (null == actualTableName || null == database) {
44              tableName = actualTableName;
45              primaryKey = false;
46          } else {
47              tableName = getLogicTableName(database, actualTableName);
48              ShardingSphereSchema schema = database.getSchema(schemaName);
49              primaryKey = null != schema
50                      && Optional.ofNullable(schema.getTable(tableName)).map(optional -> optional.getColumn(columnName)).map(ShardingSphereColumn::isPrimaryKey).orElse(false);
51          }
52          int columnType = queryResultMetaData.getColumnType(columnIndex);
53          String columnTypeName = queryResultMetaData.getColumnTypeName(columnIndex);
54          int columnLength = queryResultMetaData.getColumnLength(columnIndex);
55          int decimals = queryResultMetaData.getDecimals(columnIndex);
56          boolean signed = queryResultMetaData.isSigned(columnIndex);
57          boolean notNull = queryResultMetaData.isNotNull(columnIndex);
58          boolean autoIncrement = queryResultMetaData.isAutoIncrement(columnIndex);
59          return new QueryHeader(schemaName, tableName, columnLabel, columnName, columnType, columnTypeName, columnLength, decimals, signed, primaryKey, notNull, autoIncrement);
60      }
61      
62      private String getLogicTableName(final ShardingSphereDatabase database, final String actualTableName) {
63          for (DataNodeRuleAttribute each : database.getRuleMetaData().getAttributes(DataNodeRuleAttribute.class)) {
64              Optional<String> logicTable = each.findLogicTableByActualTable(actualTableName);
65              if (logicTable.isPresent()) {
66                  return logicTable.get();
67              }
68          }
69          return actualTableName;
70      }
71      
72      @Override
73      public String getDatabaseType() {
74          return "MySQL";
75      }
76      
77      // TODO to be confirmed, QueryHeaderBuilder should not has default value, just throw unsupported exception if database type missing
78      @Override
79      public boolean isDefault() {
80          return true;
81      }
82  }