1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
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
72
73
74
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 }