...

Source file src/github.com/jackc/pgtype/bytea.go

Documentation: github.com/jackc/pgtype

     1  package pgtype
     2  
     3  import (
     4  	"database/sql/driver"
     5  	"encoding/hex"
     6  	"fmt"
     7  )
     8  
     9  type Bytea struct {
    10  	Bytes  []byte
    11  	Status Status
    12  }
    13  
    14  func (dst *Bytea) Set(src interface{}) error {
    15  	if src == nil {
    16  		*dst = Bytea{Status: Null}
    17  		return nil
    18  	}
    19  
    20  	if value, ok := src.(interface{ Get() interface{} }); ok {
    21  		value2 := value.Get()
    22  		if value2 != value {
    23  			return dst.Set(value2)
    24  		}
    25  	}
    26  
    27  	switch value := src.(type) {
    28  	case []byte:
    29  		if value != nil {
    30  			*dst = Bytea{Bytes: value, Status: Present}
    31  		} else {
    32  			*dst = Bytea{Status: Null}
    33  		}
    34  	default:
    35  		if originalSrc, ok := underlyingBytesType(src); ok {
    36  			return dst.Set(originalSrc)
    37  		}
    38  		return fmt.Errorf("cannot convert %v to Bytea", value)
    39  	}
    40  
    41  	return nil
    42  }
    43  
    44  func (dst Bytea) Get() interface{} {
    45  	switch dst.Status {
    46  	case Present:
    47  		return dst.Bytes
    48  	case Null:
    49  		return nil
    50  	default:
    51  		return dst.Status
    52  	}
    53  }
    54  
    55  func (src *Bytea) AssignTo(dst interface{}) error {
    56  	switch src.Status {
    57  	case Present:
    58  		switch v := dst.(type) {
    59  		case *[]byte:
    60  			buf := make([]byte, len(src.Bytes))
    61  			copy(buf, src.Bytes)
    62  			*v = buf
    63  			return nil
    64  		default:
    65  			if nextDst, retry := GetAssignToDstType(dst); retry {
    66  				return src.AssignTo(nextDst)
    67  			}
    68  			return fmt.Errorf("unable to assign to %T", dst)
    69  		}
    70  	case Null:
    71  		return NullAssignTo(dst)
    72  	}
    73  
    74  	return fmt.Errorf("cannot decode %#v into %T", src, dst)
    75  }
    76  
    77  // DecodeText only supports the hex format. This has been the default since
    78  // PostgreSQL 9.0.
    79  func (dst *Bytea) DecodeText(ci *ConnInfo, src []byte) error {
    80  	if src == nil {
    81  		*dst = Bytea{Status: Null}
    82  		return nil
    83  	}
    84  
    85  	if len(src) < 2 || src[0] != '\\' || src[1] != 'x' {
    86  		return fmt.Errorf("invalid hex format")
    87  	}
    88  
    89  	buf := make([]byte, (len(src)-2)/2)
    90  	_, err := hex.Decode(buf, src[2:])
    91  	if err != nil {
    92  		return err
    93  	}
    94  
    95  	*dst = Bytea{Bytes: buf, Status: Present}
    96  	return nil
    97  }
    98  
    99  func (dst *Bytea) DecodeBinary(ci *ConnInfo, src []byte) error {
   100  	if src == nil {
   101  		*dst = Bytea{Status: Null}
   102  		return nil
   103  	}
   104  
   105  	*dst = Bytea{Bytes: src, Status: Present}
   106  	return nil
   107  }
   108  
   109  func (src Bytea) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
   110  	switch src.Status {
   111  	case Null:
   112  		return nil, nil
   113  	case Undefined:
   114  		return nil, errUndefined
   115  	}
   116  
   117  	buf = append(buf, `\x`...)
   118  	buf = append(buf, hex.EncodeToString(src.Bytes)...)
   119  	return buf, nil
   120  }
   121  
   122  func (src Bytea) EncodeBinary(ci *ConnInfo, buf []byte) ([]byte, error) {
   123  	switch src.Status {
   124  	case Null:
   125  		return nil, nil
   126  	case Undefined:
   127  		return nil, errUndefined
   128  	}
   129  
   130  	return append(buf, src.Bytes...), nil
   131  }
   132  
   133  // Scan implements the database/sql Scanner interface.
   134  func (dst *Bytea) Scan(src interface{}) error {
   135  	if src == nil {
   136  		*dst = Bytea{Status: Null}
   137  		return nil
   138  	}
   139  
   140  	switch src := src.(type) {
   141  	case string:
   142  		return dst.DecodeText(nil, []byte(src))
   143  	case []byte:
   144  		buf := make([]byte, len(src))
   145  		copy(buf, src)
   146  		*dst = Bytea{Bytes: buf, Status: Present}
   147  		return nil
   148  	}
   149  
   150  	return fmt.Errorf("cannot scan %T", src)
   151  }
   152  
   153  // Value implements the database/sql/driver Valuer interface.
   154  func (src Bytea) Value() (driver.Value, error) {
   155  	switch src.Status {
   156  	case Present:
   157  		return src.Bytes, nil
   158  	case Null:
   159  		return nil, nil
   160  	default:
   161  		return nil, errUndefined
   162  	}
   163  }
   164  

View as plain text