func ReadDataRow(m *Message) (*DataRow, error) { if t := m.MsgType(); t != MsgDataRowD { return nil, e.BadTypeCode(t) } b := m.Payload() fieldCount, err := ReadUint16(b) if err != nil { return nil, err } values := make([][]byte, fieldCount) for i := range values { fieldLen, err := ReadInt32(b) if err != nil { return nil, err } if fieldLen >= 0 { fieldData := make([]byte, fieldLen) io.ReadFull(b, fieldData) values[i] = fieldData } else if fieldLen == -1 { values[i] = nil } else { return nil, e.WrongSize("Invalid length %v for field %v", fieldLen, i) } } return &DataRow{values}, nil }
func ReadRowDescription(msg *Message) ( rd *RowDescription, err error) { if t := msg.MsgType(); t != MsgRowDescriptionT { return nil, e.BadTypeCode(t) } b := msg.Payload() fieldCount, err := ReadUint16(b) if err != nil { return nil, err } fields := make([]FieldDescription, fieldCount) for i := range fields { name, err := ReadCString(b) if err != nil { return nil, err } tableOid, err := ReadInt32(b) if err != nil { return nil, err } tableAttNo, err := ReadInt16(b) if err != nil { return nil, err } typeOid, err := ReadUint32(b) if err != nil { return nil, err } typLen, err := ReadInt16(b) if err != nil { return nil, err } atttypmod, err := ReadInt32(b) if err != nil { return nil, err } format, err := ReadInt16(b) if err != nil { return nil, err } fields[i] = FieldDescription{name, Oid(tableOid), tableAttNo, Oid(typeOid), typLen, atttypmod, EncFmt(format)} } return &RowDescription{fields}, nil }
func ReadCommandComplete(m *Message) (*CommandComplete, error) { if t := m.MsgType(); t != MsgCommandCompleteC { return nil, e.BadTypeCode(t) } p := m.Payload() fullTag, err := ReadCString(p) if err != nil { return nil, err } cmdRe := regexp.MustCompile("(INSERT|DELETE|UPDATE|SELECT|MOVE|FETCH|COPY) (\\d+)(?: (\\d+))?") if match := cmdRe.FindStringSubmatch(fullTag); match != nil { var rowcountIdx int var rowcount uint64 var oid uint32 hasOid := len(match) == 4 && match[3] != "" tag := match[1] if hasOid { val, err := strconv.ParseUint(match[2], 10, 32) if err != nil { panic("Oh snap") } oid = uint32(val) rowcountIdx = 3 } else { rowcountIdx = 2 oid = 0 } rowcount, err := strconv.ParseUint(match[rowcountIdx], 10, 64) if err != nil { panic("Oh snap") } return &CommandComplete{tag, rowcount, oid}, nil } else { return &CommandComplete{fullTag, 0, 0}, nil } }
func ReadErrorResponse(msg *Message) (*ErrorResponse, error) { if t := msg.MsgType(); t != MsgErrorResponseE { return nil, e.BadTypeCode(t) } p := msg.Payload() details := make(map[byte]string) for { fieldCode, err := ReadByte(p) if err != nil { return nil, err } if fieldCode == 0 { break } fieldValue, err := ReadCString(p) if err != nil { return nil, err } details[fieldCode] = fieldValue } return &ErrorResponse{details}, nil }
func ReadBackendKeyData(msg *Message) (*BackendKeyData, error) { if t := msg.MsgType(); t != MsgBackendKeyDataK { return nil, e.BadTypeCode(t) } const RIGHT_SZ = 12 if msg.Size() != RIGHT_SZ { return nil, e.WrongSize("BackendKeyData is wrong size: "+ "expected %v, got %v", RIGHT_SZ, msg.Size()) } r := msg.Payload() pid, err := ReadUint32(r) if err != nil { return nil, err } key, err := ReadUint32(r) if err != nil { return nil, err } return &BackendKeyData{BackendPid: pid, SecretKey: key}, err }