mirror of
https://github.com/jackc/pgx.git
synced 2025-05-17 04:52:59 +00:00
Though this doesn't follow Go naming conventions exactly it makes names more consistent with PostgreSQL and it is easier to read. For example, TIDOID becomes TidOid. In addition this is one less breaking change in the move to V3.
165 lines
2.9 KiB
Go
165 lines
2.9 KiB
Go
package pgx
|
|
|
|
import (
|
|
"errors"
|
|
)
|
|
|
|
// ValueReader is used by the Scanner interface to decode values.
|
|
type ValueReader struct {
|
|
mr *msgReader
|
|
fd *FieldDescription
|
|
valueBytesRemaining int32
|
|
err error
|
|
}
|
|
|
|
// Err returns any error that the ValueReader has experienced
|
|
func (r *ValueReader) Err() error {
|
|
return r.err
|
|
}
|
|
|
|
// Fatal tells r that a Fatal error has occurred
|
|
func (r *ValueReader) Fatal(err error) {
|
|
r.err = err
|
|
}
|
|
|
|
// Len returns the number of unread bytes
|
|
func (r *ValueReader) Len() int32 {
|
|
return r.valueBytesRemaining
|
|
}
|
|
|
|
// Type returns the *FieldDescription of the value
|
|
func (r *ValueReader) Type() *FieldDescription {
|
|
return r.fd
|
|
}
|
|
|
|
func (r *ValueReader) ReadByte() byte {
|
|
if r.err != nil {
|
|
return 0
|
|
}
|
|
|
|
r.valueBytesRemaining--
|
|
if r.valueBytesRemaining < 0 {
|
|
r.Fatal(errors.New("read past end of value"))
|
|
return 0
|
|
}
|
|
|
|
return r.mr.readByte()
|
|
}
|
|
|
|
func (r *ValueReader) ReadInt16() int16 {
|
|
if r.err != nil {
|
|
return 0
|
|
}
|
|
|
|
r.valueBytesRemaining -= 2
|
|
if r.valueBytesRemaining < 0 {
|
|
r.Fatal(errors.New("read past end of value"))
|
|
return 0
|
|
}
|
|
|
|
return r.mr.readInt16()
|
|
}
|
|
|
|
func (r *ValueReader) ReadUint16() uint16 {
|
|
if r.err != nil {
|
|
return 0
|
|
}
|
|
|
|
r.valueBytesRemaining -= 2
|
|
if r.valueBytesRemaining < 0 {
|
|
r.Fatal(errors.New("read past end of value"))
|
|
return 0
|
|
}
|
|
|
|
return r.mr.readUint16()
|
|
}
|
|
|
|
func (r *ValueReader) ReadInt32() int32 {
|
|
if r.err != nil {
|
|
return 0
|
|
}
|
|
|
|
r.valueBytesRemaining -= 4
|
|
if r.valueBytesRemaining < 0 {
|
|
r.Fatal(errors.New("read past end of value"))
|
|
return 0
|
|
}
|
|
|
|
return r.mr.readInt32()
|
|
}
|
|
|
|
func (r *ValueReader) ReadUint32() uint32 {
|
|
if r.err != nil {
|
|
return 0
|
|
}
|
|
|
|
r.valueBytesRemaining -= 4
|
|
if r.valueBytesRemaining < 0 {
|
|
r.Fatal(errors.New("read past end of value"))
|
|
return 0
|
|
}
|
|
|
|
return r.mr.readUint32()
|
|
}
|
|
|
|
func (r *ValueReader) ReadInt64() int64 {
|
|
if r.err != nil {
|
|
return 0
|
|
}
|
|
|
|
r.valueBytesRemaining -= 8
|
|
if r.valueBytesRemaining < 0 {
|
|
r.Fatal(errors.New("read past end of value"))
|
|
return 0
|
|
}
|
|
|
|
return r.mr.readInt64()
|
|
}
|
|
|
|
func (r *ValueReader) ReadOid() Oid {
|
|
return Oid(r.ReadUint32())
|
|
}
|
|
|
|
// ReadString reads count bytes and returns as string
|
|
func (r *ValueReader) ReadString(count int32) string {
|
|
if r.err != nil {
|
|
return ""
|
|
}
|
|
|
|
r.valueBytesRemaining -= count
|
|
if r.valueBytesRemaining < 0 {
|
|
r.Fatal(errors.New("read past end of value"))
|
|
return ""
|
|
}
|
|
|
|
return r.mr.readString(count)
|
|
}
|
|
|
|
// ReadBytes reads count bytes and returns as []byte
|
|
func (r *ValueReader) ReadBytes(count int32) []byte {
|
|
if r.err != nil {
|
|
return nil
|
|
}
|
|
|
|
if count < 0 {
|
|
r.Fatal(errors.New("count must not be negative"))
|
|
return nil
|
|
}
|
|
|
|
r.valueBytesRemaining -= count
|
|
if r.valueBytesRemaining < 0 {
|
|
r.Fatal(errors.New("read past end of value"))
|
|
return nil
|
|
}
|
|
|
|
return r.mr.readBytes(count)
|
|
}
|
|
|
|
// bytes is a compatibility function for pgtype.TextDecoder and pgtype.BinaryDecoder
|
|
func (r *ValueReader) bytes() []byte {
|
|
if r.Len() >= 0 {
|
|
return r.ReadBytes(r.Len())
|
|
}
|
|
return nil
|
|
}
|