mirror of
https://github.com/jackc/pgx.git
synced 2025-05-01 21:19:54 +00:00
Oids are rarely null, but they can be: on the right hand side of a left join, for instance. This commit takes moves the Oid type def from messages.go to values.go, so it can live along side the other types. It removes the special case for testing Oid and now leverages the TestNullX test instead.
160 lines
3.7 KiB
Go
160 lines
3.7 KiB
Go
package pgx
|
|
|
|
import (
|
|
"encoding/binary"
|
|
)
|
|
|
|
const (
|
|
protocolVersionNumber = 196608 // 3.0
|
|
)
|
|
|
|
const (
|
|
backendKeyData = 'K'
|
|
authenticationX = 'R'
|
|
readyForQuery = 'Z'
|
|
rowDescription = 'T'
|
|
dataRow = 'D'
|
|
commandComplete = 'C'
|
|
errorResponse = 'E'
|
|
noticeResponse = 'N'
|
|
parseComplete = '1'
|
|
parameterDescription = 't'
|
|
bindComplete = '2'
|
|
notificationResponse = 'A'
|
|
emptyQueryResponse = 'I'
|
|
noData = 'n'
|
|
closeComplete = '3'
|
|
flush = 'H'
|
|
copyInResponse = 'G'
|
|
copyData = 'd'
|
|
copyFail = 'f'
|
|
copyDone = 'c'
|
|
)
|
|
|
|
type startupMessage struct {
|
|
options map[string]string
|
|
}
|
|
|
|
func newStartupMessage() *startupMessage {
|
|
return &startupMessage{map[string]string{}}
|
|
}
|
|
|
|
func (s *startupMessage) Bytes() (buf []byte) {
|
|
buf = make([]byte, 8, 128)
|
|
binary.BigEndian.PutUint32(buf[4:8], uint32(protocolVersionNumber))
|
|
for key, value := range s.options {
|
|
buf = append(buf, key...)
|
|
buf = append(buf, 0)
|
|
buf = append(buf, value...)
|
|
buf = append(buf, 0)
|
|
}
|
|
buf = append(buf, ("\000")...)
|
|
binary.BigEndian.PutUint32(buf[0:4], uint32(len(buf)))
|
|
return buf
|
|
}
|
|
|
|
type FieldDescription struct {
|
|
Name string
|
|
Table Oid
|
|
AttributeNumber int16
|
|
DataType Oid
|
|
DataTypeSize int16
|
|
DataTypeName string
|
|
Modifier int32
|
|
FormatCode int16
|
|
}
|
|
|
|
// PgError represents an error reported by the PostgreSQL server. See
|
|
// http://www.postgresql.org/docs/9.3/static/protocol-error-fields.html for
|
|
// detailed field description.
|
|
type PgError struct {
|
|
Severity string
|
|
Code string
|
|
Message string
|
|
Detail string
|
|
Hint string
|
|
Position int32
|
|
InternalPosition int32
|
|
InternalQuery string
|
|
Where string
|
|
SchemaName string
|
|
TableName string
|
|
ColumnName string
|
|
DataTypeName string
|
|
ConstraintName string
|
|
File string
|
|
Line int32
|
|
Routine string
|
|
}
|
|
|
|
func (pe PgError) Error() string {
|
|
return pe.Severity + ": " + pe.Message + " (SQLSTATE " + pe.Code + ")"
|
|
}
|
|
|
|
func newWriteBuf(c *Conn, t byte) *WriteBuf {
|
|
buf := append(c.wbuf[0:0], t, 0, 0, 0, 0)
|
|
c.writeBuf = WriteBuf{buf: buf, sizeIdx: 1, conn: c}
|
|
return &c.writeBuf
|
|
}
|
|
|
|
// WriteBuf is used build messages to send to the PostgreSQL server. It is used
|
|
// by the Encoder interface when implementing custom encoders.
|
|
type WriteBuf struct {
|
|
buf []byte
|
|
sizeIdx int
|
|
conn *Conn
|
|
}
|
|
|
|
func (wb *WriteBuf) startMsg(t byte) {
|
|
wb.closeMsg()
|
|
wb.buf = append(wb.buf, t, 0, 0, 0, 0)
|
|
wb.sizeIdx = len(wb.buf) - 4
|
|
}
|
|
|
|
func (wb *WriteBuf) closeMsg() {
|
|
binary.BigEndian.PutUint32(wb.buf[wb.sizeIdx:wb.sizeIdx+4], uint32(len(wb.buf)-wb.sizeIdx))
|
|
}
|
|
|
|
func (wb *WriteBuf) WriteByte(b byte) {
|
|
wb.buf = append(wb.buf, b)
|
|
}
|
|
|
|
func (wb *WriteBuf) WriteCString(s string) {
|
|
wb.buf = append(wb.buf, []byte(s)...)
|
|
wb.buf = append(wb.buf, 0)
|
|
}
|
|
|
|
func (wb *WriteBuf) WriteInt16(n int16) {
|
|
b := make([]byte, 2)
|
|
binary.BigEndian.PutUint16(b, uint16(n))
|
|
wb.buf = append(wb.buf, b...)
|
|
}
|
|
|
|
func (wb *WriteBuf) WriteUint16(n uint16) {
|
|
b := make([]byte, 2)
|
|
binary.BigEndian.PutUint16(b, n)
|
|
wb.buf = append(wb.buf, b...)
|
|
}
|
|
|
|
func (wb *WriteBuf) WriteInt32(n int32) {
|
|
b := make([]byte, 4)
|
|
binary.BigEndian.PutUint32(b, uint32(n))
|
|
wb.buf = append(wb.buf, b...)
|
|
}
|
|
|
|
func (wb *WriteBuf) WriteUint32(n uint32) {
|
|
b := make([]byte, 4)
|
|
binary.BigEndian.PutUint32(b, n)
|
|
wb.buf = append(wb.buf, b...)
|
|
}
|
|
|
|
func (wb *WriteBuf) WriteInt64(n int64) {
|
|
b := make([]byte, 8)
|
|
binary.BigEndian.PutUint64(b, uint64(n))
|
|
wb.buf = append(wb.buf, b...)
|
|
}
|
|
|
|
func (wb *WriteBuf) WriteBytes(b []byte) {
|
|
wb.buf = append(wb.buf, b...)
|
|
}
|