1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.encrypt.merge.dal.show;
19
20 import org.apache.shardingsphere.encrypt.exception.syntax.UnsupportedEncryptSQLException;
21 import org.apache.shardingsphere.encrypt.rule.EncryptRule;
22 import org.apache.shardingsphere.encrypt.rule.table.EncryptTable;
23 import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
24 import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
25 import org.apache.shardingsphere.infra.merge.result.MergedResult;
26 import org.apache.shardingsphere.infra.merge.result.impl.decorator.DecoratorMergedResult;
27 import org.apache.shardingsphere.sql.parser.statement.core.statement.attribute.type.ColumnInResultSetSQLStatementAttribute;
28
29 import java.sql.SQLException;
30 import java.util.Optional;
31
32
33
34
35 public final class EncryptShowColumnsMergedResult extends DecoratorMergedResult {
36
37 private final EncryptRule rule;
38
39 private final String tableName;
40
41 private final int columnNameResultSetIndex;
42
43 public EncryptShowColumnsMergedResult(final MergedResult mergedResult, final SQLStatementContext sqlStatementContext, final EncryptRule rule) {
44 super(mergedResult);
45 ShardingSpherePreconditions.checkState(1 == sqlStatementContext.getTablesContext().getSimpleTables().size(),
46 () -> new UnsupportedEncryptSQLException("SHOW COLUMNS FOR MULTI TABLES"));
47 this.rule = rule;
48 tableName = sqlStatementContext.getTablesContext().getSimpleTables().iterator().next().getTableName().getIdentifier().getValue();
49 ColumnInResultSetSQLStatementAttribute attribute = sqlStatementContext.getSqlStatement().getAttributes().getAttribute(ColumnInResultSetSQLStatementAttribute.class);
50 columnNameResultSetIndex = attribute.getNameResultSetIndex();
51 }
52
53 @Override
54 public boolean next() throws SQLException {
55 boolean hasNext = getMergedResult().next();
56 Optional<EncryptTable> encryptTable = rule.findEncryptTable(tableName);
57 if (hasNext && !encryptTable.isPresent()) {
58 return true;
59 }
60 if (!hasNext) {
61 return false;
62 }
63 return next(encryptTable.get());
64 }
65
66 private boolean next(final EncryptTable encryptTable) throws SQLException {
67 while (encryptTable.isDerivedColumn(getMergedResult().getValue(columnNameResultSetIndex, String.class).toString())) {
68 boolean isFinished = !getMergedResult().next();
69 if (isFinished) {
70 return false;
71 }
72 }
73 return true;
74 }
75
76 @Override
77 public Object getValue(final int columnIndex, final Class<?> type) throws SQLException {
78 if (columnNameResultSetIndex == columnIndex) {
79 return getColumnNameValue(type);
80 }
81 return getMergedResult().getValue(columnIndex, type);
82 }
83
84 private String getColumnNameValue(final Class<?> type) throws SQLException {
85 String columnName = getMergedResult().getValue(columnNameResultSetIndex, type).toString();
86 Optional<EncryptTable> encryptTable = rule.findEncryptTable(tableName);
87 return encryptTable.isPresent() && encryptTable.get().isCipherColumn(columnName) ? encryptTable.get().getLogicColumnByCipherColumn(columnName) : columnName;
88 }
89 }