...

Source file src/github.com/jackc/pgx/v5/pgproto3/error_response.go

Documentation: github.com/jackc/pgx/v5/pgproto3

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

View as plain text