// Process the identity ('I') message, reporting the identity therein. func processIdentMsg(msgInit msgInit, exit exitFn) string { var m core.Message msgInit(&m, exit) // Read the remote system identifier string if m.MsgType() != 'I' { exit("expected identification ('I') message, "+ "but received %c", m.MsgType()) } // hard-coded lengh limit, but it's very generous if m.Size() > 10*KB { log.Printf("oversized message string, msg size is %d", m.Size()) } s, err := buf.ReadCString(m.Payload()) if err != nil { exit("couldn't read identification string: %v", err) } return s }
// Read the version message, calling exit if this is not a supported // version. func processVerMsg(msgInit msgInit, exit exitFn) { var m core.Message msgInit(&m, exit) if m.MsgType() != 'V' { exit("expected version ('V') message, "+ "but received %c", m.MsgType()) } // hard-coded lengh limit, but it's very generous if m.Size() > 10*KB { log.Printf("oversized message string, msg size is %d", m.Size()) } s, err := buf.ReadCString(m.Payload()) if err != nil { exit("couldn't read version string: %v", err) } if !(strings.HasPrefix(s, "PG-9.0") || strings.HasPrefix(s, "PG-9.1") || strings.HasPrefix(s, "PG-9.2") || strings.HasPrefix(s, "PG-9.3") || strings.HasPrefix(s, "PG-9.4") || strings.HasPrefix(s, "PG-9.5")) || !strings.HasSuffix(s, "/logfebe-1") { exit("protocol version not supported: %s", s) } }
func (c *FrontendConnection) readExecuteMessage(msg *fbcore.Message) error { statementName, err := fbbuf.ReadCString(msg.Payload()) if err != nil { return err } if statementName != "" { return fmt.Errorf("attempted to use statement name %q; only unnamed statements are supported") } // ignore maxRowCount _, err = fbbuf.ReadInt32(msg.Payload()) // TODO: ensure we're at the end of the packet return err }
func (c *FrontendConnection) readBindMessage(msg *fbcore.Message) error { portalName, err := fbbuf.ReadCString(msg.Payload()) if err != nil { return err } if portalName != "" { return fmt.Errorf("attempted to bind to a named portal %q; only the unnamed portal is supported") } statementName, err := fbbuf.ReadCString(msg.Payload()) if err != nil { return err } if statementName != "" { return fmt.Errorf("attempted to bind statement %q, even though it has not been parsed yet", statementName) } numParamFormats, err := fbbuf.ReadInt16(msg.Payload()) if err != nil { return err } if numParamFormats != 0 { return fmt.Errorf("the number of parameter formats (%d) does not match the number of parameters in the query (0)", numParamFormats) } numParameters, err := fbbuf.ReadInt16(msg.Payload()) if err != nil { return err } if numParameters != 0 { return fmt.Errorf("the number of parameters provided by the client (%d) does not match the number of parameters in the query (0)", numParameters) } // TODO: ensure we're at the end of the packet return nil }
func (c *FrontendConnection) readDescribeMessage(msg *fbcore.Message) (byte, error) { typ, err := fbbuf.ReadByte(msg.Payload()) if err != nil { return 0, err } if typ != 'S' && typ != 'P' { return 0, fmt.Errorf("invalid type %q", typ) } statementName, err := fbbuf.ReadCString(msg.Payload()) if err != nil { return 0, err } if statementName != "" { return 0, fmt.Errorf("tried to use statement/portal name %q; only unnamed statements and portals are supported") } // TODO: ensure we're at the end of the packet return typ, nil }
func (c *FrontendConnection) readParseMessage(msg *fbcore.Message) (queryString string, err error) { statementName, err := fbbuf.ReadCString(msg.Payload()) if err != nil { return "", err } if statementName != "" { return "", fmt.Errorf("attempted to use statement name %q; only unnamed statements are supported") } queryString, err = fbbuf.ReadCString(msg.Payload()) if err != nil { return "", err } numParamTypes, err := fbbuf.ReadInt16(msg.Payload()) if err != nil { return "", err } if numParamTypes != 0 { return "", fmt.Errorf("attempted to prepare a statement with %d param types", numParamTypes) } // TODO: ensure we're at the end of the packet return queryString, nil }