Remove old Scanner and Encoder system
This commit is contained in:
@@ -159,245 +159,6 @@ func (e SerializationError) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
// Deprecated: Scanner is an interface used to decode values from the PostgreSQL
|
||||
// server. To allow types to support pgx and database/sql.Scan this interface
|
||||
// has been deprecated in favor of PgxScanner.
|
||||
type Scanner interface {
|
||||
// Scan MUST check r.Type().DataType (to check by Oid) or
|
||||
// r.Type().DataTypeName (to check by name) to ensure that it is scanning an
|
||||
// expected column type. It also MUST check r.Type().FormatCode before
|
||||
// decoding. It should not assume that it was called on a data type or format
|
||||
// that it understands.
|
||||
Scan(r *ValueReader) error
|
||||
}
|
||||
|
||||
// PgxScanner is an interface used to decode values from the PostgreSQL server.
|
||||
// It is used exactly the same as the Scanner interface. It simply has renamed
|
||||
// the method.
|
||||
type PgxScanner interface {
|
||||
// ScanPgx MUST check r.Type().DataType (to check by Oid) or
|
||||
// r.Type().DataTypeName (to check by name) to ensure that it is scanning an
|
||||
// expected column type. It also MUST check r.Type().FormatCode before
|
||||
// decoding. It should not assume that it was called on a data type or format
|
||||
// that it understands.
|
||||
ScanPgx(r *ValueReader) error
|
||||
}
|
||||
|
||||
// Encoder is an interface used to encode values for transmission to the
|
||||
// PostgreSQL server.
|
||||
type Encoder interface {
|
||||
// Encode writes the value to w.
|
||||
//
|
||||
// If the value is NULL an int32(-1) should be written.
|
||||
//
|
||||
// Encode MUST check oid to see if the parameter data type is compatible. If
|
||||
// this is not done, the PostgreSQL server may detect the error if the
|
||||
// expected data size or format of the encoded data does not match. But if
|
||||
// the encoded data is a valid representation of the data type PostgreSQL
|
||||
// expects such as date and int4, incorrect data may be stored.
|
||||
Encode(w *WriteBuf, oid Oid) error
|
||||
|
||||
// FormatCode returns the format that the encoder writes the value. It must be
|
||||
// either pgx.TextFormatCode or pgx.BinaryFormatCode.
|
||||
FormatCode() int16
|
||||
}
|
||||
|
||||
// NullFloat32 represents an float4 that may be null. NullFloat32 implements the
|
||||
// Scanner and Encoder interfaces so it may be used both as an argument to
|
||||
// Query[Row] and a destination for Scan.
|
||||
//
|
||||
// If Valid is false then the value is NULL.
|
||||
type NullFloat32 struct {
|
||||
Float32 float32
|
||||
Valid bool // Valid is true if Float32 is not NULL
|
||||
}
|
||||
|
||||
func (n *NullFloat32) Scan(vr *ValueReader) error {
|
||||
if vr.Type().DataType != Float4Oid {
|
||||
return SerializationError(fmt.Sprintf("NullFloat32.Scan cannot decode Oid %d", vr.Type().DataType))
|
||||
}
|
||||
|
||||
if vr.Len() == -1 {
|
||||
n.Float32, n.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
n.Float32 = decodeFloat4(vr)
|
||||
return vr.Err()
|
||||
}
|
||||
|
||||
func (n NullFloat32) FormatCode() int16 { return BinaryFormatCode }
|
||||
|
||||
func (n NullFloat32) Encode(w *WriteBuf, oid Oid) error {
|
||||
if oid != Float4Oid {
|
||||
return SerializationError(fmt.Sprintf("NullFloat32.Encode cannot encode into Oid %d", oid))
|
||||
}
|
||||
|
||||
if !n.Valid {
|
||||
w.WriteInt32(-1)
|
||||
return nil
|
||||
}
|
||||
|
||||
return encodeFloat32(w, oid, n.Float32)
|
||||
}
|
||||
|
||||
// NullFloat64 represents an float8 that may be null. NullFloat64 implements the
|
||||
// Scanner and Encoder interfaces so it may be used both as an argument to
|
||||
// Query[Row] and a destination for Scan.
|
||||
//
|
||||
// If Valid is false then the value is NULL.
|
||||
type NullFloat64 struct {
|
||||
Float64 float64
|
||||
Valid bool // Valid is true if Float64 is not NULL
|
||||
}
|
||||
|
||||
func (n *NullFloat64) Scan(vr *ValueReader) error {
|
||||
if vr.Type().DataType != Float8Oid {
|
||||
return SerializationError(fmt.Sprintf("NullFloat64.Scan cannot decode Oid %d", vr.Type().DataType))
|
||||
}
|
||||
|
||||
if vr.Len() == -1 {
|
||||
n.Float64, n.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
n.Float64 = decodeFloat8(vr)
|
||||
return vr.Err()
|
||||
}
|
||||
|
||||
func (n NullFloat64) FormatCode() int16 { return BinaryFormatCode }
|
||||
|
||||
func (n NullFloat64) Encode(w *WriteBuf, oid Oid) error {
|
||||
if oid != Float8Oid {
|
||||
return SerializationError(fmt.Sprintf("NullFloat64.Encode cannot encode into Oid %d", oid))
|
||||
}
|
||||
|
||||
if !n.Valid {
|
||||
w.WriteInt32(-1)
|
||||
return nil
|
||||
}
|
||||
|
||||
return encodeFloat64(w, oid, n.Float64)
|
||||
}
|
||||
|
||||
// NullString represents an string that may be null. NullString implements the
|
||||
// Scanner Encoder interfaces so it may be used both as an argument to
|
||||
// Query[Row] and a destination for Scan.
|
||||
//
|
||||
// If Valid is false then the value is NULL.
|
||||
type NullString struct {
|
||||
String string
|
||||
Valid bool // Valid is true if String is not NULL
|
||||
}
|
||||
|
||||
func (n *NullString) Scan(vr *ValueReader) error {
|
||||
// Not checking oid as so we can scan anything into into a NullString - may revisit this decision later
|
||||
|
||||
if vr.Len() == -1 {
|
||||
n.String, n.Valid = "", false
|
||||
return nil
|
||||
}
|
||||
|
||||
n.Valid = true
|
||||
n.String = decodeText(vr)
|
||||
return vr.Err()
|
||||
}
|
||||
|
||||
func (n NullString) FormatCode() int16 { return TextFormatCode }
|
||||
|
||||
func (s NullString) Encode(w *WriteBuf, oid Oid) error {
|
||||
if !s.Valid {
|
||||
w.WriteInt32(-1)
|
||||
return nil
|
||||
}
|
||||
|
||||
return encodeString(w, oid, s.String)
|
||||
}
|
||||
|
||||
// NullInt16 represents a smallint that may be null. NullInt16 implements the
|
||||
// Scanner and Encoder interfaces so it may be used both as an argument to
|
||||
// Query[Row] and a destination for Scan for prepared and unprepared queries.
|
||||
//
|
||||
// If Valid is false then the value is NULL.
|
||||
type NullInt16 struct {
|
||||
Int16 int16
|
||||
Valid bool // Valid is true if Int16 is not NULL
|
||||
}
|
||||
|
||||
func (n *NullInt16) Scan(vr *ValueReader) error {
|
||||
if vr.Type().DataType != Int2Oid {
|
||||
return SerializationError(fmt.Sprintf("NullInt16.Scan cannot decode Oid %d", vr.Type().DataType))
|
||||
}
|
||||
|
||||
if vr.Len() == -1 {
|
||||
n.Int16, n.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
n.Int16 = decodeInt2(vr)
|
||||
return vr.Err()
|
||||
}
|
||||
|
||||
func (n NullInt16) FormatCode() int16 { return BinaryFormatCode }
|
||||
|
||||
func (n NullInt16) Encode(w *WriteBuf, oid Oid) error {
|
||||
if oid != Int2Oid {
|
||||
return SerializationError(fmt.Sprintf("NullInt16.Encode cannot encode into Oid %d", oid))
|
||||
}
|
||||
|
||||
if !n.Valid {
|
||||
w.WriteInt32(-1)
|
||||
return nil
|
||||
}
|
||||
|
||||
w.WriteInt32(2)
|
||||
|
||||
_, err := pgtype.Int2{Int: n.Int16, Status: pgtype.Present}.EncodeBinary(w)
|
||||
return err
|
||||
}
|
||||
|
||||
// NullInt32 represents an integer that may be null. NullInt32 implements the
|
||||
// Scanner and Encoder interfaces so it may be used both as an argument to
|
||||
// Query[Row] and a destination for Scan.
|
||||
//
|
||||
// If Valid is false then the value is NULL.
|
||||
type NullInt32 struct {
|
||||
Int32 int32
|
||||
Valid bool // Valid is true if Int32 is not NULL
|
||||
}
|
||||
|
||||
func (n *NullInt32) Scan(vr *ValueReader) error {
|
||||
if vr.Type().DataType != Int4Oid {
|
||||
return SerializationError(fmt.Sprintf("NullInt32.Scan cannot decode Oid %d", vr.Type().DataType))
|
||||
}
|
||||
|
||||
if vr.Len() == -1 {
|
||||
n.Int32, n.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
n.Int32 = decodeInt4(vr)
|
||||
return vr.Err()
|
||||
}
|
||||
|
||||
func (n NullInt32) FormatCode() int16 { return BinaryFormatCode }
|
||||
|
||||
func (n NullInt32) Encode(w *WriteBuf, oid Oid) error {
|
||||
if oid != Int4Oid {
|
||||
return SerializationError(fmt.Sprintf("NullInt32.Encode cannot encode into Oid %d", oid))
|
||||
}
|
||||
|
||||
if !n.Valid {
|
||||
w.WriteInt32(-1)
|
||||
return nil
|
||||
}
|
||||
|
||||
w.WriteInt32(4)
|
||||
|
||||
_, err := pgtype.Int4{Int: n.Int32, Status: pgtype.Present}.EncodeBinary(w)
|
||||
return err
|
||||
}
|
||||
|
||||
// Oid (Object Identifier Type) is, according to https://www.postgresql.org/docs/current/static/datatype-oid.html,
|
||||
// used internally by PostgreSQL as a primary key for various system tables. It is currently implemented
|
||||
// as an unsigned four-byte integer. Its definition can be found in src/include/postgres_ext.h
|
||||
@@ -442,140 +203,6 @@ func (src Oid) EncodeBinary(w io.Writer) (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// NullInt64 represents an bigint that may be null. NullInt64 implements the
|
||||
// Scanner and Encoder interfaces so it may be used both as an argument to
|
||||
// Query[Row] and a destination for Scan.
|
||||
//
|
||||
// If Valid is false then the value is NULL.
|
||||
type NullInt64 struct {
|
||||
Int64 int64
|
||||
Valid bool // Valid is true if Int64 is not NULL
|
||||
}
|
||||
|
||||
func (n *NullInt64) Scan(vr *ValueReader) error {
|
||||
if vr.Type().DataType != Int8Oid {
|
||||
return SerializationError(fmt.Sprintf("NullInt64.Scan cannot decode Oid %d", vr.Type().DataType))
|
||||
}
|
||||
|
||||
if vr.Len() == -1 {
|
||||
n.Int64, n.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
n.Int64 = decodeInt8(vr)
|
||||
return vr.Err()
|
||||
}
|
||||
|
||||
func (n NullInt64) FormatCode() int16 { return BinaryFormatCode }
|
||||
|
||||
func (n NullInt64) Encode(w *WriteBuf, oid Oid) error {
|
||||
if oid != Int8Oid {
|
||||
return SerializationError(fmt.Sprintf("NullInt64.Encode cannot encode into Oid %d", oid))
|
||||
}
|
||||
|
||||
if !n.Valid {
|
||||
w.WriteInt32(-1)
|
||||
return nil
|
||||
}
|
||||
|
||||
w.WriteInt32(8)
|
||||
|
||||
_, err := pgtype.Int8{Int: n.Int64, Status: pgtype.Present}.EncodeBinary(w)
|
||||
return err
|
||||
}
|
||||
|
||||
// NullBool represents an bool that may be null. NullBool implements the Scanner
|
||||
// and Encoder interfaces so it may be used both as an argument to Query[Row]
|
||||
// and a destination for Scan.
|
||||
//
|
||||
// If Valid is false then the value is NULL.
|
||||
type NullBool struct {
|
||||
Bool bool
|
||||
Valid bool // Valid is true if Bool is not NULL
|
||||
}
|
||||
|
||||
func (n *NullBool) Scan(vr *ValueReader) error {
|
||||
if vr.Type().DataType != BoolOid {
|
||||
return SerializationError(fmt.Sprintf("NullBool.Scan cannot decode Oid %d", vr.Type().DataType))
|
||||
}
|
||||
|
||||
if vr.Len() == -1 {
|
||||
n.Bool, n.Valid = false, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
n.Bool = decodeBool(vr)
|
||||
return vr.Err()
|
||||
}
|
||||
|
||||
func (n NullBool) FormatCode() int16 { return BinaryFormatCode }
|
||||
|
||||
func (n NullBool) Encode(w *WriteBuf, oid Oid) error {
|
||||
if oid != BoolOid {
|
||||
return SerializationError(fmt.Sprintf("NullBool.Encode cannot encode into Oid %d", oid))
|
||||
}
|
||||
|
||||
if !n.Valid {
|
||||
w.WriteInt32(-1)
|
||||
return nil
|
||||
}
|
||||
|
||||
w.WriteInt32(1)
|
||||
|
||||
_, err := pgtype.Bool{Bool: n.Bool, Status: pgtype.Present}.EncodeBinary(w)
|
||||
return err
|
||||
}
|
||||
|
||||
// NullTime represents an time.Time that may be null. NullTime implements the
|
||||
// Scanner and Encoder interfaces so it may be used both as an argument to
|
||||
// Query[Row] and a destination for Scan. It corresponds with the PostgreSQL
|
||||
// types timestamptz, timestamp, and date.
|
||||
//
|
||||
// If Valid is false then the value is NULL.
|
||||
type NullTime struct {
|
||||
Time time.Time
|
||||
Valid bool // Valid is true if Time is not NULL
|
||||
}
|
||||
|
||||
func (n *NullTime) Scan(vr *ValueReader) error {
|
||||
oid := vr.Type().DataType
|
||||
if oid != TimestampTzOid && oid != TimestampOid && oid != DateOid {
|
||||
return SerializationError(fmt.Sprintf("NullTime.Scan cannot decode Oid %d", vr.Type().DataType))
|
||||
}
|
||||
|
||||
if vr.Len() == -1 {
|
||||
n.Time, n.Valid = time.Time{}, false
|
||||
return nil
|
||||
}
|
||||
|
||||
n.Valid = true
|
||||
switch oid {
|
||||
case TimestampTzOid:
|
||||
n.Time = decodeTimestampTz(vr)
|
||||
case TimestampOid:
|
||||
n.Time = decodeTimestamp(vr)
|
||||
case DateOid:
|
||||
n.Time = decodeDate(vr)
|
||||
}
|
||||
|
||||
return vr.Err()
|
||||
}
|
||||
|
||||
func (n NullTime) FormatCode() int16 { return BinaryFormatCode }
|
||||
|
||||
func (n NullTime) Encode(w *WriteBuf, oid Oid) error {
|
||||
if oid != TimestampTzOid && oid != TimestampOid && oid != DateOid {
|
||||
return SerializationError(fmt.Sprintf("NullTime.Encode cannot encode into Oid %d", oid))
|
||||
}
|
||||
|
||||
if !n.Valid {
|
||||
w.WriteInt32(-1)
|
||||
return nil
|
||||
}
|
||||
|
||||
return encodeTime(w, oid, n.Time)
|
||||
}
|
||||
|
||||
// Encode encodes arg into wbuf as the type oid. This allows implementations
|
||||
// of the Encoder interface to delegate the actual work of encoding to the
|
||||
// built-in functionality.
|
||||
@@ -586,8 +213,6 @@ func Encode(wbuf *WriteBuf, oid Oid, arg interface{}) error {
|
||||
}
|
||||
|
||||
switch arg := arg.(type) {
|
||||
case Encoder:
|
||||
return arg.Encode(wbuf, oid)
|
||||
case pgtype.BinaryEncoder:
|
||||
buf := &bytes.Buffer{}
|
||||
null, err := arg.EncodeBinary(buf)
|
||||
|
||||
Reference in New Issue
Block a user