gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

error_response.go (7725B)


      1 package pgproto3
      2 
      3 import (
      4 	"bytes"
      5 	"encoding/binary"
      6 	"encoding/json"
      7 	"strconv"
      8 )
      9 
     10 type ErrorResponse struct {
     11 	Severity            string
     12 	SeverityUnlocalized string // only in 9.6 and greater
     13 	Code                string
     14 	Message             string
     15 	Detail              string
     16 	Hint                string
     17 	Position            int32
     18 	InternalPosition    int32
     19 	InternalQuery       string
     20 	Where               string
     21 	SchemaName          string
     22 	TableName           string
     23 	ColumnName          string
     24 	DataTypeName        string
     25 	ConstraintName      string
     26 	File                string
     27 	Line                int32
     28 	Routine             string
     29 
     30 	UnknownFields map[byte]string
     31 }
     32 
     33 // Backend identifies this message as sendable by the PostgreSQL backend.
     34 func (*ErrorResponse) Backend() {}
     35 
     36 // Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
     37 // type identifier and 4 byte message length.
     38 func (dst *ErrorResponse) Decode(src []byte) error {
     39 	*dst = ErrorResponse{}
     40 
     41 	buf := bytes.NewBuffer(src)
     42 
     43 	for {
     44 		k, err := buf.ReadByte()
     45 		if err != nil {
     46 			return err
     47 		}
     48 		if k == 0 {
     49 			break
     50 		}
     51 
     52 		vb, err := buf.ReadBytes(0)
     53 		if err != nil {
     54 			return err
     55 		}
     56 		v := string(vb[:len(vb)-1])
     57 
     58 		switch k {
     59 		case 'S':
     60 			dst.Severity = v
     61 		case 'V':
     62 			dst.SeverityUnlocalized = v
     63 		case 'C':
     64 			dst.Code = v
     65 		case 'M':
     66 			dst.Message = v
     67 		case 'D':
     68 			dst.Detail = v
     69 		case 'H':
     70 			dst.Hint = v
     71 		case 'P':
     72 			s := v
     73 			n, _ := strconv.ParseInt(s, 10, 32)
     74 			dst.Position = int32(n)
     75 		case 'p':
     76 			s := v
     77 			n, _ := strconv.ParseInt(s, 10, 32)
     78 			dst.InternalPosition = int32(n)
     79 		case 'q':
     80 			dst.InternalQuery = v
     81 		case 'W':
     82 			dst.Where = v
     83 		case 's':
     84 			dst.SchemaName = v
     85 		case 't':
     86 			dst.TableName = v
     87 		case 'c':
     88 			dst.ColumnName = v
     89 		case 'd':
     90 			dst.DataTypeName = v
     91 		case 'n':
     92 			dst.ConstraintName = v
     93 		case 'F':
     94 			dst.File = v
     95 		case 'L':
     96 			s := v
     97 			n, _ := strconv.ParseInt(s, 10, 32)
     98 			dst.Line = int32(n)
     99 		case 'R':
    100 			dst.Routine = v
    101 
    102 		default:
    103 			if dst.UnknownFields == nil {
    104 				dst.UnknownFields = make(map[byte]string)
    105 			}
    106 			dst.UnknownFields[k] = v
    107 		}
    108 	}
    109 
    110 	return nil
    111 }
    112 
    113 // Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
    114 func (src *ErrorResponse) Encode(dst []byte) []byte {
    115 	return append(dst, src.marshalBinary('E')...)
    116 }
    117 
    118 func (src *ErrorResponse) marshalBinary(typeByte byte) []byte {
    119 	var bigEndian BigEndianBuf
    120 	buf := &bytes.Buffer{}
    121 
    122 	buf.WriteByte(typeByte)
    123 	buf.Write(bigEndian.Uint32(0))
    124 
    125 	if src.Severity != "" {
    126 		buf.WriteByte('S')
    127 		buf.WriteString(src.Severity)
    128 		buf.WriteByte(0)
    129 	}
    130 	if src.SeverityUnlocalized != "" {
    131 		buf.WriteByte('V')
    132 		buf.WriteString(src.SeverityUnlocalized)
    133 		buf.WriteByte(0)
    134 	}
    135 	if src.Code != "" {
    136 		buf.WriteByte('C')
    137 		buf.WriteString(src.Code)
    138 		buf.WriteByte(0)
    139 	}
    140 	if src.Message != "" {
    141 		buf.WriteByte('M')
    142 		buf.WriteString(src.Message)
    143 		buf.WriteByte(0)
    144 	}
    145 	if src.Detail != "" {
    146 		buf.WriteByte('D')
    147 		buf.WriteString(src.Detail)
    148 		buf.WriteByte(0)
    149 	}
    150 	if src.Hint != "" {
    151 		buf.WriteByte('H')
    152 		buf.WriteString(src.Hint)
    153 		buf.WriteByte(0)
    154 	}
    155 	if src.Position != 0 {
    156 		buf.WriteByte('P')
    157 		buf.WriteString(strconv.Itoa(int(src.Position)))
    158 		buf.WriteByte(0)
    159 	}
    160 	if src.InternalPosition != 0 {
    161 		buf.WriteByte('p')
    162 		buf.WriteString(strconv.Itoa(int(src.InternalPosition)))
    163 		buf.WriteByte(0)
    164 	}
    165 	if src.InternalQuery != "" {
    166 		buf.WriteByte('q')
    167 		buf.WriteString(src.InternalQuery)
    168 		buf.WriteByte(0)
    169 	}
    170 	if src.Where != "" {
    171 		buf.WriteByte('W')
    172 		buf.WriteString(src.Where)
    173 		buf.WriteByte(0)
    174 	}
    175 	if src.SchemaName != "" {
    176 		buf.WriteByte('s')
    177 		buf.WriteString(src.SchemaName)
    178 		buf.WriteByte(0)
    179 	}
    180 	if src.TableName != "" {
    181 		buf.WriteByte('t')
    182 		buf.WriteString(src.TableName)
    183 		buf.WriteByte(0)
    184 	}
    185 	if src.ColumnName != "" {
    186 		buf.WriteByte('c')
    187 		buf.WriteString(src.ColumnName)
    188 		buf.WriteByte(0)
    189 	}
    190 	if src.DataTypeName != "" {
    191 		buf.WriteByte('d')
    192 		buf.WriteString(src.DataTypeName)
    193 		buf.WriteByte(0)
    194 	}
    195 	if src.ConstraintName != "" {
    196 		buf.WriteByte('n')
    197 		buf.WriteString(src.ConstraintName)
    198 		buf.WriteByte(0)
    199 	}
    200 	if src.File != "" {
    201 		buf.WriteByte('F')
    202 		buf.WriteString(src.File)
    203 		buf.WriteByte(0)
    204 	}
    205 	if src.Line != 0 {
    206 		buf.WriteByte('L')
    207 		buf.WriteString(strconv.Itoa(int(src.Line)))
    208 		buf.WriteByte(0)
    209 	}
    210 	if src.Routine != "" {
    211 		buf.WriteByte('R')
    212 		buf.WriteString(src.Routine)
    213 		buf.WriteByte(0)
    214 	}
    215 
    216 	for k, v := range src.UnknownFields {
    217 		buf.WriteByte(k)
    218 		buf.WriteByte(0)
    219 		buf.WriteString(v)
    220 		buf.WriteByte(0)
    221 	}
    222 
    223 	buf.WriteByte(0)
    224 
    225 	binary.BigEndian.PutUint32(buf.Bytes()[1:5], uint32(buf.Len()-1))
    226 
    227 	return buf.Bytes()
    228 }
    229 
    230 // MarshalJSON implements encoding/json.Marshaler.
    231 func (src ErrorResponse) MarshalJSON() ([]byte, error) {
    232 	return json.Marshal(struct {
    233 		Type                string
    234 		Severity            string
    235 		SeverityUnlocalized string // only in 9.6 and greater
    236 		Code                string
    237 		Message             string
    238 		Detail              string
    239 		Hint                string
    240 		Position            int32
    241 		InternalPosition    int32
    242 		InternalQuery       string
    243 		Where               string
    244 		SchemaName          string
    245 		TableName           string
    246 		ColumnName          string
    247 		DataTypeName        string
    248 		ConstraintName      string
    249 		File                string
    250 		Line                int32
    251 		Routine             string
    252 
    253 		UnknownFields map[byte]string
    254 	}{
    255 		Type:                "ErrorResponse",
    256 		Severity:            src.Severity,
    257 		SeverityUnlocalized: src.SeverityUnlocalized,
    258 		Code:                src.Code,
    259 		Message:             src.Message,
    260 		Detail:              src.Detail,
    261 		Hint:                src.Hint,
    262 		Position:            src.Position,
    263 		InternalPosition:    src.InternalPosition,
    264 		InternalQuery:       src.InternalQuery,
    265 		Where:               src.Where,
    266 		SchemaName:          src.SchemaName,
    267 		TableName:           src.TableName,
    268 		ColumnName:          src.ColumnName,
    269 		DataTypeName:        src.DataTypeName,
    270 		ConstraintName:      src.ConstraintName,
    271 		File:                src.File,
    272 		Line:                src.Line,
    273 		Routine:             src.Routine,
    274 		UnknownFields:       src.UnknownFields,
    275 	})
    276 }
    277 
    278 // UnmarshalJSON implements encoding/json.Unmarshaler.
    279 func (dst *ErrorResponse) UnmarshalJSON(data []byte) error {
    280 	// Ignore null, like in the main JSON package.
    281 	if string(data) == "null" {
    282 		return nil
    283 	}
    284 
    285 	var msg struct {
    286 		Type                string
    287 		Severity            string
    288 		SeverityUnlocalized string // only in 9.6 and greater
    289 		Code                string
    290 		Message             string
    291 		Detail              string
    292 		Hint                string
    293 		Position            int32
    294 		InternalPosition    int32
    295 		InternalQuery       string
    296 		Where               string
    297 		SchemaName          string
    298 		TableName           string
    299 		ColumnName          string
    300 		DataTypeName        string
    301 		ConstraintName      string
    302 		File                string
    303 		Line                int32
    304 		Routine             string
    305 
    306 		UnknownFields map[byte]string
    307 	}
    308 	if err := json.Unmarshal(data, &msg); err != nil {
    309 		return err
    310 	}
    311 
    312 	dst.Severity = msg.Severity
    313 	dst.SeverityUnlocalized = msg.SeverityUnlocalized
    314 	dst.Code = msg.Code
    315 	dst.Message = msg.Message
    316 	dst.Detail = msg.Detail
    317 	dst.Hint = msg.Hint
    318 	dst.Position = msg.Position
    319 	dst.InternalPosition = msg.InternalPosition
    320 	dst.InternalQuery = msg.InternalQuery
    321 	dst.Where = msg.Where
    322 	dst.SchemaName = msg.SchemaName
    323 	dst.TableName = msg.TableName
    324 	dst.ColumnName = msg.ColumnName
    325 	dst.DataTypeName = msg.DataTypeName
    326 	dst.ConstraintName = msg.ConstraintName
    327 	dst.File = msg.File
    328 	dst.Line = msg.Line
    329 	dst.Routine = msg.Routine
    330 
    331 	dst.UnknownFields = msg.UnknownFields
    332 
    333 	return nil
    334 }