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.postgresql.packet.command.query;
19  
20  import lombok.Getter;
21  import lombok.RequiredArgsConstructor;
22  import org.apache.shardingsphere.db.protocol.binary.BinaryCell;
23  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.PostgreSQLBinaryProtocolValue;
24  import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.bind.protocol.PostgreSQLBinaryProtocolValueFactory;
25  import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLIdentifierPacket;
26  import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLIdentifierTag;
27  import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLMessagePacketType;
28  import org.apache.shardingsphere.db.protocol.postgresql.payload.PostgreSQLPacketPayload;
29  
30  import java.sql.SQLException;
31  import java.sql.SQLXML;
32  import java.util.Collection;
33  
34  /**
35   * Data row packet for PostgreSQL.
36   */
37  @RequiredArgsConstructor
38  @Getter
39  public final class PostgreSQLDataRowPacket extends PostgreSQLIdentifierPacket {
40      
41      private final Collection<Object> data;
42      
43      @Override
44      protected void write(final PostgreSQLPacketPayload payload) {
45          payload.writeInt2(data.size());
46          for (Object each : data) {
47              if (each instanceof BinaryCell) {
48                  writeBinaryValue(payload, (BinaryCell) each);
49              } else {
50                  writeTextValue(payload, each);
51              }
52          }
53      }
54      
55      private void writeBinaryValue(final PostgreSQLPacketPayload payload, final BinaryCell each) {
56          Object value = each.getData();
57          if (null == value) {
58              payload.writeInt4(0xFFFFFFFF);
59              return;
60          }
61          PostgreSQLBinaryProtocolValue binaryProtocolValue = PostgreSQLBinaryProtocolValueFactory.getBinaryProtocolValue(each.getColumnType());
62          payload.writeInt4(binaryProtocolValue.getColumnLength(value));
63          binaryProtocolValue.write(payload, value);
64      }
65      
66      private void writeTextValue(final PostgreSQLPacketPayload payload, final Object each) {
67          if (null == each) {
68              payload.writeInt4(0xFFFFFFFF);
69          } else if (each instanceof byte[]) {
70              payload.writeInt4(((byte[]) each).length);
71              payload.writeBytes((byte[]) each);
72          } else if (each instanceof SQLXML) {
73              writeSQLXMLData(payload, each);
74          } else {
75              byte[] columnData = each.toString().getBytes(payload.getCharset());
76              payload.writeInt4(columnData.length);
77              payload.writeBytes(columnData);
78          }
79      }
80      
81      private void writeSQLXMLData(final PostgreSQLPacketPayload payload, final Object data) {
82          try {
83              byte[] dataBytes = ((SQLXML) data).getString().getBytes(payload.getCharset());
84              payload.writeInt4(dataBytes.length);
85              payload.writeBytes(dataBytes);
86          } catch (final SQLException ex) {
87              throw new IllegalStateException(ex);
88          }
89      }
90      
91      @Override
92      public PostgreSQLIdentifierTag getIdentifier() {
93          return PostgreSQLMessagePacketType.DATA_ROW;
94      }
95  }