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.generic;
19  
20  import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLIdentifierPacket;
21  import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLIdentifierTag;
22  import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLMessagePacketType;
23  import org.apache.shardingsphere.db.protocol.postgresql.payload.PostgreSQLPacketPayload;
24  import org.opengauss.util.ServerErrorMessage;
25  
26  import java.util.LinkedHashMap;
27  import java.util.Map;
28  import java.util.Map.Entry;
29  
30  /**
31   * Error response packet for openGauss.
32   */
33  public final class OpenGaussErrorResponsePacket extends PostgreSQLIdentifierPacket {
34      
35      public static final char FIELD_TYPE_SEVERITY = 'S';
36      
37      public static final char FIELD_TYPE_CODE = 'C';
38      
39      public static final char FIELD_TYPE_MESSAGE = 'M';
40      
41      public static final char FIELD_TYPE_DETAIL = 'D';
42      
43      public static final char FIELD_TYPE_HINT = 'H';
44      
45      public static final char FIELD_TYPE_POSITION = 'P';
46      
47      public static final char FIELD_TYPE_INTERNAL_POSITION = 'p';
48      
49      public static final char FIELD_TYPE_INTERNAL_QUERY = 'q';
50      
51      public static final char FIELD_TYPE_WHERE = 'W';
52      
53      public static final char FIELD_TYPE_FILE = 'F';
54      
55      public static final char FIELD_TYPE_LINE = 'L';
56      
57      public static final char FIELD_TYPE_ROUTINE = 'R';
58      
59      public static final char FIELD_TYPE_ERROR_CODE = 'c';
60      
61      private final Map<Character, String> fields;
62      
63      public OpenGaussErrorResponsePacket(final ServerErrorMessage serverErrorMessage) {
64          fields = new LinkedHashMap<>(13, 1F);
65          fillFieldsByServerErrorMessage(serverErrorMessage);
66          fillRequiredFieldsIfNecessary();
67      }
68      
69      public OpenGaussErrorResponsePacket(final String severityLevel, final String sqlState, final String message) {
70          fields = new LinkedHashMap<>(4, 1F);
71          fields.put(FIELD_TYPE_SEVERITY, severityLevel);
72          fields.put(FIELD_TYPE_CODE, sqlState);
73          fields.put(FIELD_TYPE_MESSAGE, message);
74          fillRequiredFieldsIfNecessary();
75      }
76      
77      private void fillFieldsByServerErrorMessage(final ServerErrorMessage serverErrorMessage) {
78          if (null != serverErrorMessage.getSeverity()) {
79              fields.put(FIELD_TYPE_SEVERITY, serverErrorMessage.getSeverity());
80          }
81          if (null != serverErrorMessage.getSQLState()) {
82              fields.put(FIELD_TYPE_CODE, serverErrorMessage.getSQLState());
83          }
84          if (null != serverErrorMessage.getMessage()) {
85              fields.put(FIELD_TYPE_MESSAGE, serverErrorMessage.getMessage());
86          }
87          if (null != serverErrorMessage.getERRORCODE()) {
88              fields.put(FIELD_TYPE_ERROR_CODE, serverErrorMessage.getERRORCODE());
89          }
90          if (null != serverErrorMessage.getDetail()) {
91              fields.put(FIELD_TYPE_DETAIL, serverErrorMessage.getDetail());
92          }
93          if (null != serverErrorMessage.getHint()) {
94              fields.put(FIELD_TYPE_HINT, serverErrorMessage.getHint());
95          }
96          if (serverErrorMessage.getPosition() > 0) {
97              fields.put(FIELD_TYPE_POSITION, String.valueOf(serverErrorMessage.getPosition()));
98          }
99          if (serverErrorMessage.getInternalPosition() > 0) {
100             fields.put(FIELD_TYPE_INTERNAL_POSITION, String.valueOf(serverErrorMessage.getInternalPosition()));
101         }
102         if (null != serverErrorMessage.getInternalQuery()) {
103             fields.put(FIELD_TYPE_INTERNAL_QUERY, serverErrorMessage.getInternalQuery());
104         }
105         if (null != serverErrorMessage.getWhere()) {
106             fields.put(FIELD_TYPE_WHERE, serverErrorMessage.getWhere());
107         }
108         if (null != serverErrorMessage.getFile()) {
109             fields.put(FIELD_TYPE_FILE, serverErrorMessage.getFile());
110         }
111         if (serverErrorMessage.getLine() > 0) {
112             fields.put(FIELD_TYPE_LINE, String.valueOf(serverErrorMessage.getLine()));
113         }
114         if (null != serverErrorMessage.getRoutine()) {
115             fields.put(FIELD_TYPE_ROUTINE, serverErrorMessage.getRoutine());
116         }
117     }
118     
119     private void fillRequiredFieldsIfNecessary() {
120         fields.putIfAbsent(FIELD_TYPE_ERROR_CODE, "0");
121     }
122     
123     @Override
124     protected void write(final PostgreSQLPacketPayload payload) {
125         for (Entry<Character, String> entry : fields.entrySet()) {
126             payload.writeInt1(entry.getKey());
127             payload.writeStringNul(entry.getValue());
128         }
129         payload.writeInt1(0);
130     }
131     
132     @Override
133     public PostgreSQLIdentifierTag getIdentifier() {
134         return PostgreSQLMessagePacketType.ERROR_RESPONSE;
135     }
136 }