1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind;
19
20 import lombok.Getter;
21 import org.apache.shardingsphere.db.protocol.postgresql.constant.PostgreSQLValueFormat;
22 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.PostgreSQLCommandPacket;
23 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.PostgreSQLCommandPacketType;
24 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.PostgreSQLColumnType;
25 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.PostgreSQLBinaryProtocolValue;
26 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.PostgreSQLBinaryProtocolValueFactory;
27 import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLIdentifierTag;
28 import org.apache.shardingsphere.db.protocol.postgresql.payload.PostgreSQLPacketPayload;
29
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.List;
33
34
35
36
37 public final class PostgreSQLComBindPacket extends PostgreSQLCommandPacket {
38
39 private final PostgreSQLPacketPayload payload;
40
41 @Getter
42 private final String portal;
43
44 @Getter
45 private final String statementId;
46
47 public PostgreSQLComBindPacket(final PostgreSQLPacketPayload payload) {
48 this.payload = payload;
49 payload.readInt4();
50 portal = payload.readStringNul();
51 statementId = payload.readStringNul();
52 }
53
54
55
56
57
58
59
60 public List<Object> readParameters(final List<PostgreSQLColumnType> paramTypes) {
61 List<Integer> paramFormats = getParameterFormats();
62 int parameterCount = payload.readInt2();
63 List<Object> result = new ArrayList<>(parameterCount);
64 for (int paramIndex = 0; paramIndex < parameterCount; paramIndex++) {
65 int parameterValueLength = payload.readInt4();
66 if (-1 == parameterValueLength) {
67 result.add(null);
68 continue;
69 }
70 Object paramValue = isTextParameterValue(paramFormats, paramIndex)
71 ? getTextParameterValue(payload, parameterValueLength, paramTypes.get(paramIndex))
72 : getBinaryParameterValue(payload, parameterValueLength, paramTypes.get(paramIndex));
73 result.add(paramValue);
74 }
75 return result;
76 }
77
78 private List<Integer> getParameterFormats() {
79 int parameterFormatCount = payload.readInt2();
80 List<Integer> result = new ArrayList<>(parameterFormatCount);
81 for (int i = 0; i < parameterFormatCount; i++) {
82 result.add(payload.readInt2());
83 }
84 return result;
85 }
86
87 private boolean isTextParameterValue(final List<Integer> paramFormats, final int paramIndex) {
88 if (paramFormats.isEmpty()) {
89 return true;
90 }
91 return PostgreSQLValueFormat.TEXT.getCode() == paramFormats.get(1 == paramFormats.size() ? 0 : paramIndex);
92 }
93
94 private Object getTextParameterValue(final PostgreSQLPacketPayload payload, final int paramValueLength, final PostgreSQLColumnType paramType) {
95 String value = payload.getByteBuf().readCharSequence(paramValueLength, payload.getCharset()).toString();
96 return paramType.getTextValueParser().parse(value);
97 }
98
99 private Object getBinaryParameterValue(final PostgreSQLPacketPayload payload, final int paramValueLength, final PostgreSQLColumnType paramType) {
100 PostgreSQLBinaryProtocolValue binaryProtocolValue = PostgreSQLBinaryProtocolValueFactory.getBinaryProtocolValue(paramType);
101 return binaryProtocolValue.read(payload, paramValueLength);
102 }
103
104
105
106
107
108
109 public List<PostgreSQLValueFormat> readResultFormats() {
110 int resultFormatsLength = payload.readInt2();
111 if (0 == resultFormatsLength) {
112 return Collections.emptyList();
113 }
114 if (1 == resultFormatsLength) {
115 return Collections.singletonList(PostgreSQLValueFormat.valueOf(payload.readInt2()));
116 }
117 List<PostgreSQLValueFormat> result = new ArrayList<>(resultFormatsLength);
118 for (int i = 0; i < resultFormatsLength; i++) {
119 result.add(PostgreSQLValueFormat.valueOf(payload.readInt2()));
120 }
121 return result;
122 }
123
124 @Override
125 protected void write(final PostgreSQLPacketPayload payload) {
126 }
127
128 @Override
129 public PostgreSQLIdentifierTag getIdentifier() {
130 return PostgreSQLCommandPacketType.BIND_COMMAND;
131 }
132 }