...

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

Documentation: github.com/jackc/pgtype

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

View as plain text