...

Text file src/github.com/jackc/pgtype/typed_multirange.go.erb

Documentation: github.com/jackc/pgtype

     1package pgtype
     2
     3import (
     4	"database/sql/driver"
     5	"encoding/binary"
     6	"fmt"
     7
     8	"github.com/jackc/pgio"
     9)
    10
    11type <%= multirange_type %> struct {
    12	Ranges 	[]<%= range_type %>
    13	Status  Status
    14}
    15
    16func (dst *<%= multirange_type %>) Set(src interface{}) error {
    17	//untyped nil and typed nil interfaces are different
    18	if src == nil {
    19		*dst = <%= multirange_type %>{Status: Null}
    20		return nil
    21	}
    22
    23	switch value := src.(type) {
    24	case <%= multirange_type %>:
    25		*dst = value
    26	case *<%= multirange_type %>:
    27		*dst = *value
    28	case string:
    29		return dst.DecodeText(nil, []byte(value))
    30	case []<%= range_type %>:
    31		if value == nil {
    32			*dst = <%= multirange_type %>{Status: Null}
    33		} else if len(value) == 0 {
    34			*dst = <%= multirange_type %>{Status: Present}
    35		} else {
    36			elements := make([]<%= range_type %>, len(value))
    37			for i := range value {
    38				if err := elements[i].Set(value[i]); err != nil {
    39					return err
    40				}
    41			}
    42			*dst = <%= multirange_type %>{
    43				Ranges: elements,
    44				Status:    Present,
    45			}
    46		}
    47	case []*<%= range_type %>:
    48		if value == nil {
    49			*dst = <%= multirange_type %>{Status: Null}
    50		} else if len(value) == 0 {
    51			*dst = <%= multirange_type %>{Status: Present}
    52		} else {
    53			elements := make([]<%= range_type %>, len(value))
    54			for i := range value {
    55				if err := elements[i].Set(value[i]); err != nil {
    56					return err
    57				}
    58			}
    59			*dst = <%= multirange_type %>{
    60				Ranges: elements,
    61				Status:    Present,
    62			}
    63		}
    64	default:
    65		return fmt.Errorf("cannot convert %v to <%= multirange_type %>", src)
    66	}
    67
    68	return nil
    69
    70}
    71
    72func (dst <%= multirange_type %>) Get() interface{} {
    73	switch dst.Status {
    74	case Present:
    75		return dst
    76	case Null:
    77		return nil
    78	default:
    79		return dst.Status
    80	}
    81}
    82
    83func (src *<%= multirange_type %>) AssignTo(dst interface{}) error {
    84	return fmt.Errorf("cannot assign %v to %T", src, dst)
    85}
    86
    87func (dst *<%= multirange_type %>) DecodeText(ci *ConnInfo, src []byte) error {
    88	if src == nil {
    89		*dst = <%= multirange_type %>{Status: Null}
    90		return nil
    91	}
    92
    93	utmr, err := ParseUntypedTextMultirange(string(src))
    94	if err != nil {
    95		return err
    96	}
    97
    98	var elements []<%= range_type %>
    99
   100	if len(utmr.Elements) > 0 {
   101		elements = make([]<%= range_type %>, len(utmr.Elements))
   102
   103		for i, s := range utmr.Elements {
   104			var elem <%= range_type %>
   105
   106			elemSrc := []byte(s)
   107
   108			err = elem.DecodeText(ci, elemSrc)
   109			if err != nil {
   110				return err
   111			}
   112
   113			elements[i] = elem
   114		}
   115	}
   116
   117	*dst = <%= multirange_type %>{Ranges: elements, Status: Present}
   118
   119	return nil
   120}
   121
   122func (dst *<%= multirange_type %>) DecodeBinary(ci *ConnInfo, src []byte) error {
   123	if src == nil {
   124		*dst = <%= multirange_type %>{Status: Null}
   125		return nil
   126	}
   127
   128	rp := 0
   129
   130	numElems := int(binary.BigEndian.Uint32(src[rp:]))
   131	rp += 4
   132
   133	if numElems == 0 {
   134		*dst = <%= multirange_type %>{Status: Present}
   135		return nil
   136	}
   137
   138	elements := make([]<%= range_type %>, numElems)
   139
   140	for i := range elements {
   141		elemLen := int(int32(binary.BigEndian.Uint32(src[rp:])))
   142		rp += 4
   143		var elemSrc []byte
   144		if elemLen >= 0 {
   145			elemSrc = src[rp : rp+elemLen]
   146			rp += elemLen
   147		}
   148		err := elements[i].DecodeBinary(ci, elemSrc)
   149		if err != nil {
   150			return err
   151		}
   152	}
   153
   154	*dst = <%= multirange_type %>{Ranges: elements, Status: Present}
   155	return nil
   156}
   157
   158func (src <%= multirange_type %>) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
   159	switch src.Status {
   160	case Null:
   161		return nil, nil
   162	case Undefined:
   163		return nil, errUndefined
   164	}
   165
   166	buf = append(buf, '{')
   167
   168	inElemBuf := make([]byte, 0, 32)
   169	for i, elem := range src.Ranges {
   170		if i > 0 {
   171			buf = append(buf, ',')
   172		}
   173
   174		elemBuf, err := elem.EncodeText(ci, inElemBuf)
   175		if err != nil {
   176			return nil, err
   177		}
   178		if elemBuf == nil {
   179			return nil, fmt.Errorf("multi-range does not allow null range")
   180		} else {
   181			buf = append(buf, string(elemBuf)...)
   182		}
   183
   184	}
   185
   186	buf = append(buf, '}')
   187
   188	return buf, nil
   189}
   190
   191func (src <%= multirange_type %>) EncodeBinary(ci *ConnInfo, buf []byte) ([]byte, error) {
   192	switch src.Status {
   193	case Null:
   194		return nil, nil
   195	case Undefined:
   196		return nil, errUndefined
   197	}
   198
   199	buf = pgio.AppendInt32(buf, int32(len(src.Ranges)))
   200
   201	for i := range src.Ranges {
   202		sp := len(buf)
   203		buf = pgio.AppendInt32(buf, -1)
   204
   205		elemBuf, err := src.Ranges[i].EncodeBinary(ci, buf)
   206		if err != nil {
   207			return nil, err
   208		}
   209		if elemBuf != nil {
   210			buf = elemBuf
   211			pgio.SetInt32(buf[sp:], int32(len(buf[sp:])-4))
   212		}
   213	}
   214
   215	return buf, nil
   216}
   217
   218// Scan implements the database/sql Scanner interface.
   219func (dst *<%= multirange_type %>) Scan(src interface{}) error {
   220	if src == nil {
   221		return dst.DecodeText(nil, nil)
   222	}
   223
   224	switch src := src.(type) {
   225	case string:
   226		return dst.DecodeText(nil, []byte(src))
   227	case []byte:
   228		srcCopy := make([]byte, len(src))
   229		copy(srcCopy, src)
   230		return dst.DecodeText(nil, srcCopy)
   231	}
   232
   233	return fmt.Errorf("cannot scan %T", src)
   234}
   235
   236// Value implements the database/sql/driver Valuer interface.
   237func (src <%= multirange_type %>) Value() (driver.Value, error) {
   238	return EncodeValueText(src)
   239}

View as plain text