Bump deps

This commit is contained in:
Jeff Mitchell
2017-03-30 20:03:13 -04:00
parent 1f0d9b10b6
commit 7902612773
378 changed files with 61384 additions and 4576 deletions

View File

@@ -181,7 +181,7 @@ func (d *Decoder) decode(av *dynamodb.AttributeValue, v reflect.Value, fieldTag
case len(av.M) != 0:
return d.decodeMap(av.M, v)
case av.N != nil:
return d.decodeNumber(av.N, v)
return d.decodeNumber(av.N, v, fieldTag)
case len(av.NS) != 0:
return d.decodeNumberSet(av.NS, v)
case av.S != nil:
@@ -286,7 +286,7 @@ func (d *Decoder) decodeBinarySet(bs [][]byte, v reflect.Value) error {
return nil
}
func (d *Decoder) decodeNumber(n *string, v reflect.Value) error {
func (d *Decoder) decodeNumber(n *string, v reflect.Value, fieldTag tag) error {
switch v.Kind() {
case reflect.Interface:
i, err := d.decodeNumberToInterface(n)
@@ -338,6 +338,14 @@ func (d *Decoder) decodeNumber(n *string, v reflect.Value) error {
}
v.SetFloat(i)
default:
if _, ok := v.Interface().(time.Time); ok && fieldTag.AsUnixTime {
t, err := decodeUnixTime(*n)
if err != nil {
return err
}
v.Set(reflect.ValueOf(t))
return nil
}
return &UnmarshalTypeError{Value: "number", Type: v.Type()}
}
@@ -367,7 +375,7 @@ func (d *Decoder) decodeNumberSet(ns []*string, v reflect.Value) error {
if d.UseNumber {
set := make([]Number, len(ns))
for i, n := range ns {
if err := d.decodeNumber(n, reflect.ValueOf(&set[i]).Elem()); err != nil {
if err := d.decodeNumber(n, reflect.ValueOf(&set[i]).Elem(), tag{}); err != nil {
return err
}
}
@@ -375,7 +383,7 @@ func (d *Decoder) decodeNumberSet(ns []*string, v reflect.Value) error {
} else {
set := make([]float64, len(ns))
for i, n := range ns {
if err := d.decodeNumber(n, reflect.ValueOf(&set[i]).Elem()); err != nil {
if err := d.decodeNumber(n, reflect.ValueOf(&set[i]).Elem(), tag{}); err != nil {
return err
}
}
@@ -392,7 +400,7 @@ func (d *Decoder) decodeNumberSet(ns []*string, v reflect.Value) error {
if u != nil {
return u.UnmarshalDynamoDBAttributeValue(&dynamodb.AttributeValue{NS: ns})
}
if err := d.decodeNumber(ns[i], elem); err != nil {
if err := d.decodeNumber(ns[i], elem, tag{}); err != nil {
return err
}
}
@@ -489,7 +497,7 @@ func (d *Decoder) decodeNull(v reflect.Value) error {
func (d *Decoder) decodeString(s *string, v reflect.Value, fieldTag tag) error {
if fieldTag.AsString {
return d.decodeNumber(s, v)
return d.decodeNumber(s, v, fieldTag)
}
// To maintain backwards compatibility with ConvertFrom family of methods which
@@ -552,6 +560,17 @@ func (d *Decoder) decodeStringSet(ss []*string, v reflect.Value) error {
return nil
}
func decodeUnixTime(n string) (time.Time, error) {
v, err := strconv.ParseInt(n, 10, 64)
if err != nil {
return time.Time{}, &UnmarshalError{
Err: err, Value: n, Type: reflect.TypeOf(time.Time{}),
}
}
return time.Unix(v, 0), nil
}
// indirect will walk a value's interface or pointer value types. Returning
// the final value or the value a unmarshaler is defined on.
//
@@ -678,3 +697,36 @@ func (e *InvalidUnmarshalError) Message() string {
}
return "cannot unmarshal to nil value, " + e.Type.String()
}
// An UnmarshalError wraps an error that occured while unmarshaling a DynamoDB
// AttributeValue element into a Go type. This is different from UnmarshalTypeError
// in that it wraps the underlying error that occured.
type UnmarshalError struct {
Err error
Value string
Type reflect.Type
}
// Error returns the string representation of the error.
// satisfying the error interface.
func (e *UnmarshalError) Error() string {
return fmt.Sprintf("%s: %s\ncaused by: %v", e.Code(), e.Message(), e.Err)
}
// OrigErr returns the original error that caused this issue.
func (e UnmarshalError) OrigErr() error {
return e.Err
}
// Code returns the code of the error, satisfying the awserr.Error
// interface.
func (e *UnmarshalError) Code() string {
return "UnmarshalError"
}
// Message returns the detailed message of the error, satisfying
// the awserr.Error interface.
func (e *UnmarshalError) Message() string {
return fmt.Sprintf("cannot unmarshal %q into %s.",
e.Value, e.Type.String())
}

View File

@@ -6,9 +6,50 @@ import (
"strconv"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/dynamodb"
)
// An UnixTime provides aliasing of time.Time into a type that when marshaled
// and unmarshaled with DynamoDB AttributeValues it will be done so as number
// instead of string in seconds since January 1, 1970 UTC.
//
// This type is useful as an alterntitive to the struct tag `unixtime` when you
// want to have your time value marshaled as Unix time in seconds intead of
// the default time.RFC3339.
//
// Important to note that zero value time as unixtime is not 0 seconds
// from January 1, 1970 UTC, but -62135596800. Which is seconds between
// January 1, 0001 UTC, and January 1, 0001 UTC.
type UnixTime time.Time
// MarshalDynamoDBAttributeValue implements the Marshaler interface so that
// the UnixTime can be marshaled from to a DynamoDB AttributeValue number
// value encoded in the number of seconds since January 1, 1970 UTC.
func (e UnixTime) MarshalDynamoDBAttributeValue(av *dynamodb.AttributeValue) error {
t := time.Time(e)
s := strconv.FormatInt(t.Unix(), 10)
av.N = &s
return nil
}
// UnmarshalDynamoDBAttributeValue implements the Unmarshaler interface so that
// the UnixTime can be unmarshaled from a DynamoDB AttributeValue number representing
// the number of seconds since January 1, 1970 UTC.
//
// If an error parsing the AttributeValue number occurs UnmarshalError will be
// returned.
func (e *UnixTime) UnmarshalDynamoDBAttributeValue(av *dynamodb.AttributeValue) error {
t, err := decodeUnixTime(aws.StringValue(av.N))
if err != nil {
return err
}
*e = UnixTime(t)
return nil
}
// A Marshaler is an interface to provide custom marshaling of Go value types
// to AttributeValues. Use this to provide custom logic determining how a
// Go Value type should be marshaled.
@@ -75,6 +116,13 @@ type Marshaler interface {
// // Field will be marshaled as a string set
// Field []string `dynamodbav:",stringset"`
//
// // Field will be marshaled as Unix time number in seconds.
// // This tag is only valid with time.Time typed struct fields.
// // Important to note that zero value time as unixtime is not 0 seconds
// // from January 1, 1970 UTC, but -62135596800. Which is seconds between
// // January 1, 0001 UTC, and January 1, 0001 UTC.
// Field time.Time `dynamodbav:",unixtime"`
//
// The omitempty tag is only used during Marshaling and is ignored for
// Unmarshal. Any zero value or a value when marshaled results in a
// AttributeValue NULL will be added to AttributeValue Maps during struct
@@ -219,7 +267,7 @@ func (e *Encoder) encode(av *dynamodb.AttributeValue, v reflect.Value, fieldTag
case reflect.Invalid:
encodeNull(av)
case reflect.Struct:
return e.encodeStruct(av, v)
return e.encodeStruct(av, v, fieldTag)
case reflect.Map:
return e.encodeMap(av, v, fieldTag)
case reflect.Slice, reflect.Array:
@@ -233,11 +281,13 @@ func (e *Encoder) encode(av *dynamodb.AttributeValue, v reflect.Value, fieldTag
return nil
}
func (e *Encoder) encodeStruct(av *dynamodb.AttributeValue, v reflect.Value) error {
func (e *Encoder) encodeStruct(av *dynamodb.AttributeValue, v reflect.Value, fieldTag tag) error {
// To maintain backwards compatibility with ConvertTo family of methods which
// converted time.Time structs to strings
if t, ok := v.Interface().(time.Time); ok {
if fieldTag.AsUnixTime {
return UnixTime(t).MarshalDynamoDBAttributeValue(av)
}
s := t.Format(time.RFC3339Nano)
av.S = &s
return nil

View File

@@ -12,6 +12,7 @@ type tag struct {
OmitEmptyElem bool
AsString bool
AsBinSet, AsNumSet, AsStrSet bool
AsUnixTime bool
}
func (t *tag) parseAVTag(structTag reflect.StructTag) {
@@ -60,6 +61,8 @@ func (t *tag) parseTagStr(tagStr string) {
t.AsNumSet = true
case "stringset":
t.AsStrSet = true
case "unixtime":
t.AsUnixTime = true
}
}
}