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.EncryptTable;
23 import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
24 import org.apache.shardingsphere.infra.binder.context.type.TableAvailable;
25 import org.apache.shardingsphere.infra.merge.result.MergedResult;
26 import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
27
28 import java.io.InputStream;
29 import java.io.Reader;
30 import java.sql.SQLException;
31 import java.sql.SQLFeatureNotSupportedException;
32 import java.util.Calendar;
33 import java.util.Optional;
34
35
36
37
38 public abstract class EncryptShowColumnsMergedResult implements MergedResult {
39
40 private static final int COLUMN_FIELD_INDEX = 1;
41
42 private final String tableName;
43
44 private final EncryptRule encryptRule;
45
46 protected EncryptShowColumnsMergedResult(final SQLStatementContext sqlStatementContext, final EncryptRule encryptRule) {
47 ShardingSpherePreconditions.checkState(sqlStatementContext instanceof TableAvailable && 1 == ((TableAvailable) sqlStatementContext).getAllTables().size(),
48 () -> new UnsupportedEncryptSQLException("SHOW COLUMNS FOR MULTI TABLE"));
49 tableName = ((TableAvailable) sqlStatementContext).getAllTables().iterator().next().getTableName().getIdentifier().getValue();
50 this.encryptRule = encryptRule;
51 }
52
53 @Override
54 public final boolean next() throws SQLException {
55 boolean hasNext = nextValue();
56 Optional<EncryptTable> encryptTable = encryptRule.findEncryptTable(tableName);
57 if (hasNext && !encryptTable.isPresent()) {
58 return true;
59 }
60 if (!hasNext) {
61 return false;
62 }
63 String columnName = getOriginalValue(COLUMN_FIELD_INDEX, String.class).toString();
64 while (isDerivedColumn(encryptTable.get(), columnName)) {
65 hasNext = nextValue();
66 if (!hasNext) {
67 return false;
68 }
69 columnName = getOriginalValue(COLUMN_FIELD_INDEX, String.class).toString();
70 }
71 return true;
72 }
73
74 private boolean isDerivedColumn(final EncryptTable encryptTable, final String columnName) {
75 return encryptTable.isAssistedQueryColumn(columnName) || encryptTable.isLikeQueryColumn(columnName);
76 }
77
78 @Override
79 public final Object getValue(final int columnIndex, final Class<?> type) throws SQLException {
80 if (COLUMN_FIELD_INDEX == columnIndex) {
81 String columnName = getOriginalValue(COLUMN_FIELD_INDEX, type).toString();
82 Optional<EncryptTable> encryptTable = encryptRule.findEncryptTable(tableName);
83 if (!encryptTable.isPresent()) {
84 return columnName;
85 }
86 Optional<String> logicColumn = encryptTable.get().isCipherColumn(columnName) ? Optional.of(encryptTable.get().getLogicColumnByCipherColumn(columnName)) : Optional.empty();
87 return logicColumn.orElse(columnName);
88 }
89 return getOriginalValue(columnIndex, type);
90 }
91
92 @Override
93 public final Object getCalendarValue(final int columnIndex, final Class<?> type, final Calendar calendar) throws SQLException {
94 throw new SQLFeatureNotSupportedException("");
95 }
96
97 @Override
98 public final InputStream getInputStream(final int columnIndex, final String type) throws SQLException {
99 throw new SQLFeatureNotSupportedException("");
100 }
101
102 @Override
103 public Reader getCharacterStream(final int columnIndex) throws SQLException {
104 throw new SQLFeatureNotSupportedException("");
105 }
106
107 protected abstract boolean nextValue() throws SQLException;
108
109 protected abstract Object getOriginalValue(int columnIndex, Class<?> type) throws SQLException;
110 }