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.db.protocol.opengauss.packet.command.query.extended.bind;
19  
20  import lombok.Getter;
21  import org.apache.shardingsphere.db.protocol.opengauss.packet.command.OpenGaussCommandPacket;
22  import org.apache.shardingsphere.db.protocol.opengauss.packet.command.OpenGaussCommandPacketType;
23  import org.apache.shardingsphere.db.protocol.opengauss.packet.identifier.OpenGaussIdentifierTag;
24  import org.apache.shardingsphere.db.protocol.postgresql.constant.PostgreSQLValueFormat;
25  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.PostgreSQLColumnType;
26  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.PostgreSQLBinaryProtocolValue;
27  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.PostgreSQLBinaryProtocolValueFactory;
28  import org.apache.shardingsphere.db.protocol.postgresql.payload.PostgreSQLPacketPayload;
29  
30  import java.util.ArrayList;
31  import java.util.List;
32  
33  /**
34   * Batch bind packet for openGauss.
35   */
36  @Getter
37  public final class OpenGaussComBatchBindPacket extends OpenGaussCommandPacket {
38      
39      private final PostgreSQLPacketPayload payload;
40      
41      private final int batchNum;
42      
43      private final String statementId;
44      
45      private final List<Integer> parameterFormats;
46      
47      private final List<PostgreSQLValueFormat> resultFormats;
48      
49      private final int eachGroupParametersCount;
50      
51      public OpenGaussComBatchBindPacket(final PostgreSQLPacketPayload payload) {
52          this.payload = payload;
53          payload.readInt4();
54          batchNum = payload.readInt4();
55          payload.readStringNul();
56          statementId = payload.readStringNul();
57          int parameterFormatCount = payload.readInt2();
58          parameterFormats = new ArrayList<>(parameterFormatCount);
59          for (int i = 0; i < parameterFormatCount; i++) {
60              parameterFormats.add(payload.readInt2());
61          }
62          int resultFormatsLength = payload.readInt2();
63          resultFormats = new ArrayList<>(resultFormatsLength);
64          for (int i = 0; i < resultFormatsLength; i++) {
65              resultFormats.add(PostgreSQLValueFormat.valueOf(payload.readInt2()));
66          }
67          eachGroupParametersCount = payload.readInt2();
68      }
69      
70      /**
71       * Read parameter sets from payload.
72       *
73       * @param parameterTypes types of parameters
74       * @return parameter sets
75       */
76      public List<List<Object>> readParameterSets(final List<PostgreSQLColumnType> parameterTypes) {
77          List<List<Object>> result = new ArrayList<>(batchNum);
78          for (int i = 0; i < batchNum; i++) {
79              result.add(readOneGroupOfParameters(parameterTypes));
80          }
81          payload.skipReserved(payload.getByteBuf().readableBytes());
82          return result;
83      }
84      
85      private List<Object> readOneGroupOfParameters(final List<PostgreSQLColumnType> parameterTypes) {
86          List<Object> result = new ArrayList<>(eachGroupParametersCount);
87          for (int paramIndex = 0; paramIndex < eachGroupParametersCount; paramIndex++) {
88              int paramValueLength = payload.readInt4();
89              if (-1 == paramValueLength) {
90                  result.add(null);
91                  continue;
92              }
93              Object parameterValue = isTextParameterValue(paramIndex)
94                      ? getTextParameters(paramValueLength, parameterTypes.get(paramIndex))
95                      : getBinaryParameters(paramValueLength, parameterTypes.get(paramIndex));
96              result.add(parameterValue);
97          }
98          return result;
99      }
100     
101     private boolean isTextParameterValue(final int paramIndex) {
102         return parameterFormats.isEmpty() || 0 == parameterFormats.get(paramIndex % parameterFormats.size());
103     }
104     
105     private Object getTextParameters(final int paramValueLength, final PostgreSQLColumnType paramType) {
106         String value = payload.getByteBuf().readCharSequence(paramValueLength, payload.getCharset()).toString();
107         return paramType.getTextValueParser().parse(value);
108     }
109     
110     private Object getBinaryParameters(final int paramValueLength, final PostgreSQLColumnType columnType) {
111         PostgreSQLBinaryProtocolValue binaryProtocolValue = PostgreSQLBinaryProtocolValueFactory.getBinaryProtocolValue(columnType);
112         return binaryProtocolValue.read(payload, paramValueLength);
113     }
114     
115     @Override
116     protected void write(final PostgreSQLPacketPayload payload) {
117     }
118     
119     @Override
120     public OpenGaussIdentifierTag getIdentifier() {
121         return OpenGaussCommandPacketType.BATCH_BIND_COMMAND;
122     }
123 }