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.encrypt.merge.dql;
19  
20  import lombok.RequiredArgsConstructor;
21  import org.apache.shardingsphere.encrypt.exception.data.DecryptFailedException;
22  import org.apache.shardingsphere.encrypt.rule.EncryptRule;
23  import org.apache.shardingsphere.encrypt.rule.column.EncryptColumn;
24  import org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.ColumnProjection;
25  import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext;
26  import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
27  import org.apache.shardingsphere.infra.exception.core.external.sql.identifier.SQLExceptionIdentifier;
28  import org.apache.shardingsphere.infra.merge.result.MergedResult;
29  import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
30  
31  import java.io.InputStream;
32  import java.io.Reader;
33  import java.sql.SQLException;
34  import java.util.Calendar;
35  import java.util.Optional;
36  
37  /**
38   * Merged result for encrypt.
39   */
40  @RequiredArgsConstructor
41  public final class EncryptMergedResult implements MergedResult {
42      
43      private final ShardingSphereDatabase database;
44      
45      private final EncryptRule encryptRule;
46      
47      private final SelectStatementContext selectStatementContext;
48      
49      private final MergedResult mergedResult;
50      
51      @Override
52      public boolean next() throws SQLException {
53          return mergedResult.next();
54      }
55      
56      @Override
57      public Object getValue(final int columnIndex, final Class<?> type) throws SQLException {
58          Optional<ColumnProjection> columnProjection = selectStatementContext.findColumnProjection(columnIndex);
59          if (!columnProjection.isPresent()) {
60              return mergedResult.getValue(columnIndex, type);
61          }
62          String originalTableName = columnProjection.get().getOriginalTable().getValue();
63          String originalColumnName = columnProjection.get().getOriginalColumn().getValue();
64          if (!encryptRule.findEncryptTable(originalTableName).map(optional -> optional.isEncryptColumn(originalColumnName)).orElse(false)) {
65              return mergedResult.getValue(columnIndex, type);
66          }
67          Object cipherValue = mergedResult.getValue(columnIndex, Object.class);
68          EncryptColumn encryptColumn = encryptRule.getEncryptTable(originalTableName).getEncryptColumn(originalColumnName);
69          String schemaName =
70                  selectStatementContext.getTablesContext().getSchemaName().orElseGet(() -> new DatabaseTypeRegistry(selectStatementContext.getDatabaseType()).getDefaultSchemaName(database.getName()));
71          try {
72              return encryptColumn.getCipher().decrypt(database.getName(), schemaName, originalTableName, originalColumnName, cipherValue);
73              // CHECKSTYLE:OFF
74          } catch (final Exception ex) {
75              // CHECKSTYLE:ON
76              throw new DecryptFailedException(String.valueOf(cipherValue), new SQLExceptionIdentifier(database.getName(), originalTableName, originalColumnName), ex);
77          }
78      }
79      
80      @Override
81      public Object getCalendarValue(final int columnIndex, final Class<?> type, final Calendar calendar) throws SQLException {
82          return mergedResult.getCalendarValue(columnIndex, type, calendar);
83      }
84      
85      @Override
86      public InputStream getInputStream(final int columnIndex, final String type) throws SQLException {
87          return mergedResult.getInputStream(columnIndex, type);
88      }
89      
90      @Override
91      public Reader getCharacterStream(final int columnIndex) throws SQLException {
92          return mergedResult.getCharacterStream(columnIndex);
93      }
94      
95      @Override
96      public boolean wasNull() throws SQLException {
97          return mergedResult.wasNull();
98      }
99  }