Skip to content

Commit

Permalink
dynamodb: Do not omit empty value in some types
Browse files Browse the repository at this point in the history
  • Loading branch information
TANABE Ken-ichi committed Jan 6, 2014
1 parent 49c7886 commit 14fa9b4
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
14 changes: 13 additions & 1 deletion dynamodb/marshaller.go
Expand Up @@ -20,7 +20,7 @@ func MarshalAttributes(m interface{}) ([]Attribute, error) {
builder.buffer = []Attribute{}
for _, f := range cachedTypeFields(v.Type()) { // loop on each field
fv := fieldByIndex(v, f.index)
if !fv.IsValid() || isEmptyValue(fv) {
if !fv.IsValid() || isEmptyValueToOmit(fv) {
continue
}

Expand Down Expand Up @@ -293,6 +293,18 @@ func numericReflectedValueString(v reflect.Value) (string, error) {
return "", fmt.Errorf("UnsupportedNumericValueError %#v", v.Type())
}

// In DynamoDB we should omit empty value in some type
// See http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html
func isEmptyValueToOmit(v reflect.Value) bool {
switch v.Kind() {
case reflect.Array, reflect.Map, reflect.Slice, reflect.String, reflect.Interface, reflect.Ptr:
// should omit if empty value
return isEmptyValue(v)
}
// otherwise should not omit
return false
}

// ---------------- Below are copied handy functions from http://golang.org/src/pkg/encoding/json/encode.go --------------------------------
func isEmptyValue(v reflect.Value) bool {
switch v.Kind() {
Expand Down
28 changes: 28 additions & 0 deletions dynamodb/marshaller_test.go
Expand Up @@ -65,6 +65,10 @@ func testObjectTime() *TestStructTime {
}
}

func testObjectWithZeroValues() *TestStruct {
return &TestStruct{}
}

func testObjectWithNilSets() *TestStruct {
return &TestStruct{
TestBool: true,
Expand Down Expand Up @@ -135,6 +139,19 @@ func testAttrsTime() []dynamodb.Attribute {
}
}

func testAttrsWithZeroValues() []dynamodb.Attribute {
return []dynamodb.Attribute{
dynamodb.Attribute{Type: "N", Name: "TestBool", Value: "0", SetValues: []string(nil)},
dynamodb.Attribute{Type: "N", Name: "TestInt", Value: "0", SetValues: []string(nil)},
dynamodb.Attribute{Type: "N", Name: "TestInt32", Value: "0", SetValues: []string(nil)},
dynamodb.Attribute{Type: "N", Name: "TestInt64", Value: "0", SetValues: []string(nil)},
dynamodb.Attribute{Type: "N", Name: "TestUint", Value: "0", SetValues: []string(nil)},
dynamodb.Attribute{Type: "N", Name: "TestFloat32", Value: "0", SetValues: []string(nil)},
dynamodb.Attribute{Type: "N", Name: "TestFloat64", Value: "0", SetValues: []string(nil)},
dynamodb.Attribute{Type: "S", Name: "TestSub", Value: `{"SubBool":false,"SubInt":0,"SubString":"","SubStringArray":null}`, SetValues: []string(nil)},
}
}

func testAttrsWithNilSets() []dynamodb.Attribute {
return []dynamodb.Attribute{
dynamodb.Attribute{Type: "N", Name: "TestBool", Value: "1", SetValues: []string(nil)},
Expand Down Expand Up @@ -224,6 +241,17 @@ func (s *MarshallerSuite) TestMarshalNilSets(c *gocheck.C) {
c.Check(attrs, gocheck.DeepEquals, expected)
}

func (s *MarshallerSuite) TestMarshalZeroValues(c *gocheck.C) {
testObj := testObjectWithZeroValues()
attrs, err := dynamodb.MarshalAttributes(testObj)
if err != nil {
c.Errorf("Error from dynamodb.MarshalAttributes: %#v", err)
}

expected := testAttrsWithZeroValues()
c.Check(attrs, gocheck.DeepEquals, expected)
}

func (s *MarshallerSuite) TestMarshalEmptySets(c *gocheck.C) {
testObj := testObjectWithEmptySets()
attrs, err := dynamodb.MarshalAttributes(testObj)
Expand Down

0 comments on commit 14fa9b4

Please sign in to comment.