You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by wu...@apache.org on 2023/06/11 07:39:20 UTC
[shardingsphere] branch master updated: Refactor EncryptAlterTableTokenGenerator (#26255)
This is an automated email from the ASF dual-hosted git repository.
wuweijie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new ad6bda50d95 Refactor EncryptAlterTableTokenGenerator (#26255)
ad6bda50d95 is described below
commit ad6bda50d95fc58658f2e600012613e369105e1b
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Sun Jun 11 15:39:12 2023 +0800
Refactor EncryptAlterTableTokenGenerator (#26255)
* Remove EncryptRule.findEncryptColumn
* Refactor EncryptAlterTableTokenGenerator
* Refactor EncryptAlterTableTokenGenerator
* Refactor EncryptAlterTableTokenGenerator
* Refactor EncryptAlterTableTokenGenerator
---
.../generator/EncryptAlterTableTokenGenerator.java | 172 ++++++++++-----------
.../shardingsphere/encrypt/rule/EncryptTable.java | 13 ++
.../impl/EncryptAlterTableTokenGeneratorTest.java | 97 ++++++------
3 files changed, 147 insertions(+), 135 deletions(-)
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptAlterTableTokenGenerator.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptAlterTableTokenGenerator.java
index 53bf8e3c428..da5b1ec3f44 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptAlterTableTokenGenerator.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptAlterTableTokenGenerator.java
@@ -20,12 +20,12 @@ package org.apache.shardingsphere.encrypt.rewrite.token.generator;
import lombok.Setter;
import org.apache.shardingsphere.encrypt.api.encrypt.standard.StandardEncryptAlgorithm;
import org.apache.shardingsphere.encrypt.exception.metadata.EncryptColumnAlterException;
-import org.apache.shardingsphere.encrypt.exception.metadata.EncryptColumnNotFoundException;
import org.apache.shardingsphere.encrypt.rewrite.aware.EncryptRuleAware;
import org.apache.shardingsphere.encrypt.rewrite.token.pojo.EncryptAlterTableToken;
import org.apache.shardingsphere.encrypt.rule.EncryptColumn;
import org.apache.shardingsphere.encrypt.rule.EncryptColumnItem;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
+import org.apache.shardingsphere.encrypt.rule.EncryptTable;
import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.binder.statement.ddl.AlterTableStatementContext;
import org.apache.shardingsphere.infra.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
@@ -63,10 +63,14 @@ public final class EncryptAlterTableTokenGenerator implements CollectionSQLToken
@Override
public Collection<SQLToken> generateSQLTokens(final AlterTableStatementContext alterTableStatementContext) {
String tableName = alterTableStatementContext.getSqlStatement().getTable().getTableName().getIdentifier().getValue();
- Collection<SQLToken> result = new LinkedList<>(getAddColumnTokens(tableName, alterTableStatementContext.getSqlStatement().getAddColumnDefinitions()));
- result.addAll(getModifyColumnTokens(tableName, alterTableStatementContext.getSqlStatement().getModifyColumnDefinitions()));
- result.addAll(getChangeColumnTokens(tableName, alterTableStatementContext.getSqlStatement().getChangeColumnDefinitions()));
- List<SQLToken> dropColumnTokens = getDropColumnTokens(tableName, alterTableStatementContext.getSqlStatement().getDropColumnDefinitions());
+ Optional<EncryptTable> encryptTable = encryptRule.findEncryptTable(tableName);
+ if (!encryptTable.isPresent()) {
+ return Collections.emptyList();
+ }
+ Collection<SQLToken> result = new LinkedList<>(getAddColumnTokens(tableName, encryptTable.get(), alterTableStatementContext.getSqlStatement().getAddColumnDefinitions()));
+ result.addAll(getModifyColumnTokens(tableName, encryptTable.get(), alterTableStatementContext.getSqlStatement().getModifyColumnDefinitions()));
+ result.addAll(getChangeColumnTokens(tableName, encryptTable.get(), alterTableStatementContext.getSqlStatement().getChangeColumnDefinitions()));
+ List<SQLToken> dropColumnTokens = getDropColumnTokens(tableName, encryptTable.get(), alterTableStatementContext.getSqlStatement().getDropColumnDefinitions());
String databaseName = alterTableStatementContext.getDatabaseType().getType();
if ("SQLServer".equals(databaseName)) {
result.addAll(mergeDropColumnStatement(dropColumnTokens, "", ""));
@@ -78,155 +82,125 @@ public final class EncryptAlterTableTokenGenerator implements CollectionSQLToken
return result;
}
- private Collection<SQLToken> mergeDropColumnStatement(final List<SQLToken> dropSQLTokens, final String leftJoiner, final String rightJoiner) {
- Collection<SQLToken> result = new LinkedList<>();
- Collection<String> dropColumns = new LinkedList<>();
- int lastStartIndex = -1;
- for (int i = 0; i < dropSQLTokens.size(); i++) {
- SQLToken token = dropSQLTokens.get(i);
- if (token instanceof RemoveToken) {
- result.add(0 == i ? token : new RemoveToken(lastStartIndex, ((RemoveToken) token).getStopIndex()));
- } else {
- EncryptAlterTableToken encryptAlterTableToken = (EncryptAlterTableToken) token;
- dropColumns.add(encryptAlterTableToken.getColumnName());
- if (i == dropSQLTokens.size() - 1) {
- result.add(new EncryptAlterTableToken(token.getStartIndex(), encryptAlterTableToken.getStopIndex(), leftJoiner + String.join(",", dropColumns) + rightJoiner, "DROP COLUMN"));
- }
- }
- lastStartIndex = ((Substitutable) token).getStartIndex();
- }
- return result;
- }
-
- private Collection<SQLToken> getAddColumnTokens(final String tableName, final Collection<AddColumnDefinitionSegment> columnDefinitionSegments) {
+ private Collection<SQLToken> getAddColumnTokens(final String tableName, final EncryptTable encryptTable, final Collection<AddColumnDefinitionSegment> columnDefinitionSegments) {
Collection<SQLToken> result = new LinkedList<>();
for (AddColumnDefinitionSegment each : columnDefinitionSegments) {
- result.addAll(getAddColumnTokens(tableName, each));
+ result.addAll(getAddColumnTokens(tableName, encryptTable, each));
}
return result;
}
@SuppressWarnings("rawtypes")
- private Collection<SQLToken> getAddColumnTokens(final String tableName, final AddColumnDefinitionSegment addColumnDefinitionSegment) {
+ private Collection<SQLToken> getAddColumnTokens(final String tableName, final EncryptTable encryptTable, final AddColumnDefinitionSegment addColumnDefinitionSegment) {
Collection<SQLToken> result = new LinkedList<>();
for (ColumnDefinitionSegment each : addColumnDefinitionSegment.getColumnDefinitions()) {
String columnName = each.getColumnName().getIdentifier().getValue();
Optional<StandardEncryptAlgorithm> encryptor = encryptRule.findStandardEncryptor(tableName, columnName);
if (encryptor.isPresent()) {
- result.addAll(getAddColumnTokens(tableName, columnName, addColumnDefinitionSegment, each));
+ result.addAll(getAddColumnTokens(encryptTable, columnName, addColumnDefinitionSegment, each));
}
}
- getAddColumnPositionToken(tableName, addColumnDefinitionSegment).ifPresent(result::add);
+ getAddColumnPositionToken(tableName, encryptTable, addColumnDefinitionSegment).ifPresent(result::add);
return result;
}
- private Collection<SQLToken> getAddColumnTokens(final String tableName, final String columnName,
+ private Collection<SQLToken> getAddColumnTokens(final EncryptTable encryptTable, final String columnName,
final AddColumnDefinitionSegment addColumnDefinitionSegment, final ColumnDefinitionSegment columnDefinitionSegment) {
Collection<SQLToken> result = new LinkedList<>();
result.add(new RemoveToken(columnDefinitionSegment.getStartIndex(), columnDefinitionSegment.getColumnName().getStopIndex()));
result.add(new EncryptAlterTableToken(columnDefinitionSegment.getColumnName().getStopIndex() + 1, columnDefinitionSegment.getColumnName().getStopIndex(),
- encryptRule.getCipherColumn(tableName, columnName), null));
- Optional<String> assistedQueryColumn = encryptRule.findAssistedQueryColumn(tableName, columnName);
- assistedQueryColumn.map(optional -> new EncryptAlterTableToken(
+ encryptTable.getCipherColumn(columnName), null));
+ encryptTable.findAssistedQueryColumn(columnName).map(optional -> new EncryptAlterTableToken(
addColumnDefinitionSegment.getStopIndex() + 1, columnDefinitionSegment.getColumnName().getStopIndex(), optional, ", ADD COLUMN")).ifPresent(result::add);
- Optional<String> likeQueryColumn = encryptRule.findLikeQueryColumn(tableName, columnName);
- likeQueryColumn.map(optional -> new EncryptAlterTableToken(
+ encryptTable.findLikeQueryColumn(columnName).map(optional -> new EncryptAlterTableToken(
addColumnDefinitionSegment.getStopIndex() + 1, columnDefinitionSegment.getColumnName().getStopIndex(), optional, ", ADD COLUMN")).ifPresent(result::add);
return result;
}
- private EncryptColumn getEncryptColumn(final String tableName, final String columnName) {
- return encryptRule.findEncryptTable(tableName).flatMap(optional -> optional.findEncryptColumn(columnName)).orElseThrow(() -> new EncryptColumnNotFoundException(tableName, columnName));
- }
-
@SuppressWarnings("rawtypes")
- private Optional<SQLToken> getAddColumnPositionToken(final String tableName, final AddColumnDefinitionSegment addColumnDefinitionSegment) {
+ private Optional<SQLToken> getAddColumnPositionToken(final String tableName, final EncryptTable encryptTable, final AddColumnDefinitionSegment addColumnDefinitionSegment) {
Optional<StandardEncryptAlgorithm> encryptor = addColumnDefinitionSegment.getColumnPosition().filter(optional -> null != optional.getColumnName())
.flatMap(optional -> encryptRule.findStandardEncryptor(tableName, optional.getColumnName().getIdentifier().getValue()));
- if (encryptor.isPresent()) {
- return Optional.of(getPositionColumnToken(addColumnDefinitionSegment.getColumnPosition().get(), tableName));
- }
- return Optional.empty();
- }
-
- private EncryptAlterTableToken getPositionColumnToken(final ColumnPositionSegment positionSegment, final String tableName) {
- return new EncryptAlterTableToken(positionSegment.getColumnName().getStartIndex(), positionSegment.getStopIndex(), encryptRule
- .getCipherColumn(tableName, positionSegment.getColumnName().getIdentifier().getValue()), null);
+ return encryptor.isPresent() ? Optional.of(getPositionColumnToken(encryptTable, addColumnDefinitionSegment.getColumnPosition().get())) : Optional.empty();
}
@SuppressWarnings("rawtypes")
- private Collection<SQLToken> getModifyColumnTokens(final String tableName, final Collection<ModifyColumnDefinitionSegment> columnDefinitionSegments) {
+ private Collection<SQLToken> getModifyColumnTokens(final String tableName, final EncryptTable encryptTable, final Collection<ModifyColumnDefinitionSegment> columnDefinitionSegments) {
Collection<SQLToken> result = new LinkedList<>();
for (ModifyColumnDefinitionSegment each : columnDefinitionSegments) {
- ColumnDefinitionSegment segment = each.getColumnDefinition();
- String columnName = segment.getColumnName().getIdentifier().getValue();
+ String columnName = each.getColumnDefinition().getColumnName().getIdentifier().getValue();
Optional<StandardEncryptAlgorithm> encryptor = encryptRule.findStandardEncryptor(tableName, columnName);
if (encryptor.isPresent()) {
- result.addAll(getModifyColumnTokens(tableName, columnName, each));
+ result.addAll(getModifyColumnTokens(encryptTable, columnName, each));
}
- each.getColumnPosition().flatMap(optional -> getColumnPositionToken(tableName, optional)).ifPresent(result::add);
+ each.getColumnPosition().flatMap(optional -> getColumnPositionToken(tableName, encryptTable, optional)).ifPresent(result::add);
}
return result;
}
- private Collection<SQLToken> getModifyColumnTokens(final String tableName, final String columnName,
- final ModifyColumnDefinitionSegment modifyColumnDefinitionSegment) {
+ private Collection<SQLToken> getModifyColumnTokens(final EncryptTable encryptTable, final String columnName, final ModifyColumnDefinitionSegment modifyColumnDefinitionSegment) {
Collection<SQLToken> result = new LinkedList<>();
ColumnDefinitionSegment columnDefinitionSegment = modifyColumnDefinitionSegment.getColumnDefinition();
result.add(new RemoveToken(columnDefinitionSegment.getColumnName().getStartIndex(), columnDefinitionSegment.getColumnName().getStopIndex()));
result.add(new EncryptAlterTableToken(columnDefinitionSegment.getColumnName().getStopIndex() + 1, columnDefinitionSegment.getColumnName().getStopIndex(),
- encryptRule.getCipherColumn(tableName, columnName), null));
- encryptRule.findAssistedQueryColumn(tableName, columnName).map(optional -> new EncryptAlterTableToken(modifyColumnDefinitionSegment.getStopIndex() + 1,
+ encryptTable.getCipherColumn(columnName), null));
+ encryptTable.findAssistedQueryColumn(columnName).map(optional -> new EncryptAlterTableToken(modifyColumnDefinitionSegment.getStopIndex() + 1,
columnDefinitionSegment.getColumnName().getStopIndex(), optional, ", MODIFY COLUMN")).ifPresent(result::add);
- encryptRule.findLikeQueryColumn(tableName, columnName).map(optional -> new EncryptAlterTableToken(modifyColumnDefinitionSegment.getStopIndex() + 1,
+ encryptTable.findLikeQueryColumn(columnName).map(optional -> new EncryptAlterTableToken(modifyColumnDefinitionSegment.getStopIndex() + 1,
columnDefinitionSegment.getColumnName().getStopIndex(), optional, ", MODIFY COLUMN")).ifPresent(result::add);
return result;
}
+ private EncryptAlterTableToken getPositionColumnToken(final EncryptTable encryptTable, final ColumnPositionSegment positionSegment) {
+ return new EncryptAlterTableToken(positionSegment.getColumnName().getStartIndex(), positionSegment.getStopIndex(),
+ encryptTable.getCipherColumn(positionSegment.getColumnName().getIdentifier().getValue()), null);
+ }
+
@SuppressWarnings("rawtypes")
- private Optional<SQLToken> getColumnPositionToken(final String tableName, final ColumnPositionSegment columnPositionSegment) {
+ private Optional<SQLToken> getColumnPositionToken(final String tableName, final EncryptTable encryptTable, final ColumnPositionSegment columnPositionSegment) {
Optional<StandardEncryptAlgorithm> encryptor = Optional.of(columnPositionSegment).filter(optional -> null != optional.getColumnName())
.flatMap(optional -> encryptRule.findStandardEncryptor(tableName, optional.getColumnName().getIdentifier().getValue()));
- return encryptor.isPresent() ? Optional.of(getPositionColumnToken(columnPositionSegment, tableName)) : Optional.empty();
+ return encryptor.isPresent() ? Optional.of(getPositionColumnToken(encryptTable, columnPositionSegment)) : Optional.empty();
}
- private Collection<SQLToken> getChangeColumnTokens(final String tableName, final Collection<ChangeColumnDefinitionSegment> changeColumnDefinitions) {
+ private Collection<SQLToken> getChangeColumnTokens(final String tableName, final EncryptTable encryptTable, final Collection<ChangeColumnDefinitionSegment> changeColumnDefinitions) {
Collection<SQLToken> result = new LinkedList<>();
for (ChangeColumnDefinitionSegment each : changeColumnDefinitions) {
- result.addAll(getChangeColumnTokensEach(tableName, each));
- each.getColumnPosition().flatMap(optional -> getColumnPositionToken(tableName, optional)).ifPresent(result::add);
+ result.addAll(getChangeColumnTokens(tableName, encryptTable, each));
+ each.getColumnPosition().flatMap(optional -> getColumnPositionToken(tableName, encryptTable, optional)).ifPresent(result::add);
}
return result;
}
- private Collection<? extends SQLToken> getChangeColumnTokensEach(final String tableName, final ChangeColumnDefinitionSegment segment) {
- isSameEncryptColumn(tableName, segment);
+ private Collection<? extends SQLToken> getChangeColumnTokens(final String tableName, final EncryptTable encryptTable, final ChangeColumnDefinitionSegment segment) {
+ isSameEncryptColumn(tableName, encryptTable, segment);
if (!encryptRule.findStandardEncryptor(tableName, segment.getPreviousColumn().getIdentifier().getValue()).isPresent()
|| !encryptRule.findStandardEncryptor(tableName, segment.getColumnDefinition().getColumnName().getIdentifier().getValue()).isPresent()) {
return Collections.emptyList();
}
Collection<SQLToken> result = new LinkedList<>();
- result.addAll(getPreviousColumnTokens(tableName, segment));
- result.addAll(getColumnTokens(tableName, segment));
+ result.addAll(getPreviousColumnTokens(encryptTable, segment));
+ result.addAll(getColumnTokens(encryptTable, segment));
return result;
}
@SuppressWarnings("rawtypes")
- private void isSameEncryptColumn(final String tableName, final ChangeColumnDefinitionSegment segment) {
+ private void isSameEncryptColumn(final String tableName, final EncryptTable encryptTable, final ChangeColumnDefinitionSegment segment) {
Optional<StandardEncryptAlgorithm> previousAlgorithm = encryptRule.findStandardEncryptor(tableName, segment.getPreviousColumn().getIdentifier().getValue());
Optional<StandardEncryptAlgorithm> currentAlgorithm = encryptRule.findStandardEncryptor(tableName, segment.getColumnDefinition().getColumnName().getIdentifier().getValue());
if (!previousAlgorithm.isPresent() && !currentAlgorithm.isPresent()) {
return;
}
- if (previousAlgorithm.isPresent() && currentAlgorithm.isPresent() && previousAlgorithm.get().equals(currentAlgorithm.get()) && checkPreviousAndAfterHasSameColumnNumber(tableName, segment)) {
+ if (previousAlgorithm.isPresent()
+ && currentAlgorithm.isPresent() && previousAlgorithm.get().equals(currentAlgorithm.get()) && checkPreviousAndAfterHasSameColumnNumber(encryptTable, segment)) {
return;
}
throw new EncryptColumnAlterException(tableName, segment.getColumnDefinition().getColumnName().getIdentifier().getValue(), segment.getPreviousColumn().getIdentifier().getValue());
}
- private boolean checkPreviousAndAfterHasSameColumnNumber(final String tableName, final ChangeColumnDefinitionSegment segment) {
- EncryptColumn previousColumn = getEncryptColumn(tableName, segment.getPreviousColumn().getIdentifier().getValue());
- EncryptColumn currentColumn = getEncryptColumn(tableName, segment.getColumnDefinition().getColumnName().getIdentifier().getValue());
+ private boolean checkPreviousAndAfterHasSameColumnNumber(final EncryptTable encryptTable, final ChangeColumnDefinitionSegment changeColumnDefinitionSegment) {
+ EncryptColumn previousColumn = encryptTable.getEncryptColumn(changeColumnDefinitionSegment.getPreviousColumn().getIdentifier().getValue());
+ EncryptColumn currentColumn = encryptTable.getEncryptColumn(changeColumnDefinitionSegment.getColumnDefinition().getColumnName().getIdentifier().getValue());
if (previousColumn.getAssistedQuery().isPresent() && !currentColumn.getAssistedQuery().isPresent()) {
return false;
}
@@ -236,62 +210,82 @@ public final class EncryptAlterTableTokenGenerator implements CollectionSQLToken
return previousColumn.getAssistedQuery().isPresent() || !currentColumn.getAssistedQuery().isPresent();
}
- private Collection<? extends SQLToken> getColumnTokens(final String tableName, final ChangeColumnDefinitionSegment segment) {
+ private Collection<? extends SQLToken> getColumnTokens(final EncryptTable encryptTable, final ChangeColumnDefinitionSegment segment) {
Collection<SQLToken> result = new LinkedList<>();
result.add(new RemoveToken(segment.getColumnDefinition().getColumnName().getStartIndex(), segment.getColumnDefinition().getColumnName().getStopIndex()));
result.add(new EncryptAlterTableToken(segment.getColumnDefinition().getColumnName().getStopIndex() + 1, segment.getColumnDefinition().getColumnName().getStopIndex(),
- encryptRule.getCipherColumn(tableName, segment.getColumnDefinition().getColumnName().getIdentifier().getValue()), null));
+ encryptTable.getCipherColumn(segment.getColumnDefinition().getColumnName().getIdentifier().getValue()), null));
String previousColumnName = segment.getPreviousColumn().getIdentifier().getValue();
- EncryptColumn encryptColumn = getEncryptColumn(tableName, segment.getColumnDefinition().getColumnName().getIdentifier().getValue());
- encryptRule.findAssistedQueryColumn(tableName, previousColumnName)
+ EncryptColumn encryptColumn = encryptTable.getEncryptColumn(segment.getColumnDefinition().getColumnName().getIdentifier().getValue());
+ encryptTable.findAssistedQueryColumn(previousColumnName)
.map(optional -> new EncryptAlterTableToken(segment.getStopIndex() + 1, segment.getColumnDefinition().getColumnName().getStopIndex(),
encryptColumn.getAssistedQuery().map(EncryptColumnItem::getName).orElse(""), ", CHANGE COLUMN " + optional))
.ifPresent(result::add);
- encryptRule.findLikeQueryColumn(tableName, previousColumnName)
+ encryptTable.findLikeQueryColumn(previousColumnName)
.map(optional -> new EncryptAlterTableToken(segment.getStopIndex() + 1, segment.getColumnDefinition().getColumnName().getStopIndex(),
encryptColumn.getLikeQuery().map(EncryptColumnItem::getName).orElse(""), ", CHANGE COLUMN " + optional))
.ifPresent(result::add);
return result;
}
- private Collection<? extends SQLToken> getPreviousColumnTokens(final String tableName, final ChangeColumnDefinitionSegment segment) {
+ private Collection<? extends SQLToken> getPreviousColumnTokens(final EncryptTable encryptTable, final ChangeColumnDefinitionSegment segment) {
Collection<SQLToken> result = new LinkedList<>();
result.add(new RemoveToken(segment.getPreviousColumn().getStartIndex(), segment.getPreviousColumn().getStopIndex()));
result.add(new EncryptAlterTableToken(segment.getPreviousColumn().getStopIndex() + 1, segment.getPreviousColumn().getStopIndex(),
- encryptRule.getCipherColumn(tableName, segment.getPreviousColumn().getIdentifier().getValue()), null));
+ encryptTable.getCipherColumn(segment.getPreviousColumn().getIdentifier().getValue()), null));
return result;
}
- private List<SQLToken> getDropColumnTokens(final String tableName, final Collection<DropColumnDefinitionSegment> columnDefinitionSegments) {
+ private List<SQLToken> getDropColumnTokens(final String tableName, final EncryptTable encryptTable, final Collection<DropColumnDefinitionSegment> columnDefinitionSegments) {
List<SQLToken> result = new ArrayList<>();
for (DropColumnDefinitionSegment each : columnDefinitionSegments) {
- result.addAll(getDropColumnTokens(tableName, each));
+ result.addAll(getDropColumnTokens(tableName, encryptTable, each));
}
return result;
}
@SuppressWarnings("rawtypes")
- private Collection<SQLToken> getDropColumnTokens(final String tableName, final DropColumnDefinitionSegment dropColumnDefinitionSegment) {
+ private Collection<SQLToken> getDropColumnTokens(final String tableName, final EncryptTable encryptTable, final DropColumnDefinitionSegment dropColumnDefinitionSegment) {
Collection<SQLToken> result = new LinkedList<>();
for (ColumnSegment each : dropColumnDefinitionSegment.getColumns()) {
String columnName = each.getQualifiedName();
Optional<StandardEncryptAlgorithm> encryptor = encryptRule.findStandardEncryptor(tableName, columnName);
if (encryptor.isPresent()) {
- result.addAll(getDropColumnTokens(tableName, columnName, each, dropColumnDefinitionSegment));
+ result.addAll(getDropColumnTokens(encryptTable, columnName, each, dropColumnDefinitionSegment));
}
}
return result;
}
- private Collection<SQLToken> getDropColumnTokens(final String tableName, final String columnName,
+ private Collection<SQLToken> getDropColumnTokens(final EncryptTable encryptTable, final String columnName,
final ColumnSegment columnSegment, final DropColumnDefinitionSegment dropColumnDefinitionSegment) {
Collection<SQLToken> result = new LinkedList<>();
result.add(new RemoveToken(columnSegment.getStartIndex(), columnSegment.getStopIndex()));
- result.add(new EncryptAlterTableToken(columnSegment.getStopIndex() + 1, columnSegment.getStopIndex(), encryptRule.getCipherColumn(tableName, columnName), null));
- encryptRule.findAssistedQueryColumn(tableName, columnName).map(optional -> new EncryptAlterTableToken(dropColumnDefinitionSegment.getStopIndex() + 1,
+ result.add(new EncryptAlterTableToken(columnSegment.getStopIndex() + 1, columnSegment.getStopIndex(), encryptTable.getCipherColumn(columnName), null));
+ encryptTable.findAssistedQueryColumn(columnName).map(optional -> new EncryptAlterTableToken(dropColumnDefinitionSegment.getStopIndex() + 1,
dropColumnDefinitionSegment.getStopIndex(), optional, ", DROP COLUMN")).ifPresent(result::add);
- encryptRule.findLikeQueryColumn(tableName, columnName).map(optional -> new EncryptAlterTableToken(dropColumnDefinitionSegment.getStopIndex() + 1,
+ encryptTable.findLikeQueryColumn(columnName).map(optional -> new EncryptAlterTableToken(dropColumnDefinitionSegment.getStopIndex() + 1,
dropColumnDefinitionSegment.getStopIndex(), optional, ", DROP COLUMN")).ifPresent(result::add);
return result;
}
+
+ private Collection<SQLToken> mergeDropColumnStatement(final List<SQLToken> dropSQLTokens, final String leftJoiner, final String rightJoiner) {
+ Collection<SQLToken> result = new LinkedList<>();
+ Collection<String> dropColumns = new LinkedList<>();
+ int lastStartIndex = -1;
+ for (int i = 0; i < dropSQLTokens.size(); i++) {
+ SQLToken token = dropSQLTokens.get(i);
+ if (token instanceof RemoveToken) {
+ result.add(0 == i ? token : new RemoveToken(lastStartIndex, ((RemoveToken) token).getStopIndex()));
+ } else {
+ EncryptAlterTableToken encryptAlterTableToken = (EncryptAlterTableToken) token;
+ dropColumns.add(encryptAlterTableToken.getColumnName());
+ if (i == dropSQLTokens.size() - 1) {
+ result.add(new EncryptAlterTableToken(token.getStartIndex(), encryptAlterTableToken.getStopIndex(), leftJoiner + String.join(",", dropColumns) + rightJoiner, "DROP COLUMN"));
+ }
+ }
+ lastStartIndex = ((Substitutable) token).getStartIndex();
+ }
+ return result;
+ }
}
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptTable.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptTable.java
index c63a6f664e6..9f6fc0098a0 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptTable.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptTable.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.encrypt.rule;
import org.apache.shardingsphere.encrypt.api.config.rule.EncryptColumnRuleConfiguration;
import org.apache.shardingsphere.encrypt.api.config.rule.EncryptTableRuleConfiguration;
+import org.apache.shardingsphere.encrypt.exception.metadata.EncryptColumnNotFoundException;
import org.apache.shardingsphere.encrypt.exception.metadata.EncryptLogicColumnNotFoundException;
import java.util.Collection;
@@ -33,9 +34,12 @@ import java.util.TreeMap;
*/
public final class EncryptTable {
+ private final String table;
+
private final Map<String, EncryptColumn> columns;
public EncryptTable(final EncryptTableRuleConfiguration config) {
+ table = config.getName();
columns = createEncryptColumns(config);
}
@@ -209,4 +213,13 @@ public final class EncryptTable {
return Optional.ofNullable(columns.get(logicColumnName));
}
+ /**
+ * Get encrypt column.
+ *
+ * @param logicColumnName logic column name
+ * @return encrypt column
+ */
+ public EncryptColumn getEncryptColumn(final String logicColumnName) {
+ return findEncryptColumn(logicColumnName).orElseThrow(() -> new EncryptColumnNotFoundException(table, logicColumnName));
+ }
}
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/impl/EncryptAlterTableTokenGeneratorTest.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/impl/EncryptAlterTableTokenGeneratorTest.java
index da7f629c485..256f09c3981 100644
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/impl/EncryptAlterTableTokenGeneratorTest.java
+++ b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/impl/EncryptAlterTableTokenGeneratorTest.java
@@ -51,28 +51,32 @@ import static org.mockito.Mockito.when;
class EncryptAlterTableTokenGeneratorTest {
- private EncryptAlterTableTokenGenerator generator;
+ private final EncryptAlterTableTokenGenerator generator = new EncryptAlterTableTokenGenerator();
@BeforeEach
void setup() {
- generator = new EncryptAlterTableTokenGenerator();
generator.setEncryptRule(mockEncryptRule());
}
private EncryptRule mockEncryptRule() {
EncryptRule result = mock(EncryptRule.class);
- when(result.getCipherColumn("t_encrypt", "certificate_number")).thenReturn("cipher_certificate_number");
- when(result.findAssistedQueryColumn("t_encrypt", "certificate_number")).thenReturn(Optional.of("assisted_certificate_number"));
- when(result.findLikeQueryColumn("t_encrypt", "certificate_number")).thenReturn(Optional.of("like_certificate_number"));
- EncryptTable encryptTable = mock(EncryptTable.class);
- when(encryptTable.getLogicColumns()).thenReturn(Collections.singleton("t_encrypt"));
- when(encryptTable.findEncryptColumn("certificate_number")).thenReturn(Optional.of(mockEncryptColumn()));
- when(encryptTable.findEncryptColumn("certificate_number_new")).thenReturn(Optional.of(mockNewEncryptColumn()));
+ EncryptTable encryptTable = mockEncryptTable();
+ when(result.findEncryptTable("t_encrypt")).thenReturn(Optional.of(encryptTable));
StandardEncryptAlgorithm<?, ?> encryptAlgorithm = mock(StandardEncryptAlgorithm.class);
when(result.findStandardEncryptor("t_encrypt", "certificate_number")).thenReturn(Optional.of(encryptAlgorithm));
when(result.findStandardEncryptor("t_encrypt", "certificate_number_new")).thenReturn(Optional.of(encryptAlgorithm));
- when(result.findEncryptTable("t_encrypt")).thenReturn(Optional.of(encryptTable));
- when(result.getCipherColumn("t_encrypt", "certificate_number_new")).thenReturn("cipher_certificate_number_new");
+ return result;
+ }
+
+ private EncryptTable mockEncryptTable() {
+ EncryptTable result = mock(EncryptTable.class);
+ when(result.getCipherColumn("certificate_number")).thenReturn("cipher_certificate_number");
+ when(result.findAssistedQueryColumn("certificate_number")).thenReturn(Optional.of("assisted_certificate_number"));
+ when(result.findLikeQueryColumn("certificate_number")).thenReturn(Optional.of("like_certificate_number"));
+ when(result.getLogicColumns()).thenReturn(Collections.singleton("t_encrypt"));
+ when(result.getEncryptColumn("certificate_number")).thenReturn(mockEncryptColumn());
+ when(result.getCipherColumn("certificate_number_new")).thenReturn("cipher_certificate_number_new");
+ when(result.getEncryptColumn("certificate_number_new")).thenReturn(mockNewEncryptColumn());
return result;
}
@@ -92,92 +96,93 @@ class EncryptAlterTableTokenGeneratorTest {
@Test
void assertAddColumnGenerateSQLTokens() {
- Collection<SQLToken> sqlTokens = generator.generateSQLTokens(buildAddColumnStatementContext());
- assertThat(sqlTokens.size(), is(4));
- Iterator<SQLToken> iterator = sqlTokens.iterator();
- assertThat(iterator.next(), instanceOf(RemoveToken.class));
- EncryptAlterTableToken cipherToken = (EncryptAlterTableToken) iterator.next();
+ Collection<SQLToken> actual = generator.generateSQLTokens(mockAddColumnStatementContext());
+ assertThat(actual.size(), is(4));
+ Iterator<SQLToken> actualIterator = actual.iterator();
+ assertThat(actualIterator.next(), instanceOf(RemoveToken.class));
+ EncryptAlterTableToken cipherToken = (EncryptAlterTableToken) actualIterator.next();
assertThat(cipherToken.toString(), is("cipher_certificate_number"));
assertThat(cipherToken.getStartIndex(), is(51));
assertThat(cipherToken.getStopIndex(), is(50));
- EncryptAlterTableToken assistedToken = (EncryptAlterTableToken) iterator.next();
+ EncryptAlterTableToken assistedToken = (EncryptAlterTableToken) actualIterator.next();
assertThat(assistedToken.toString(), is(", ADD COLUMN assisted_certificate_number"));
assertThat(assistedToken.getStartIndex(), is(68));
assertThat(assistedToken.getStopIndex(), is(50));
- EncryptAlterTableToken likeToken = (EncryptAlterTableToken) iterator.next();
+ EncryptAlterTableToken likeToken = (EncryptAlterTableToken) actualIterator.next();
assertThat(likeToken.toString(), is(", ADD COLUMN like_certificate_number"));
assertThat(likeToken.getStartIndex(), is(68));
assertThat(likeToken.getStopIndex(), is(50));
}
- private AlterTableStatementContext buildAddColumnStatementContext() {
+ private AlterTableStatementContext mockAddColumnStatementContext() {
AlterTableStatementContext result = mock(AlterTableStatementContext.class, RETURNS_DEEP_STUBS);
when(result.getSqlStatement().getTable().getTableName().getIdentifier().getValue()).thenReturn("t_encrypt");
- ColumnDefinitionSegment segment = new ColumnDefinitionSegment(33, 67, new ColumnSegment(33, 50, new IdentifierValue("certificate_number")), new DataTypeSegment(), false, false);
- AddColumnDefinitionSegment addColumnDefinitionSegment = new AddColumnDefinitionSegment(22, 67, Collections.singletonList(segment));
- when(result.getSqlStatement().getAddColumnDefinitions()).thenReturn(Collections.singletonList(addColumnDefinitionSegment));
+ ColumnDefinitionSegment columnDefinitionSegment = new ColumnDefinitionSegment(
+ 33, 67, new ColumnSegment(33, 50, new IdentifierValue("certificate_number")), new DataTypeSegment(), false, false);
+ when(result.getSqlStatement().getAddColumnDefinitions()).thenReturn(Collections.singleton(new AddColumnDefinitionSegment(22, 67, Collections.singleton(columnDefinitionSegment))));
return result;
}
@Test
void assertModifyColumnGenerateSQLTokens() {
- Collection<SQLToken> sqlTokens = generator.generateSQLTokens(buildModifyColumnStatementContext());
- assertThat(sqlTokens.size(), is(4));
- Iterator<SQLToken> iterator = sqlTokens.iterator();
- assertThat(iterator.next(), instanceOf(RemoveToken.class));
- EncryptAlterTableToken cipherToken = (EncryptAlterTableToken) iterator.next();
+ Collection<SQLToken> actual = generator.generateSQLTokens(mockModifyColumnStatementContext());
+ assertThat(actual.size(), is(4));
+ Iterator<SQLToken> actualIterator = actual.iterator();
+ assertThat(actualIterator.next(), instanceOf(RemoveToken.class));
+ EncryptAlterTableToken cipherToken = (EncryptAlterTableToken) actualIterator.next();
assertThat(cipherToken.toString(), is("cipher_certificate_number"));
assertThat(cipherToken.getStartIndex(), is(54));
assertThat(cipherToken.getStopIndex(), is(53));
- EncryptAlterTableToken assistedToken = (EncryptAlterTableToken) iterator.next();
+ EncryptAlterTableToken assistedToken = (EncryptAlterTableToken) actualIterator.next();
assertThat(assistedToken.toString(), is(", MODIFY COLUMN assisted_certificate_number"));
assertThat(assistedToken.getStartIndex(), is(71));
assertThat(assistedToken.getStopIndex(), is(53));
- EncryptAlterTableToken likeToken = (EncryptAlterTableToken) iterator.next();
+ EncryptAlterTableToken likeToken = (EncryptAlterTableToken) actualIterator.next();
assertThat(likeToken.toString(), is(", MODIFY COLUMN like_certificate_number"));
assertThat(likeToken.getStartIndex(), is(71));
assertThat(likeToken.getStopIndex(), is(53));
}
- private AlterTableStatementContext buildModifyColumnStatementContext() {
+ private AlterTableStatementContext mockModifyColumnStatementContext() {
AlterTableStatementContext result = mock(AlterTableStatementContext.class, RETURNS_DEEP_STUBS);
when(result.getSqlStatement().getTable().getTableName().getIdentifier().getValue()).thenReturn("t_encrypt");
- ColumnDefinitionSegment segment = new ColumnDefinitionSegment(36, 70, new ColumnSegment(36, 53, new IdentifierValue("certificate_number")), new DataTypeSegment(), false, false);
- ModifyColumnDefinitionSegment modifyColumnDefinitionSegment = new ModifyColumnDefinitionSegment(22, 70, segment);
- when(result.getSqlStatement().getModifyColumnDefinitions()).thenReturn(Collections.singletonList(modifyColumnDefinitionSegment));
+ ColumnDefinitionSegment columnDefinitionSegment = new ColumnDefinitionSegment(
+ 36, 70, new ColumnSegment(36, 53, new IdentifierValue("certificate_number")), new DataTypeSegment(), false, false);
+ when(result.getSqlStatement().getModifyColumnDefinitions()).thenReturn(Collections.singleton(new ModifyColumnDefinitionSegment(22, 70, columnDefinitionSegment)));
return result;
}
@Test
void assertChangeColumnGenerateSQLTokens() {
- Collection<SQLToken> sqlTokens = generator.generateSQLTokens(buildChangeColumnStatementContext());
- assertThat(sqlTokens.size(), is(6));
- Iterator<SQLToken> iterator = sqlTokens.iterator();
- assertThat(iterator.next(), instanceOf(RemoveToken.class));
- EncryptAlterTableToken previous = (EncryptAlterTableToken) iterator.next();
+ Collection<SQLToken> actual = generator.generateSQLTokens(mockChangeColumnStatementContext());
+ assertThat(actual.size(), is(6));
+ Iterator<SQLToken> actualIterator = actual.iterator();
+ assertThat(actualIterator.next(), instanceOf(RemoveToken.class));
+ EncryptAlterTableToken previous = (EncryptAlterTableToken) actualIterator.next();
assertThat(previous.toString(), is("cipher_certificate_number"));
- assertThat(iterator.next(), instanceOf(RemoveToken.class));
- EncryptAlterTableToken cipherToken = (EncryptAlterTableToken) iterator.next();
+ assertThat(actualIterator.next(), instanceOf(RemoveToken.class));
+ EncryptAlterTableToken cipherToken = (EncryptAlterTableToken) actualIterator.next();
assertThat(cipherToken.toString(), is("cipher_certificate_number_new"));
assertThat(cipherToken.getStartIndex(), is(77));
assertThat(cipherToken.getStopIndex(), is(76));
- EncryptAlterTableToken assistedToken = (EncryptAlterTableToken) iterator.next();
+ EncryptAlterTableToken assistedToken = (EncryptAlterTableToken) actualIterator.next();
assertThat(assistedToken.toString(), is(", CHANGE COLUMN assisted_certificate_number assisted_certificate_number_new"));
assertThat(assistedToken.getStartIndex(), is(94));
assertThat(assistedToken.getStopIndex(), is(76));
- EncryptAlterTableToken likeToken = (EncryptAlterTableToken) iterator.next();
+ EncryptAlterTableToken likeToken = (EncryptAlterTableToken) actualIterator.next();
assertThat(likeToken.toString(), is(", CHANGE COLUMN like_certificate_number like_certificate_number_new"));
assertThat(likeToken.getStartIndex(), is(94));
assertThat(likeToken.getStopIndex(), is(76));
}
- private AlterTableStatementContext buildChangeColumnStatementContext() {
+ private AlterTableStatementContext mockChangeColumnStatementContext() {
AlterTableStatementContext result = mock(AlterTableStatementContext.class, RETURNS_DEEP_STUBS);
when(result.getSqlStatement().getTable().getTableName().getIdentifier().getValue()).thenReturn("t_encrypt");
- ColumnDefinitionSegment segment = new ColumnDefinitionSegment(55, 93, new ColumnSegment(55, 76, new IdentifierValue("certificate_number_new")), new DataTypeSegment(), false, false);
- ChangeColumnDefinitionSegment changeColumnDefinitionSegment = new ChangeColumnDefinitionSegment(22, 93, segment);
+ ColumnDefinitionSegment columnDefinitionSegment = new ColumnDefinitionSegment(
+ 55, 93, new ColumnSegment(55, 76, new IdentifierValue("certificate_number_new")), new DataTypeSegment(), false, false);
+ ChangeColumnDefinitionSegment changeColumnDefinitionSegment = new ChangeColumnDefinitionSegment(22, 93, columnDefinitionSegment);
changeColumnDefinitionSegment.setPreviousColumn(new ColumnSegment(36, 53, new IdentifierValue("certificate_number")));
- when(result.getSqlStatement().getChangeColumnDefinitions()).thenReturn(Collections.singletonList(changeColumnDefinitionSegment));
+ when(result.getSqlStatement().getChangeColumnDefinitions()).thenReturn(Collections.singleton(changeColumnDefinitionSegment));
return result;
}
}