...

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

Documentation: github.com/jackc/pgtype

     1  package pgtype
     2  
     3  import (
     4  	"database/sql/driver"
     5  	"fmt"
     6  
     7  	"github.com/jackc/pgio"
     8  )
     9  
    10  type Numrange struct {
    11  	Lower     Numeric
    12  	Upper     Numeric
    13  	LowerType BoundType
    14  	UpperType BoundType
    15  	Status    Status
    16  }
    17  
    18  func (dst *Numrange) Set(src interface{}) error {
    19  	// untyped nil and typed nil interfaces are different
    20  	if src == nil {
    21  		*dst = Numrange{Status: Null}
    22  		return nil
    23  	}
    24  
    25  	switch value := src.(type) {
    26  	case Numrange:
    27  		*dst = value
    28  	case *Numrange:
    29  		*dst = *value
    30  	case string:
    31  		return dst.DecodeText(nil, []byte(value))
    32  	default:
    33  		return fmt.Errorf("cannot convert %v to Numrange", src)
    34  	}
    35  
    36  	return nil
    37  }
    38  
    39  func (dst Numrange) Get() interface{} {
    40  	switch dst.Status {
    41  	case Present:
    42  		return dst
    43  	case Null:
    44  		return nil
    45  	default:
    46  		return dst.Status
    47  	}
    48  }
    49  
    50  func (src *Numrange) AssignTo(dst interface{}) error {
    51  	return fmt.Errorf("cannot assign %v to %T", src, dst)
    52  }
    53  
    54  func (dst *Numrange) DecodeText(ci *ConnInfo, src []byte) error {
    55  	if src == nil {
    56  		*dst = Numrange{Status: Null}
    57  		return nil
    58  	}
    59  
    60  	utr, err := ParseUntypedTextRange(string(src))
    61  	if err != nil {
    62  		return err
    63  	}
    64  
    65  	*dst = Numrange{Status: Present}
    66  
    67  	dst.LowerType = utr.LowerType
    68  	dst.UpperType = utr.UpperType
    69  
    70  	if dst.LowerType == Empty {
    71  		return nil
    72  	}
    73  
    74  	if dst.LowerType == Inclusive || dst.LowerType == Exclusive {
    75  		if err := dst.Lower.DecodeText(ci, []byte(utr.Lower)); err != nil {
    76  			return err
    77  		}
    78  	}
    79  
    80  	if dst.UpperType == Inclusive || dst.UpperType == Exclusive {
    81  		if err := dst.Upper.DecodeText(ci, []byte(utr.Upper)); err != nil {
    82  			return err
    83  		}
    84  	}
    85  
    86  	return nil
    87  }
    88  
    89  func (dst *Numrange) DecodeBinary(ci *ConnInfo, src []byte) error {
    90  	if src == nil {
    91  		*dst = Numrange{Status: Null}
    92  		return nil
    93  	}
    94  
    95  	ubr, err := ParseUntypedBinaryRange(src)
    96  	if err != nil {
    97  		return err
    98  	}
    99  
   100  	*dst = Numrange{Status: Present}
   101  
   102  	dst.LowerType = ubr.LowerType
   103  	dst.UpperType = ubr.UpperType
   104  
   105  	if dst.LowerType == Empty {
   106  		return nil
   107  	}
   108  
   109  	if dst.LowerType == Inclusive || dst.LowerType == Exclusive {
   110  		if err := dst.Lower.DecodeBinary(ci, ubr.Lower); err != nil {
   111  			return err
   112  		}
   113  	}
   114  
   115  	if dst.UpperType == Inclusive || dst.UpperType == Exclusive {
   116  		if err := dst.Upper.DecodeBinary(ci, ubr.Upper); err != nil {
   117  			return err
   118  		}
   119  	}
   120  
   121  	return nil
   122  }
   123  
   124  func (src Numrange) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
   125  	switch src.Status {
   126  	case Null:
   127  		return nil, nil
   128  	case Undefined:
   129  		return nil, errUndefined
   130  	}
   131  
   132  	switch src.LowerType {
   133  	case Exclusive, Unbounded:
   134  		buf = append(buf, '(')
   135  	case Inclusive:
   136  		buf = append(buf, '[')
   137  	case Empty:
   138  		return append(buf, "empty"...), nil
   139  	default:
   140  		return nil, fmt.Errorf("unknown lower bound type %v", src.LowerType)
   141  	}
   142  
   143  	var err error
   144  
   145  	if src.LowerType != Unbounded {
   146  		buf, err = src.Lower.EncodeText(ci, buf)
   147  		if err != nil {
   148  			return nil, err
   149  		} else if buf == nil {
   150  			return nil, fmt.Errorf("Lower cannot be null unless LowerType is Unbounded")
   151  		}
   152  	}
   153  
   154  	buf = append(buf, ',')
   155  
   156  	if src.UpperType != Unbounded {
   157  		buf, err = src.Upper.EncodeText(ci, buf)
   158  		if err != nil {
   159  			return nil, err
   160  		} else if buf == nil {
   161  			return nil, fmt.Errorf("Upper cannot be null unless UpperType is Unbounded")
   162  		}
   163  	}
   164  
   165  	switch src.UpperType {
   166  	case Exclusive, Unbounded:
   167  		buf = append(buf, ')')
   168  	case Inclusive:
   169  		buf = append(buf, ']')
   170  	default:
   171  		return nil, fmt.Errorf("unknown upper bound type %v", src.UpperType)
   172  	}
   173  
   174  	return buf, nil
   175  }
   176  
   177  func (src Numrange) EncodeBinary(ci *ConnInfo, buf []byte) ([]byte, error) {
   178  	switch src.Status {
   179  	case Null:
   180  		return nil, nil
   181  	case Undefined:
   182  		return nil, errUndefined
   183  	}
   184  
   185  	var rangeType byte
   186  	switch src.LowerType {
   187  	case Inclusive:
   188  		rangeType |= lowerInclusiveMask
   189  	case Unbounded:
   190  		rangeType |= lowerUnboundedMask
   191  	case Exclusive:
   192  	case Empty:
   193  		return append(buf, emptyMask), nil
   194  	default:
   195  		return nil, fmt.Errorf("unknown LowerType: %v", src.LowerType)
   196  	}
   197  
   198  	switch src.UpperType {
   199  	case Inclusive:
   200  		rangeType |= upperInclusiveMask
   201  	case Unbounded:
   202  		rangeType |= upperUnboundedMask
   203  	case Exclusive:
   204  	default:
   205  		return nil, fmt.Errorf("unknown UpperType: %v", src.UpperType)
   206  	}
   207  
   208  	buf = append(buf, rangeType)
   209  
   210  	var err error
   211  
   212  	if src.LowerType != Unbounded {
   213  		sp := len(buf)
   214  		buf = pgio.AppendInt32(buf, -1)
   215  
   216  		buf, err = src.Lower.EncodeBinary(ci, buf)
   217  		if err != nil {
   218  			return nil, err
   219  		}
   220  		if buf == nil {
   221  			return nil, fmt.Errorf("Lower cannot be null unless LowerType is Unbounded")
   222  		}
   223  
   224  		pgio.SetInt32(buf[sp:], int32(len(buf[sp:])-4))
   225  	}
   226  
   227  	if src.UpperType != Unbounded {
   228  		sp := len(buf)
   229  		buf = pgio.AppendInt32(buf, -1)
   230  
   231  		buf, err = src.Upper.EncodeBinary(ci, buf)
   232  		if err != nil {
   233  			return nil, err
   234  		}
   235  		if buf == nil {
   236  			return nil, fmt.Errorf("Upper cannot be null unless UpperType is Unbounded")
   237  		}
   238  
   239  		pgio.SetInt32(buf[sp:], int32(len(buf[sp:])-4))
   240  	}
   241  
   242  	return buf, nil
   243  }
   244  
   245  // Scan implements the database/sql Scanner interface.
   246  func (dst *Numrange) Scan(src interface{}) error {
   247  	if src == nil {
   248  		*dst = Numrange{Status: Null}
   249  		return nil
   250  	}
   251  
   252  	switch src := src.(type) {
   253  	case string:
   254  		return dst.DecodeText(nil, []byte(src))
   255  	case []byte:
   256  		srcCopy := make([]byte, len(src))
   257  		copy(srcCopy, src)
   258  		return dst.DecodeText(nil, srcCopy)
   259  	}
   260  
   261  	return fmt.Errorf("cannot scan %T", src)
   262  }
   263  
   264  // Value implements the database/sql/driver Valuer interface.
   265  func (src Numrange) Value() (driver.Value, error) {
   266  	return EncodeValueText(src)
   267  }
   268  

View as plain text