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.rewrite.token.pojo;
19  
20  import lombok.Getter;
21  import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.SQLToken;
22  import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.Substitutable;
23  import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
24  import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.FunctionSegment;
25  
26  import java.util.Collection;
27  import java.util.Map;
28  import java.util.concurrent.atomic.AtomicInteger;
29  
30  /**
31   * Predicate in right value token for encrypt.
32   */
33  public final class EncryptPredicateFunctionRightValueToken extends SQLToken implements Substitutable {
34      
35      private static final String COMMA_SEPARATOR = ", ";
36      
37      @Getter
38      private final int stopIndex;
39      
40      private final String functionName;
41      
42      private final Collection<ExpressionSegment> parameters;
43      
44      private final Map<Integer, Object> indexValues;
45      
46      private final Collection<Integer> paramMarkerIndexes;
47      
48      public EncryptPredicateFunctionRightValueToken(final int startIndex, final int stopIndex, final String functionName, final Collection<ExpressionSegment> parameters,
49                                                     final Map<Integer, Object> indexValues, final Collection<Integer> paramMarkerIndexes) {
50          super(startIndex);
51          this.stopIndex = stopIndex;
52          this.functionName = functionName;
53          this.parameters = parameters;
54          this.indexValues = indexValues;
55          this.paramMarkerIndexes = paramMarkerIndexes;
56      }
57      
58      @Override
59      public String toString() {
60          StringBuilder result = new StringBuilder();
61          AtomicInteger parameterIndex = new AtomicInteger();
62          appendFunctionSegment(functionName, parameters, result, parameterIndex);
63          return result.toString();
64      }
65      
66      private void appendFunctionSegment(final String functionName, final Collection<ExpressionSegment> parameters, final StringBuilder builder, final AtomicInteger parameterIndex) {
67          builder.append(functionName).append(" (");
68          for (ExpressionSegment each : parameters) {
69              if (each instanceof FunctionSegment) {
70                  appendFunctionSegment(((FunctionSegment) each).getFunctionName(), ((FunctionSegment) each).getParameters(), builder, parameterIndex);
71                  builder.append(COMMA_SEPARATOR);
72              } else {
73                  appendRewrittenParameters(builder, parameterIndex.getAndIncrement());
74              }
75          }
76          if (builder.toString().endsWith(COMMA_SEPARATOR)) {
77              builder.delete(builder.length() - 2, builder.length());
78          }
79          builder.append(')');
80      }
81      
82      private void appendRewrittenParameters(final StringBuilder builder, final int parameterIndex) {
83          if (paramMarkerIndexes.contains(parameterIndex)) {
84              builder.append('?');
85          } else {
86              if (indexValues.get(parameterIndex) instanceof String) {
87                  builder.append('\'').append(indexValues.get(parameterIndex)).append('\'');
88              } else {
89                  builder.append(indexValues.get(parameterIndex));
90              }
91          }
92          builder.append(COMMA_SEPARATOR);
93      }
94  }