diff options
Diffstat (limited to 'vendor/github.com/goamz/goamz/dynamodb')
20 files changed, 0 insertions, 4092 deletions
diff --git a/vendor/github.com/goamz/goamz/dynamodb/.gitignore b/vendor/github.com/goamz/goamz/dynamodb/.gitignore deleted file mode 100644 index 2385ddf57..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/.gitignore +++ /dev/null @@ -1 +0,0 @@ -dynamodb_local* diff --git a/vendor/github.com/goamz/goamz/dynamodb/Makefile b/vendor/github.com/goamz/goamz/dynamodb/Makefile deleted file mode 100644 index 4c02cd4b7..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -DYNAMODB_LOCAL_VERSION = 2013-12-12 - -launch: DynamoDBLocal.jar - cd dynamodb_local_$(DYNAMODB_LOCAL_VERSION) && java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar - -DynamoDBLocal.jar: dynamodb_local_$(DYNAMODB_LOCAL_VERSION).tar.gz - [ -d dynamodb_local_$(DYNAMODB_LOCAL_VERSION) ] || tar -zxf dynamodb_local_$(DYNAMODB_LOCAL_VERSION).tar.gz - -dynamodb_local_$(DYNAMODB_LOCAL_VERSION).tar.gz: - curl -O https://s3-us-west-2.amazonaws.com/dynamodb-local/dynamodb_local_$(DYNAMODB_LOCAL_VERSION).tar.gz - -clean: - rm -rf dynamodb_local_$(DYNAMODB_LOCAL_VERSION)* diff --git a/vendor/github.com/goamz/goamz/dynamodb/README.md b/vendor/github.com/goamz/goamz/dynamodb/README.md deleted file mode 100644 index 5896d67b6..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Running integration tests - -## against DynamoDB local - -To download and launch DynamoDB local: - -```sh -$ make -``` - -To test: - -```sh -$ go test -v -amazon -``` - -## against real DynamoDB server on us-east - -_WARNING_: Some dangerous operations such as `DeleteTable` will be performed during the tests. Please be careful. - -To test: - -```sh -$ go test -v -amazon -local=false -``` - -_Note_: Running tests against real DynamoDB will take several minutes. diff --git a/vendor/github.com/goamz/goamz/dynamodb/attribute.go b/vendor/github.com/goamz/goamz/dynamodb/attribute.go deleted file mode 100755 index 38389ada2..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/attribute.go +++ /dev/null @@ -1,185 +0,0 @@ -package dynamodb - -import ( - "strconv" -) - -const ( - TYPE_STRING = "S" - TYPE_NUMBER = "N" - TYPE_BINARY = "B" - - TYPE_STRING_SET = "SS" - TYPE_NUMBER_SET = "NS" - TYPE_BINARY_SET = "BS" - - COMPARISON_EQUAL = "EQ" - COMPARISON_NOT_EQUAL = "NE" - COMPARISON_LESS_THAN_OR_EQUAL = "LE" - COMPARISON_LESS_THAN = "LT" - COMPARISON_GREATER_THAN_OR_EQUAL = "GE" - COMPARISON_GREATER_THAN = "GT" - COMPARISON_ATTRIBUTE_EXISTS = "NOT_NULL" - COMPARISON_ATTRIBUTE_DOES_NOT_EXIST = "NULL" - COMPARISON_CONTAINS = "CONTAINS" - COMPARISON_DOES_NOT_CONTAIN = "NOT_CONTAINS" - COMPARISON_BEGINS_WITH = "BEGINS_WITH" - COMPARISON_IN = "IN" - COMPARISON_BETWEEN = "BETWEEN" -) - -type Key struct { - HashKey string - RangeKey string -} - -type PrimaryKey struct { - KeyAttribute *Attribute - RangeAttribute *Attribute -} - -type Attribute struct { - Type string - Name string - Value string - SetValues []string - Exists string // exists on dynamodb? Values: "true", "false", or "" -} - -type AttributeComparison struct { - AttributeName string - ComparisonOperator string - AttributeValueList []Attribute // contains attributes with only types and names (value ignored) -} - -func NewEqualInt64AttributeComparison(attributeName string, equalToValue int64) *AttributeComparison { - numeric := NewNumericAttribute(attributeName, strconv.FormatInt(equalToValue, 10)) - return &AttributeComparison{attributeName, - COMPARISON_EQUAL, - []Attribute{*numeric}, - } -} - -func NewEqualStringAttributeComparison(attributeName string, equalToValue string) *AttributeComparison { - str := NewStringAttribute(attributeName, equalToValue) - return &AttributeComparison{attributeName, - COMPARISON_EQUAL, - []Attribute{*str}, - } -} - -func NewStringAttributeComparison(attributeName string, comparisonOperator string, value string) *AttributeComparison { - valueToCompare := NewStringAttribute(attributeName, value) - return &AttributeComparison{attributeName, - comparisonOperator, - []Attribute{*valueToCompare}, - } -} - -func NewNumericAttributeComparison(attributeName string, comparisonOperator string, value int64) *AttributeComparison { - valueToCompare := NewNumericAttribute(attributeName, strconv.FormatInt(value, 10)) - return &AttributeComparison{attributeName, - comparisonOperator, - []Attribute{*valueToCompare}, - } -} - -func NewBinaryAttributeComparison(attributeName string, comparisonOperator string, value bool) *AttributeComparison { - valueToCompare := NewBinaryAttribute(attributeName, strconv.FormatBool(value)) - return &AttributeComparison{attributeName, - comparisonOperator, - []Attribute{*valueToCompare}, - } -} - -func NewStringAttribute(name string, value string) *Attribute { - return &Attribute{ - Type: TYPE_STRING, - Name: name, - Value: value, - } -} - -func NewNumericAttribute(name string, value string) *Attribute { - return &Attribute{ - Type: TYPE_NUMBER, - Name: name, - Value: value, - } -} - -func NewBinaryAttribute(name string, value string) *Attribute { - return &Attribute{ - Type: TYPE_BINARY, - Name: name, - Value: value, - } -} - -func NewStringSetAttribute(name string, values []string) *Attribute { - return &Attribute{ - Type: TYPE_STRING_SET, - Name: name, - SetValues: values, - } -} - -func NewNumericSetAttribute(name string, values []string) *Attribute { - return &Attribute{ - Type: TYPE_NUMBER_SET, - Name: name, - SetValues: values, - } -} - -func NewBinarySetAttribute(name string, values []string) *Attribute { - return &Attribute{ - Type: TYPE_BINARY_SET, - Name: name, - SetValues: values, - } -} - -func (a *Attribute) SetType() bool { - switch a.Type { - case TYPE_BINARY_SET, TYPE_NUMBER_SET, TYPE_STRING_SET: - return true - } - return false -} - -func (a *Attribute) SetExists(exists bool) *Attribute { - if exists { - a.Exists = "true" - } else { - a.Exists = "false" - } - return a -} - -func (k *PrimaryKey) HasRange() bool { - return k.RangeAttribute != nil -} - -// Useful when you may have many goroutines using a primary key, so they don't fuxor up your values. -func (k *PrimaryKey) Clone(h string, r string) []Attribute { - pk := &Attribute{ - Type: k.KeyAttribute.Type, - Name: k.KeyAttribute.Name, - Value: h, - } - - result := []Attribute{*pk} - - if k.HasRange() { - rk := &Attribute{ - Type: k.RangeAttribute.Type, - Name: k.RangeAttribute.Name, - Value: r, - } - - result = append(result, *rk) - } - - return result -} diff --git a/vendor/github.com/goamz/goamz/dynamodb/const.go b/vendor/github.com/goamz/goamz/dynamodb/const.go deleted file mode 100644 index b070d44cb..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/const.go +++ /dev/null @@ -1,11 +0,0 @@ -package dynamodb - -type ReturnValues string - -const ( - NONE ReturnValues = "NONE" - ALL_OLD ReturnValues = "ALL_HOLD" - UPDATED_OLD ReturnValues = "UPDATED_OLD" - ALL_NEW ReturnValues = "ALL_NEW" - UPDATED_NEW ReturnValues = "UPDATED_NEW" -) diff --git a/vendor/github.com/goamz/goamz/dynamodb/dynamodb.go b/vendor/github.com/goamz/goamz/dynamodb/dynamodb.go deleted file mode 100755 index 7881e8dc1..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/dynamodb.go +++ /dev/null @@ -1,142 +0,0 @@ -package dynamodb - -import simplejson "github.com/bitly/go-simplejson" -import ( - "errors" - "github.com/goamz/goamz/aws" - "io/ioutil" - "log" - "net/http" - "strings" - "time" -) - -type Server struct { - Auth aws.Auth - Region aws.Region -} - -/* -type Query struct { - Query string -} -*/ - -/* -func NewQuery(queryParts []string) *Query { - return &Query{ - "{" + strings.Join(queryParts, ",") + "}", - } -} -*/ - -const ( - // DynamoDBAPIPrefix is the versioned prefix for DynamoDB API commands. - DynamoDBAPIPrefix = "DynamoDB_20120810." - // DynamoDBStreamsAPIPrefix is the versioned prefix for DynamoDB Streams API commands. - DynamoDBStreamsAPIPrefix = "DynamoDBStreams_20120810." -) - -// Specific error constants -var ErrNotFound = errors.New("Item not found") - -// Error represents an error in an operation with Dynamodb (following goamz/s3) -type Error struct { - StatusCode int // HTTP status code (200, 403, ...) - Status string - Code string // Dynamodb error code ("MalformedQueryString", ...) - Message string // The human-oriented error message -} - -func (e *Error) Error() string { - return e.Code + ": " + e.Message -} - -func buildError(r *http.Response, jsonBody []byte) error { - - ddbError := Error{ - StatusCode: r.StatusCode, - Status: r.Status, - } - // TODO return error if Unmarshal fails? - - json, err := simplejson.NewJson(jsonBody) - if err != nil { - log.Printf("Failed to parse body as JSON") - return err - } - ddbError.Message = json.Get("message").MustString() - - // Of the form: com.amazon.coral.validate#ValidationException - // We only want the last part - codeStr := json.Get("__type").MustString() - hashIndex := strings.Index(codeStr, "#") - if hashIndex > 0 { - codeStr = codeStr[hashIndex+1:] - } - ddbError.Code = codeStr - - return &ddbError -} - -func (s *Server) queryServer(target string, query *Query) ([]byte, error) { - data := strings.NewReader(query.String()) - var endpoint string - if isStreamsTarget(target) { - endpoint = s.Region.DynamoDBStreamsEndpoint - } else { - endpoint = s.Region.DynamoDBEndpoint - } - hreq, err := http.NewRequest("POST", endpoint+"/", data) - if err != nil { - return nil, err - } - - hreq.Header.Set("Content-Type", "application/x-amz-json-1.0") - hreq.Header.Set("X-Amz-Date", time.Now().UTC().Format(aws.ISO8601BasicFormat)) - hreq.Header.Set("X-Amz-Target", target) - - token := s.Auth.Token() - if token != "" { - hreq.Header.Set("X-Amz-Security-Token", token) - } - - signer := aws.NewV4Signer(s.Auth, "dynamodb", s.Region) - signer.Sign(hreq) - - resp, err := http.DefaultClient.Do(hreq) - - if err != nil { - log.Printf("Error calling Amazon") - return nil, err - } - - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Printf("Could not read response body") - return nil, err - } - - // http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ErrorHandling.html - // "A response code of 200 indicates the operation was successful." - if resp.StatusCode != 200 { - ddbErr := buildError(resp, body) - return nil, ddbErr - } - - return body, nil -} - -func target(name string) string { - return DynamoDBAPIPrefix + name -} - -func streamsTarget(name string) string { - return DynamoDBStreamsAPIPrefix + name -} - -func isStreamsTarget(target string) bool { - return strings.HasPrefix(target, DynamoDBStreamsAPIPrefix) -} diff --git a/vendor/github.com/goamz/goamz/dynamodb/dynamodb_test.go b/vendor/github.com/goamz/goamz/dynamodb/dynamodb_test.go deleted file mode 100755 index 63dd03da3..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/dynamodb_test.go +++ /dev/null @@ -1,166 +0,0 @@ -package dynamodb_test - -import ( - "flag" - "testing" - "time" - - "github.com/goamz/goamz/aws" - "github.com/goamz/goamz/dynamodb" - . "gopkg.in/check.v1" -) - -const TIMEOUT = 3 * time.Minute - -var amazon = flag.Bool("amazon", false, "Enable tests against dynamodb") -var local = flag.Bool("local", true, "Use DynamoDB local on 8080 instead of real server on us-east.") - -var dynamodb_region aws.Region -var dynamodb_auth aws.Auth - -type DynamoDBTest struct { - server *dynamodb.Server - aws.Region // Exports Region - TableDescriptionT dynamodb.TableDescriptionT - table *dynamodb.Table -} - -// Delete all items in the table -func (s *DynamoDBTest) TearDownTest(c *C) { - pk, err := s.TableDescriptionT.BuildPrimaryKey() - if err != nil { - c.Fatal(err) - } - - attrs, err := s.table.Scan(nil) - if err != nil { - c.Fatal(err) - } - for _, a := range attrs { - key := &dynamodb.Key{ - HashKey: a[pk.KeyAttribute.Name].Value, - } - if pk.HasRange() { - key.RangeKey = a[pk.RangeAttribute.Name].Value - } - if ok, err := s.table.DeleteItem(key); !ok { - c.Fatal(err) - } - } -} - -func (s *DynamoDBTest) TearDownSuite(c *C) { - // return immediately in the case of calling c.Skip() in SetUpSuite() - if s.server == nil { - return - } - - // check whether the table exists - if tables, err := s.server.ListTables(); err != nil { - c.Fatal(err) - } else { - if !findTableByName(tables, s.TableDescriptionT.TableName) { - return - } - } - - // Delete the table and wait - if _, err := s.server.DeleteTable(s.TableDescriptionT); err != nil { - c.Fatal(err) - } - - done := make(chan bool) - timeout := time.After(TIMEOUT) - go func() { - for { - select { - case <-done: - return - default: - tables, err := s.server.ListTables() - if err != nil { - c.Fatal(err) - } - if findTableByName(tables, s.TableDescriptionT.TableName) { - time.Sleep(5 * time.Second) - } else { - done <- true - return - } - } - } - }() - select { - case <-done: - break - case <-timeout: - c.Error("Expect the table to be deleted but timed out") - close(done) - } -} - -func (s *DynamoDBTest) WaitUntilStatus(c *C, status string) { - // We should wait until the table is in specified status because a real DynamoDB has some delay for ready - done := make(chan bool) - timeout := time.After(TIMEOUT) - go func() { - for { - select { - case <-done: - return - default: - desc, err := s.table.DescribeTable() - if err != nil { - c.Fatal(err) - } - if desc.TableStatus == status { - done <- true - return - } - time.Sleep(5 * time.Second) - } - } - }() - select { - case <-done: - break - case <-timeout: - c.Errorf("Expect a status to be %s, but timed out", status) - close(done) - } -} - -func setUpAuth(c *C) { - if !*amazon { - c.Skip("Test against amazon not enabled.") - } - if *local { - c.Log("Using local server") - dynamodb_region = aws.Region{ - DynamoDBEndpoint: "http://127.0.0.1:8000", - DynamoDBStreamsEndpoint: "http://127.0.0.1:8000", - } - dynamodb_auth = aws.Auth{AccessKey: "DUMMY_KEY", SecretKey: "DUMMY_SECRET"} - } else { - c.Log("Using REAL AMAZON SERVER") - dynamodb_region = aws.USEast - auth, err := aws.EnvAuth() - if err != nil { - c.Fatal(err) - } - dynamodb_auth = auth - } -} - -func findTableByName(tables []string, name string) bool { - for _, t := range tables { - if t == name { - return true - } - } - return false -} - -func Test(t *testing.T) { - TestingT(t) -} diff --git a/vendor/github.com/goamz/goamz/dynamodb/item.go b/vendor/github.com/goamz/goamz/dynamodb/item.go deleted file mode 100755 index a3814d9ad..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/item.go +++ /dev/null @@ -1,351 +0,0 @@ -package dynamodb - -import simplejson "github.com/bitly/go-simplejson" -import ( - "errors" - "fmt" - "log" -) - -type BatchGetItem struct { - Server *Server - Keys map[*Table][]Key -} - -type BatchWriteItem struct { - Server *Server - ItemActions map[*Table]map[string][][]Attribute -} - -func (t *Table) BatchGetItems(keys []Key) *BatchGetItem { - batchGetItem := &BatchGetItem{t.Server, make(map[*Table][]Key)} - - batchGetItem.Keys[t] = keys - return batchGetItem -} - -func (t *Table) BatchWriteItems(itemActions map[string][][]Attribute) *BatchWriteItem { - batchWriteItem := &BatchWriteItem{t.Server, make(map[*Table]map[string][][]Attribute)} - - batchWriteItem.ItemActions[t] = itemActions - return batchWriteItem -} - -func (batchGetItem *BatchGetItem) AddTable(t *Table, keys *[]Key) *BatchGetItem { - batchGetItem.Keys[t] = *keys - return batchGetItem -} - -func (batchWriteItem *BatchWriteItem) AddTable(t *Table, itemActions *map[string][][]Attribute) *BatchWriteItem { - batchWriteItem.ItemActions[t] = *itemActions - return batchWriteItem -} - -func (batchGetItem *BatchGetItem) Execute() (map[string][]map[string]*Attribute, error) { - q := NewEmptyQuery() - q.AddGetRequestItems(batchGetItem.Keys) - - jsonResponse, err := batchGetItem.Server.queryServer("DynamoDB_20120810.BatchGetItem", q) - if err != nil { - return nil, err - } - - json, err := simplejson.NewJson(jsonResponse) - - if err != nil { - return nil, err - } - - results := make(map[string][]map[string]*Attribute) - - tables, err := json.Get("Responses").Map() - if err != nil { - message := fmt.Sprintf("Unexpected response %s", jsonResponse) - return nil, errors.New(message) - } - - for table, entries := range tables { - var tableResult []map[string]*Attribute - - jsonEntriesArray, ok := entries.([]interface{}) - if !ok { - message := fmt.Sprintf("Unexpected response %s", jsonResponse) - return nil, errors.New(message) - } - - for _, entry := range jsonEntriesArray { - item, ok := entry.(map[string]interface{}) - if !ok { - message := fmt.Sprintf("Unexpected response %s", jsonResponse) - return nil, errors.New(message) - } - - unmarshalledItem := parseAttributes(item) - tableResult = append(tableResult, unmarshalledItem) - } - - results[table] = tableResult - } - - return results, nil -} - -func (batchWriteItem *BatchWriteItem) Execute() (map[string]interface{}, error) { - q := NewEmptyQuery() - q.AddWriteRequestItems(batchWriteItem.ItemActions) - - jsonResponse, err := batchWriteItem.Server.queryServer("DynamoDB_20120810.BatchWriteItem", q) - - if err != nil { - return nil, err - } - - json, err := simplejson.NewJson(jsonResponse) - - if err != nil { - return nil, err - } - - unprocessed, err := json.Get("UnprocessedItems").Map() - if err != nil { - message := fmt.Sprintf("Unexpected response %s", jsonResponse) - return nil, errors.New(message) - } - - if len(unprocessed) == 0 { - return nil, nil - } else { - return unprocessed, errors.New("One or more unprocessed items.") - } - -} - -func (t *Table) GetItem(key *Key) (map[string]*Attribute, error) { - return t.getItem(key, false) -} - -func (t *Table) GetItemConsistent(key *Key, consistentRead bool) (map[string]*Attribute, error) { - return t.getItem(key, consistentRead) -} - -func (t *Table) getItem(key *Key, consistentRead bool) (map[string]*Attribute, error) { - q := NewQuery(t) - q.AddKey(t, key) - - if consistentRead { - q.ConsistentRead(consistentRead) - } - - jsonResponse, err := t.Server.queryServer(target("GetItem"), q) - if err != nil { - return nil, err - } - - json, err := simplejson.NewJson(jsonResponse) - if err != nil { - return nil, err - } - - itemJson, ok := json.CheckGet("Item") - if !ok { - // We got an empty from amz. The item doesn't exist. - return nil, ErrNotFound - } - - item, err := itemJson.Map() - if err != nil { - message := fmt.Sprintf("Unexpected response %s", jsonResponse) - return nil, errors.New(message) - } - - return parseAttributes(item), nil - -} - -func (t *Table) PutItem(hashKey string, rangeKey string, attributes []Attribute) (bool, error) { - return t.putItem(hashKey, rangeKey, attributes, nil) -} - -func (t *Table) ConditionalPutItem(hashKey, rangeKey string, attributes, expected []Attribute) (bool, error) { - return t.putItem(hashKey, rangeKey, attributes, expected) -} - -func (t *Table) putItem(hashKey, rangeKey string, attributes, expected []Attribute) (bool, error) { - if len(attributes) == 0 { - return false, errors.New("At least one attribute is required.") - } - - q := NewQuery(t) - - keys := t.Key.Clone(hashKey, rangeKey) - attributes = append(attributes, keys...) - - q.AddItem(attributes) - if expected != nil { - q.AddExpected(expected) - } - - jsonResponse, err := t.Server.queryServer(target("PutItem"), q) - - if err != nil { - return false, err - } - - _, err = simplejson.NewJson(jsonResponse) - if err != nil { - return false, err - } - - return true, nil -} - -func (t *Table) deleteItem(key *Key, expected []Attribute) (bool, error) { - q := NewQuery(t) - q.AddKey(t, key) - - if expected != nil { - q.AddExpected(expected) - } - - jsonResponse, err := t.Server.queryServer(target("DeleteItem"), q) - - if err != nil { - return false, err - } - - _, err = simplejson.NewJson(jsonResponse) - if err != nil { - return false, err - } - - return true, nil -} - -func (t *Table) DeleteItem(key *Key) (bool, error) { - return t.deleteItem(key, nil) -} - -func (t *Table) ConditionalDeleteItem(key *Key, expected []Attribute) (bool, error) { - return t.deleteItem(key, expected) -} - -func (t *Table) AddAttributes(key *Key, attributes []Attribute) (bool, error) { - return t.modifyAttributes(key, attributes, nil, "ADD") -} - -func (t *Table) UpdateAttributes(key *Key, attributes []Attribute) (bool, error) { - return t.modifyAttributes(key, attributes, nil, "PUT") -} - -func (t *Table) DeleteAttributes(key *Key, attributes []Attribute) (bool, error) { - return t.modifyAttributes(key, attributes, nil, "DELETE") -} - -func (t *Table) ConditionalAddAttributes(key *Key, attributes, expected []Attribute) (bool, error) { - return t.modifyAttributes(key, attributes, expected, "ADD") -} - -func (t *Table) ConditionalUpdateAttributes(key *Key, attributes, expected []Attribute) (bool, error) { - return t.modifyAttributes(key, attributes, expected, "PUT") -} - -func (t *Table) ConditionalDeleteAttributes(key *Key, attributes, expected []Attribute) (bool, error) { - return t.modifyAttributes(key, attributes, expected, "DELETE") -} - -func (t *Table) modifyAttributes(key *Key, attributes, expected []Attribute, action string) (bool, error) { - - if len(attributes) == 0 { - return false, errors.New("At least one attribute is required.") - } - - q := NewQuery(t) - q.AddKey(t, key) - q.AddUpdates(attributes, action) - - if expected != nil { - q.AddExpected(expected) - } - - jsonResponse, err := t.Server.queryServer(target("UpdateItem"), q) - - if err != nil { - return false, err - } - - _, err = simplejson.NewJson(jsonResponse) - if err != nil { - return false, err - } - - return true, nil -} - -func parseAttributes(s map[string]interface{}) map[string]*Attribute { - results := map[string]*Attribute{} - - for key, value := range s { - if v, ok := value.(map[string]interface{}); ok { - if val, ok := v[TYPE_STRING].(string); ok { - results[key] = &Attribute{ - Type: TYPE_STRING, - Name: key, - Value: val, - } - } else if val, ok := v[TYPE_NUMBER].(string); ok { - results[key] = &Attribute{ - Type: TYPE_NUMBER, - Name: key, - Value: val, - } - } else if val, ok := v[TYPE_BINARY].(string); ok { - results[key] = &Attribute{ - Type: TYPE_BINARY, - Name: key, - Value: val, - } - } else if vals, ok := v[TYPE_STRING_SET].([]interface{}); ok { - arry := make([]string, len(vals)) - for i, ivalue := range vals { - if val, ok := ivalue.(string); ok { - arry[i] = val - } - } - results[key] = &Attribute{ - Type: TYPE_STRING_SET, - Name: key, - SetValues: arry, - } - } else if vals, ok := v[TYPE_NUMBER_SET].([]interface{}); ok { - arry := make([]string, len(vals)) - for i, ivalue := range vals { - if val, ok := ivalue.(string); ok { - arry[i] = val - } - } - results[key] = &Attribute{ - Type: TYPE_NUMBER_SET, - Name: key, - SetValues: arry, - } - } else if vals, ok := v[TYPE_BINARY_SET].([]interface{}); ok { - arry := make([]string, len(vals)) - for i, ivalue := range vals { - if val, ok := ivalue.(string); ok { - arry[i] = val - } - } - results[key] = &Attribute{ - Type: TYPE_BINARY_SET, - Name: key, - SetValues: arry, - } - } - } else { - log.Printf("type assertion to map[string] interface{} failed for : %s\n ", value) - } - - } - - return results -} diff --git a/vendor/github.com/goamz/goamz/dynamodb/item_test.go b/vendor/github.com/goamz/goamz/dynamodb/item_test.go deleted file mode 100644 index 37b4b8838..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/item_test.go +++ /dev/null @@ -1,446 +0,0 @@ -package dynamodb_test - -import ( - "github.com/goamz/goamz/dynamodb" - . "gopkg.in/check.v1" -) - -type ItemSuite struct { - TableDescriptionT dynamodb.TableDescriptionT - DynamoDBTest - WithRange bool -} - -func (s *ItemSuite) SetUpSuite(c *C) { - setUpAuth(c) - s.DynamoDBTest.TableDescriptionT = s.TableDescriptionT - s.server = &dynamodb.Server{dynamodb_auth, dynamodb_region} - pk, err := s.TableDescriptionT.BuildPrimaryKey() - if err != nil { - c.Skip(err.Error()) - } - s.table = s.server.NewTable(s.TableDescriptionT.TableName, pk) - - // Cleanup - s.TearDownSuite(c) - _, err = s.server.CreateTable(s.TableDescriptionT) - if err != nil { - c.Fatal(err) - } - s.WaitUntilStatus(c, "ACTIVE") -} - -var item_suite = &ItemSuite{ - TableDescriptionT: dynamodb.TableDescriptionT{ - TableName: "DynamoDBTestMyTable", - AttributeDefinitions: []dynamodb.AttributeDefinitionT{ - dynamodb.AttributeDefinitionT{"TestHashKey", "S"}, - dynamodb.AttributeDefinitionT{"TestRangeKey", "N"}, - }, - KeySchema: []dynamodb.KeySchemaT{ - dynamodb.KeySchemaT{"TestHashKey", "HASH"}, - dynamodb.KeySchemaT{"TestRangeKey", "RANGE"}, - }, - ProvisionedThroughput: dynamodb.ProvisionedThroughputT{ - ReadCapacityUnits: 1, - WriteCapacityUnits: 1, - }, - }, - WithRange: true, -} - -var item_without_range_suite = &ItemSuite{ - TableDescriptionT: dynamodb.TableDescriptionT{ - TableName: "DynamoDBTestMyTable", - AttributeDefinitions: []dynamodb.AttributeDefinitionT{ - dynamodb.AttributeDefinitionT{"TestHashKey", "S"}, - }, - KeySchema: []dynamodb.KeySchemaT{ - dynamodb.KeySchemaT{"TestHashKey", "HASH"}, - }, - ProvisionedThroughput: dynamodb.ProvisionedThroughputT{ - ReadCapacityUnits: 1, - WriteCapacityUnits: 1, - }, - }, - WithRange: false, -} - -var _ = Suite(item_suite) -var _ = Suite(item_without_range_suite) - -func (s *ItemSuite) TestConditionalPutUpdateDeleteItem(c *C) { - if s.WithRange { - // No rangekey test required - return - } - - attrs := []dynamodb.Attribute{ - *dynamodb.NewStringAttribute("Attr1", "Attr1Val"), - } - pk := &dynamodb.Key{HashKey: "NewHashKeyVal"} - - // Put - if ok, err := s.table.PutItem("NewHashKeyVal", "", attrs); !ok { - c.Fatal(err) - } - - { - // Put with condition failed - expected := []dynamodb.Attribute{ - *dynamodb.NewStringAttribute("Attr1", "expectedAttr1Val").SetExists(true), - *dynamodb.NewStringAttribute("AttrNotExists", "").SetExists(false), - } - if ok, err := s.table.ConditionalPutItem("NewHashKeyVal", "", attrs, expected); ok { - c.Errorf("Expect condition does not meet.") - } else { - c.Check(err.Error(), Matches, "ConditionalCheckFailedException.*") - } - - // Add attributes with condition failed - if ok, err := s.table.ConditionalAddAttributes(pk, attrs, expected); ok { - c.Errorf("Expect condition does not meet.") - } else { - c.Check(err.Error(), Matches, "ConditionalCheckFailedException.*") - } - - // Update attributes with condition failed - if ok, err := s.table.ConditionalUpdateAttributes(pk, attrs, expected); ok { - c.Errorf("Expect condition does not meet.") - } else { - c.Check(err.Error(), Matches, "ConditionalCheckFailedException.*") - } - - // Delete attributes with condition failed - if ok, err := s.table.ConditionalDeleteAttributes(pk, attrs, expected); ok { - c.Errorf("Expect condition does not meet.") - } else { - c.Check(err.Error(), Matches, "ConditionalCheckFailedException.*") - } - } - - { - expected := []dynamodb.Attribute{ - *dynamodb.NewStringAttribute("Attr1", "Attr1Val").SetExists(true), - } - - // Add attributes with condition met - addNewAttrs := []dynamodb.Attribute{ - *dynamodb.NewNumericAttribute("AddNewAttr1", "10"), - *dynamodb.NewNumericAttribute("AddNewAttr2", "20"), - } - if ok, err := s.table.ConditionalAddAttributes(pk, addNewAttrs, nil); !ok { - c.Errorf("Expect condition met. %s", err) - } - - // Update attributes with condition met - updateAttrs := []dynamodb.Attribute{ - *dynamodb.NewNumericAttribute("AddNewAttr1", "100"), - } - if ok, err := s.table.ConditionalUpdateAttributes(pk, updateAttrs, expected); !ok { - c.Errorf("Expect condition met. %s", err) - } - - // Delete attributes with condition met - deleteAttrs := []dynamodb.Attribute{ - *dynamodb.NewNumericAttribute("AddNewAttr2", ""), - } - if ok, err := s.table.ConditionalDeleteAttributes(pk, deleteAttrs, expected); !ok { - c.Errorf("Expect condition met. %s", err) - } - - // Get to verify operations that condition are met - item, err := s.table.GetItem(pk) - if err != nil { - c.Fatal(err) - } - - if val, ok := item["AddNewAttr1"]; ok { - c.Check(val, DeepEquals, dynamodb.NewNumericAttribute("AddNewAttr1", "100")) - } else { - c.Error("Expect AddNewAttr1 attribute to be added and updated") - } - - if _, ok := item["AddNewAttr2"]; ok { - c.Error("Expect AddNewAttr2 attribute to be deleted") - } - } - - { - // Put with condition met - expected := []dynamodb.Attribute{ - *dynamodb.NewStringAttribute("Attr1", "Attr1Val").SetExists(true), - } - newattrs := []dynamodb.Attribute{ - *dynamodb.NewStringAttribute("Attr1", "Attr2Val"), - } - if ok, err := s.table.ConditionalPutItem("NewHashKeyVal", "", newattrs, expected); !ok { - c.Errorf("Expect condition met. %s", err) - } - - // Get to verify Put operation that condition are met - item, err := s.table.GetItem(pk) - if err != nil { - c.Fatal(err) - } - - if val, ok := item["Attr1"]; ok { - c.Check(val, DeepEquals, dynamodb.NewStringAttribute("Attr1", "Attr2Val")) - } else { - c.Error("Expect Attr1 attribute to be updated") - } - } - - { - // Delete with condition failed - expected := []dynamodb.Attribute{ - *dynamodb.NewStringAttribute("Attr1", "expectedAttr1Val").SetExists(true), - } - if ok, err := s.table.ConditionalDeleteItem(pk, expected); ok { - c.Errorf("Expect condition does not meet.") - } else { - c.Check(err.Error(), Matches, "ConditionalCheckFailedException.*") - } - } - - { - // Delete with condition met - expected := []dynamodb.Attribute{ - *dynamodb.NewStringAttribute("Attr1", "Attr2Val").SetExists(true), - } - if ok, _ := s.table.ConditionalDeleteItem(pk, expected); !ok { - c.Errorf("Expect condition met.") - } - - // Get to verify Delete operation - _, err := s.table.GetItem(pk) - c.Check(err.Error(), Matches, "Item not found") - } -} - -func (s *ItemSuite) TestPutGetDeleteItem(c *C) { - attrs := []dynamodb.Attribute{ - *dynamodb.NewStringAttribute("Attr1", "Attr1Val"), - } - - var rk string - if s.WithRange { - rk = "1" - } - - // Put - if ok, err := s.table.PutItem("NewHashKeyVal", rk, attrs); !ok { - c.Fatal(err) - } - - // Get to verify Put operation - pk := &dynamodb.Key{HashKey: "NewHashKeyVal", RangeKey: rk} - item, err := s.table.GetItem(pk) - if err != nil { - c.Fatal(err) - } - - if val, ok := item["TestHashKey"]; ok { - c.Check(val, DeepEquals, dynamodb.NewStringAttribute("TestHashKey", "NewHashKeyVal")) - } else { - c.Error("Expect TestHashKey to be found") - } - - if s.WithRange { - if val, ok := item["TestRangeKey"]; ok { - c.Check(val, DeepEquals, dynamodb.NewNumericAttribute("TestRangeKey", "1")) - } else { - c.Error("Expect TestRangeKey to be found") - } - } - - // Delete - if ok, _ := s.table.DeleteItem(pk); !ok { - c.Fatal(err) - } - - // Get to verify Delete operation - _, err = s.table.GetItem(pk) - c.Check(err.Error(), Matches, "Item not found") -} - -func (s *ItemSuite) TestUpdateItem(c *C) { - attrs := []dynamodb.Attribute{ - *dynamodb.NewNumericAttribute("count", "0"), - } - - var rk string - if s.WithRange { - rk = "1" - } - - if ok, err := s.table.PutItem("NewHashKeyVal", rk, attrs); !ok { - c.Fatal(err) - } - - // UpdateItem with Add - attrs = []dynamodb.Attribute{ - *dynamodb.NewNumericAttribute("count", "10"), - } - pk := &dynamodb.Key{HashKey: "NewHashKeyVal", RangeKey: rk} - if ok, err := s.table.AddAttributes(pk, attrs); !ok { - c.Error(err) - } - - // Get to verify Add operation - if item, err := s.table.GetItemConsistent(pk, true); err != nil { - c.Error(err) - } else { - if val, ok := item["count"]; ok { - c.Check(val, DeepEquals, dynamodb.NewNumericAttribute("count", "10")) - } else { - c.Error("Expect count to be found") - } - } - - // UpdateItem with Put - attrs = []dynamodb.Attribute{ - *dynamodb.NewNumericAttribute("count", "100"), - } - if ok, err := s.table.UpdateAttributes(pk, attrs); !ok { - c.Error(err) - } - - // Get to verify Put operation - if item, err := s.table.GetItem(pk); err != nil { - c.Fatal(err) - } else { - if val, ok := item["count"]; ok { - c.Check(val, DeepEquals, dynamodb.NewNumericAttribute("count", "100")) - } else { - c.Error("Expect count to be found") - } - } - - // UpdateItem with Delete - attrs = []dynamodb.Attribute{ - *dynamodb.NewNumericAttribute("count", ""), - } - if ok, err := s.table.DeleteAttributes(pk, attrs); !ok { - c.Error(err) - } - - // Get to verify Delete operation - if item, err := s.table.GetItem(pk); err != nil { - c.Error(err) - } else { - if _, ok := item["count"]; ok { - c.Error("Expect count not to be found") - } - } -} - -func (s *ItemSuite) TestUpdateItemWithSet(c *C) { - attrs := []dynamodb.Attribute{ - *dynamodb.NewStringSetAttribute("list", []string{"A", "B"}), - } - - var rk string - if s.WithRange { - rk = "1" - } - - if ok, err := s.table.PutItem("NewHashKeyVal", rk, attrs); !ok { - c.Error(err) - } - - // UpdateItem with Add - attrs = []dynamodb.Attribute{ - *dynamodb.NewStringSetAttribute("list", []string{"C"}), - } - pk := &dynamodb.Key{HashKey: "NewHashKeyVal", RangeKey: rk} - if ok, err := s.table.AddAttributes(pk, attrs); !ok { - c.Error(err) - } - - // Get to verify Add operation - if item, err := s.table.GetItem(pk); err != nil { - c.Error(err) - } else { - if val, ok := item["list"]; ok { - c.Check(val, DeepEquals, dynamodb.NewStringSetAttribute("list", []string{"A", "B", "C"})) - } else { - c.Error("Expect count to be found") - } - } - - // UpdateItem with Delete - attrs = []dynamodb.Attribute{ - *dynamodb.NewStringSetAttribute("list", []string{"A"}), - } - if ok, err := s.table.DeleteAttributes(pk, attrs); !ok { - c.Error(err) - } - - // Get to verify Delete operation - if item, err := s.table.GetItem(pk); err != nil { - c.Error(err) - } else { - if val, ok := item["list"]; ok { - c.Check(val, DeepEquals, dynamodb.NewStringSetAttribute("list", []string{"B", "C"})) - } else { - c.Error("Expect list to be remained") - } - } -} - -func (s *ItemSuite) TestUpdateItem_new(c *C) { - attrs := []dynamodb.Attribute{ - *dynamodb.NewStringAttribute("intval", "1"), - } - var rk string - if s.WithRange { - rk = "1" - } - pk := &dynamodb.Key{HashKey: "UpdateKeyVal", RangeKey: rk} - - num := func(a, b string) dynamodb.Attribute { - return *dynamodb.NewNumericAttribute(a, b) - } - - checkVal := func(i string) { - if item, err := s.table.GetItem(pk); err != nil { - c.Error(err) - } else { - c.Check(item["intval"], DeepEquals, dynamodb.NewNumericAttribute("intval", i)) - } - } - - if ok, err := s.table.PutItem("UpdateKeyVal", rk, attrs); !ok { - c.Error(err) - } - checkVal("1") - - // Simple Increment - s.table.UpdateItem(pk).UpdateExpression("SET intval = intval + :incr", num(":incr", "5")).Execute() - checkVal("6") - - conditionalUpdate := func(check string) { - s.table.UpdateItem(pk). - ConditionExpression("intval = :check"). - UpdateExpression("SET intval = intval + :incr"). - ExpressionAttributes(num(":check", check), num(":incr", "4")). - Execute() - } - // Conditional increment should be a no-op. - conditionalUpdate("42") - checkVal("6") - - // conditional increment should succeed this time - conditionalUpdate("6") - checkVal("10") - - // Update with new values getting values - result, err := s.table.UpdateItem(pk). - ReturnValues(dynamodb.UPDATED_NEW). - UpdateExpression("SET intval = intval + :incr", num(":incr", "2")). - Execute() - c.Check(err, IsNil) - c.Check(result.Attributes["intval"], DeepEquals, num("intval", "12")) - checkVal("12") -} diff --git a/vendor/github.com/goamz/goamz/dynamodb/marshaller.go b/vendor/github.com/goamz/goamz/dynamodb/marshaller.go deleted file mode 100644 index 2898fbda9..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/marshaller.go +++ /dev/null @@ -1,626 +0,0 @@ -package dynamodb - -import ( - "encoding/base64" - "encoding/json" - "fmt" - "math" - "reflect" - "sort" - "strconv" - "strings" - "sync" - "unicode" -) - -func MarshalAttributes(m interface{}) ([]Attribute, error) { - v := reflect.ValueOf(m).Elem() - - builder := &attributeBuilder{} - builder.buffer = []Attribute{} - for _, f := range cachedTypeFields(v.Type()) { // loop on each field - fv := fieldByIndex(v, f.index) - if !fv.IsValid() || isEmptyValueToOmit(fv) { - continue - } - - err := builder.reflectToDynamoDBAttribute(f.name, fv) - if err != nil { - return builder.buffer, err - } - } - - return builder.buffer, nil -} - -func UnmarshalAttributes(attributesRef *map[string]*Attribute, m interface{}) error { - rv := reflect.ValueOf(m) - if rv.Kind() != reflect.Ptr || rv.IsNil() { - return fmt.Errorf("InvalidUnmarshalError reflect.ValueOf(v): %#v, m interface{}: %#v", rv, reflect.TypeOf(m)) - } - - v := reflect.ValueOf(m).Elem() - - attributes := *attributesRef - for _, f := range cachedTypeFields(v.Type()) { // loop on each field - fv := fieldByIndex(v, f.index) - correlatedAttribute := attributes[f.name] - if correlatedAttribute == nil { - continue - } - err := unmarshallAttribute(correlatedAttribute, fv) - if err != nil { - return err - } - } - - return nil -} - -type attributeBuilder struct { - buffer []Attribute -} - -func (builder *attributeBuilder) Push(attribute *Attribute) { - builder.buffer = append(builder.buffer, *attribute) -} - -func unmarshallAttribute(a *Attribute, v reflect.Value) error { - switch v.Kind() { - case reflect.Bool: - n, err := strconv.ParseInt(a.Value, 10, 64) - if err != nil { - return fmt.Errorf("UnmarshalTypeError (bool) %#v: %#v", a.Value, err) - } - v.SetBool(n != 0) - - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - n, err := strconv.ParseInt(a.Value, 10, 64) - if err != nil || v.OverflowInt(n) { - return fmt.Errorf("UnmarshalTypeError (number) %#v: %#v", a.Value, err) - } - v.SetInt(n) - - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - n, err := strconv.ParseUint(a.Value, 10, 64) - if err != nil || v.OverflowUint(n) { - return fmt.Errorf("UnmarshalTypeError (number) %#v: %#v", a.Value, err) - } - v.SetUint(n) - - case reflect.Float32, reflect.Float64: - n, err := strconv.ParseFloat(a.Value, v.Type().Bits()) - if err != nil || v.OverflowFloat(n) { - return fmt.Errorf("UnmarshalTypeError (number) %#v: %#v", a.Value, err) - } - v.SetFloat(n) - - case reflect.String: - v.SetString(a.Value) - - case reflect.Slice: - if v.Type().Elem().Kind() == reflect.Uint8 { // byte arrays are a special case - b := make([]byte, base64.StdEncoding.DecodedLen(len(a.Value))) - n, err := base64.StdEncoding.Decode(b, []byte(a.Value)) - if err != nil { - return fmt.Errorf("UnmarshalTypeError (byte) %#v: %#v", a.Value, err) - } - v.Set(reflect.ValueOf(b[0:n])) - break - } - - if a.SetType() { // Special NS and SS types should be correctly handled - nativeSetCreated := false - switch v.Type().Elem().Kind() { - case reflect.Bool: - nativeSetCreated = true - arry := reflect.MakeSlice(v.Type(), len(a.SetValues), len(a.SetValues)) - for i, aval := range a.SetValues { - n, err := strconv.ParseInt(aval, 10, 64) - if err != nil { - return fmt.Errorf("UnmarshalSetTypeError (bool) %#v: %#v", aval, err) - } - arry.Index(i).SetBool(n != 0) - } - v.Set(arry) - - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - nativeSetCreated = true - arry := reflect.MakeSlice(v.Type(), len(a.SetValues), len(a.SetValues)) - for i, aval := range a.SetValues { - n, err := strconv.ParseInt(aval, 10, 64) - if err != nil || arry.Index(i).OverflowInt(n) { - return fmt.Errorf("UnmarshalSetTypeError (number) %#v: %#v", aval, err) - } - arry.Index(i).SetInt(n) - } - v.Set(arry) - - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - nativeSetCreated = true - arry := reflect.MakeSlice(v.Type(), len(a.SetValues), len(a.SetValues)) - for i, aval := range a.SetValues { - n, err := strconv.ParseUint(aval, 10, 64) - if err != nil || arry.Index(i).OverflowUint(n) { - return fmt.Errorf("UnmarshalSetTypeError (number) %#v: %#v", aval, err) - } - arry.Index(i).SetUint(n) - } - v.Set(arry) - - case reflect.Float32, reflect.Float64: - nativeSetCreated = true - arry := reflect.MakeSlice(v.Type(), len(a.SetValues), len(a.SetValues)) - for i, aval := range a.SetValues { - n, err := strconv.ParseFloat(aval, arry.Index(i).Type().Bits()) - if err != nil || arry.Index(i).OverflowFloat(n) { - return fmt.Errorf("UnmarshalSetTypeError (number) %#v: %#v", aval, err) - } - arry.Index(i).SetFloat(n) - } - v.Set(arry) - - case reflect.String: - nativeSetCreated = true - arry := reflect.MakeSlice(v.Type(), len(a.SetValues), len(a.SetValues)) - for i, aval := range a.SetValues { - arry.Index(i).SetString(aval) - } - v.Set(arry) - } - - if nativeSetCreated { - break - } - } - - // Slices can be marshalled as nil, but otherwise are handled - // as arrays. - fallthrough - case reflect.Array, reflect.Struct, reflect.Map, reflect.Interface, reflect.Ptr: - unmarshalled := reflect.New(v.Type()) - err := json.Unmarshal([]byte(a.Value), unmarshalled.Interface()) - if err != nil { - return err - } - v.Set(unmarshalled.Elem()) - - default: - return fmt.Errorf("UnsupportedTypeError %#v", v.Type()) - } - - return nil -} - -// reflectValueQuoted writes the value in v to the output. -// If quoted is true, the serialization is wrapped in a JSON string. -func (e *attributeBuilder) reflectToDynamoDBAttribute(name string, v reflect.Value) error { - if !v.IsValid() { - return nil - } // don't build - - switch v.Kind() { - case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64: - rv, err := numericReflectedValueString(v) - if err != nil { - return err - } - e.Push(NewNumericAttribute(name, rv)) - - case reflect.String: - e.Push(NewStringAttribute(name, v.String())) - - case reflect.Slice: - if v.IsNil() { - break - } - if v.Type().Elem().Kind() == reflect.Uint8 { - // Byte slices are treated as errors - s := v.Bytes() - dst := make([]byte, base64.StdEncoding.EncodedLen(len(s))) - base64.StdEncoding.Encode(dst, s) - e.Push(NewStringAttribute(name, string(dst))) - break - } - - // Special NS and SS types should be correctly handled - nativeSetCreated := false - switch v.Type().Elem().Kind() { - case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64: - nativeSetCreated = true - arrystrings := make([]string, v.Len()) - for i, _ := range arrystrings { - var err error - arrystrings[i], err = numericReflectedValueString(v.Index(i)) - if err != nil { - return err - } - } - e.Push(NewNumericSetAttribute(name, arrystrings)) - case reflect.String: // simple copy will suffice - nativeSetCreated = true - arrystrings := make([]string, v.Len()) - for i, _ := range arrystrings { - arrystrings[i] = v.Index(i).String() - } - e.Push(NewStringSetAttribute(name, arrystrings)) - } - - if nativeSetCreated { - break - } - - // Slices can be marshalled as nil, but otherwise are handled - // as arrays. - fallthrough - case reflect.Array, reflect.Struct, reflect.Map, reflect.Interface, reflect.Ptr: - jsonVersion, err := json.Marshal(v.Interface()) - if err != nil { - return err - } - escapedJson := `"` + string(jsonVersion) + `"` // strconv.Quote not required because the entire string is escaped from json Marshall - e.Push(NewStringAttribute(name, escapedJson[1:len(escapedJson)-1])) - - default: - return fmt.Errorf("UnsupportedTypeError %#v", v.Type()) - } - return nil -} - -func numericReflectedValueString(v reflect.Value) (string, error) { - switch v.Kind() { - case reflect.Bool: - x := v.Bool() - if x { - return "1", nil - } else { - return "0", nil - } - - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return strconv.FormatInt(v.Int(), 10), nil - - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return strconv.FormatUint(v.Uint(), 10), nil - - case reflect.Float32, reflect.Float64: - f := v.Float() - if math.IsInf(f, 0) || math.IsNaN(f) { - return "", fmt.Errorf("UnsupportedValueError %#v (formatted float: %s)", v, strconv.FormatFloat(f, 'g', -1, v.Type().Bits())) - } - return strconv.FormatFloat(f, 'g', -1, v.Type().Bits()), nil - } - 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() { - case reflect.Array, reflect.Map, reflect.Slice, reflect.String: - return v.Len() == 0 - case reflect.Bool: - return !v.Bool() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - case reflect.Interface, reflect.Ptr: - return v.IsNil() - } - return false -} - -func fieldByIndex(v reflect.Value, index []int) reflect.Value { - for _, i := range index { - if v.Kind() == reflect.Ptr { - if v.IsNil() { - return reflect.Value{} - } - v = v.Elem() - } - v = v.Field(i) - } - return v -} - -// A field represents a single field found in a struct. -type field struct { - name string - tag bool - index []int - typ reflect.Type - omitEmpty bool - quoted bool -} - -// byName sorts field by name, breaking ties with depth, -// then breaking ties with "name came from json tag", then -// breaking ties with index sequence. -type byName []field - -func (x byName) Len() int { return len(x) } - -func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } - -func (x byName) Less(i, j int) bool { - if x[i].name != x[j].name { - return x[i].name < x[j].name - } - if len(x[i].index) != len(x[j].index) { - return len(x[i].index) < len(x[j].index) - } - if x[i].tag != x[j].tag { - return x[i].tag - } - return byIndex(x).Less(i, j) -} - -// byIndex sorts field by index sequence. -type byIndex []field - -func (x byIndex) Len() int { return len(x) } - -func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } - -func (x byIndex) Less(i, j int) bool { - for k, xik := range x[i].index { - if k >= len(x[j].index) { - return false - } - if xik != x[j].index[k] { - return xik < x[j].index[k] - } - } - return len(x[i].index) < len(x[j].index) -} - -func isValidTag(s string) bool { - if s == "" { - return false - } - for _, c := range s { - switch { - case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): - // Backslash and quote chars are reserved, but - // otherwise any punctuation chars are allowed - // in a tag name. - default: - if !unicode.IsLetter(c) && !unicode.IsDigit(c) { - return false - } - } - } - return true -} - -// tagOptions is the string following a comma in a struct field's "json" -// tag, or the empty string. It does not include the leading comma. -type tagOptions string - -// Contains returns whether checks that a comma-separated list of options -// contains a particular substr flag. substr must be surrounded by a -// string boundary or commas. -func (o tagOptions) Contains(optionName string) bool { - if len(o) == 0 { - return false - } - s := string(o) - for s != "" { - var next string - i := strings.Index(s, ",") - if i >= 0 { - s, next = s[:i], s[i+1:] - } - if s == optionName { - return true - } - s = next - } - return false -} - -// parseTag splits a struct field's json tag into its name and -// comma-separated options. -func parseTag(tag string) (string, tagOptions) { - if idx := strings.Index(tag, ","); idx != -1 { - return tag[:idx], tagOptions(tag[idx+1:]) - } - return tag, tagOptions("") -} - -// typeFields returns a list of fields that JSON should recognize for the given type. -// The algorithm is breadth-first search over the set of structs to include - the top struct -// and then any reachable anonymous structs. -func typeFields(t reflect.Type) []field { - // Anonymous fields to explore at the current level and the next. - current := []field{} - next := []field{{typ: t}} - - // Count of queued names for current level and the next. - count := map[reflect.Type]int{} - nextCount := map[reflect.Type]int{} - - // Types already visited at an earlier level. - visited := map[reflect.Type]bool{} - - // Fields found. - var fields []field - - for len(next) > 0 { - current, next = next, current[:0] - count, nextCount = nextCount, map[reflect.Type]int{} - - for _, f := range current { - if visited[f.typ] { - continue - } - visited[f.typ] = true - - // Scan f.typ for fields to include. - for i := 0; i < f.typ.NumField(); i++ { - sf := f.typ.Field(i) - if sf.PkgPath != "" { // unexported - continue - } - tag := sf.Tag.Get("json") - if tag == "-" { - continue - } - name, opts := parseTag(tag) - if !isValidTag(name) { - name = "" - } - index := make([]int, len(f.index)+1) - copy(index, f.index) - index[len(f.index)] = i - - ft := sf.Type - if ft.Name() == "" && ft.Kind() == reflect.Ptr { - // Follow pointer. - ft = ft.Elem() - } - - // Record found field and index sequence. - if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { - tagged := name != "" - if name == "" { - name = sf.Name - } - fields = append(fields, field{name, tagged, index, ft, - opts.Contains("omitempty"), opts.Contains("string")}) - if count[f.typ] > 1 { - // If there were multiple instances, add a second, - // so that the annihilation code will see a duplicate. - // It only cares about the distinction between 1 or 2, - // so don't bother generating any more copies. - fields = append(fields, fields[len(fields)-1]) - } - continue - } - - // Record new anonymous struct to explore in next round. - nextCount[ft]++ - if nextCount[ft] == 1 { - next = append(next, field{name: ft.Name(), index: index, typ: ft}) - } - } - } - } - - sort.Sort(byName(fields)) - - // Delete all fields that are hidden by the Go rules for embedded fields, - // except that fields with JSON tags are promoted. - - // The fields are sorted in primary order of name, secondary order - // of field index length. Loop over names; for each name, delete - // hidden fields by choosing the one dominant field that survives. - out := fields[:0] - for advance, i := 0, 0; i < len(fields); i += advance { - // One iteration per name. - // Find the sequence of fields with the name of this first field. - fi := fields[i] - name := fi.name - for advance = 1; i+advance < len(fields); advance++ { - fj := fields[i+advance] - if fj.name != name { - break - } - } - if advance == 1 { // Only one field with this name - out = append(out, fi) - continue - } - dominant, ok := dominantField(fields[i : i+advance]) - if ok { - out = append(out, dominant) - } - } - - fields = out - sort.Sort(byIndex(fields)) - - return fields -} - -// dominantField looks through the fields, all of which are known to -// have the same name, to find the single field that dominates the -// others using Go's embedding rules, modified by the presence of -// JSON tags. If there are multiple top-level fields, the boolean -// will be false: This condition is an error in Go and we skip all -// the fields. -func dominantField(fields []field) (field, bool) { - // The fields are sorted in increasing index-length order. The winner - // must therefore be one with the shortest index length. Drop all - // longer entries, which is easy: just truncate the slice. - length := len(fields[0].index) - tagged := -1 // Index of first tagged field. - for i, f := range fields { - if len(f.index) > length { - fields = fields[:i] - break - } - if f.tag { - if tagged >= 0 { - // Multiple tagged fields at the same level: conflict. - // Return no field. - return field{}, false - } - tagged = i - } - } - if tagged >= 0 { - return fields[tagged], true - } - // All remaining fields have the same length. If there's more than one, - // we have a conflict (two fields named "X" at the same level) and we - // return no field. - if len(fields) > 1 { - return field{}, false - } - return fields[0], true -} - -var fieldCache struct { - sync.RWMutex - m map[reflect.Type][]field -} - -// cachedTypeFields is like typeFields but uses a cache to avoid repeated work. -func cachedTypeFields(t reflect.Type) []field { - fieldCache.RLock() - f := fieldCache.m[t] - fieldCache.RUnlock() - if f != nil { - return f - } - - // Compute fields without lock. - // Might duplicate effort but won't hold other computations back. - f = typeFields(t) - if f == nil { - f = []field{} - } - - fieldCache.Lock() - if fieldCache.m == nil { - fieldCache.m = map[reflect.Type][]field{} - } - fieldCache.m[t] = f - fieldCache.Unlock() - return f -} diff --git a/vendor/github.com/goamz/goamz/dynamodb/marshaller_test.go b/vendor/github.com/goamz/goamz/dynamodb/marshaller_test.go deleted file mode 100644 index 8b9d2fc08..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/marshaller_test.go +++ /dev/null @@ -1,283 +0,0 @@ -package dynamodb_test - -import ( - "time" - - "github.com/goamz/goamz/dynamodb" - . "gopkg.in/check.v1" -) - -type TestSubStruct struct { - SubBool bool - SubInt int - SubString string - SubStringArray []string -} - -type TestStruct struct { - TestBool bool - TestInt int - TestInt32 int32 - TestInt64 int64 - TestUint uint - TestFloat32 float32 - TestFloat64 float64 - TestString string - TestByteArray []byte - TestStringArray []string - TestIntArray []int - TestInt8Array []int8 - TestFloatArray []float64 - TestSub TestSubStruct -} - -type TestStructTime struct { - TestTime time.Time -} - -func testObject() *TestStruct { - return &TestStruct{ - TestBool: true, - TestInt: -99, - TestInt32: 999, - TestInt64: 9999, - TestUint: 99, - TestFloat32: 9.9999, - TestFloat64: 99.999999, - TestString: "test", - TestByteArray: []byte("bytes"), - TestStringArray: []string{"test1", "test2", "test3", "test4"}, - TestIntArray: []int{0, 1, 12, 123, 1234, 12345}, - TestInt8Array: []int8{0, 1, 12, 123}, - TestFloatArray: []float64{0.1, 1.1, 1.2, 1.23, 1.234, 1.2345}, - TestSub: TestSubStruct{ - SubBool: true, - SubInt: 2, - SubString: "subtest", - SubStringArray: []string{"sub1", "sub2", "sub3"}, - }, - } -} - -func testObjectTime() *TestStructTime { - t, _ := time.Parse("Jan 2, 2006 at 3:04pm", "Mar 3, 2003 at 5:03pm") - return &TestStructTime{ - TestTime: t, - } -} - -func testObjectWithZeroValues() *TestStruct { - return &TestStruct{} -} - -func testObjectWithNilSets() *TestStruct { - return &TestStruct{ - TestBool: true, - TestInt: -99, - TestInt32: 999, - TestInt64: 9999, - TestUint: 99, - TestFloat32: 9.9999, - TestFloat64: 99.999999, - TestString: "test", - TestByteArray: []byte("bytes"), - TestStringArray: []string(nil), - TestIntArray: []int(nil), - TestFloatArray: []float64(nil), - TestSub: TestSubStruct{ - SubBool: true, - SubInt: 2, - SubString: "subtest", - SubStringArray: []string{"sub1", "sub2", "sub3"}, - }, - } -} -func testObjectWithEmptySets() *TestStruct { - return &TestStruct{ - TestBool: true, - TestInt: -99, - TestInt32: 999, - TestInt64: 9999, - TestUint: 99, - TestFloat32: 9.9999, - TestFloat64: 99.999999, - TestString: "test", - TestByteArray: []byte("bytes"), - TestStringArray: []string{}, - TestIntArray: []int{}, - TestFloatArray: []float64{}, - TestSub: TestSubStruct{ - SubBool: true, - SubInt: 2, - SubString: "subtest", - SubStringArray: []string{"sub1", "sub2", "sub3"}, - }, - } -} - -func testAttrs() []dynamodb.Attribute { - return []dynamodb.Attribute{ - dynamodb.Attribute{Type: "N", Name: "TestBool", Value: "1", SetValues: []string(nil)}, - dynamodb.Attribute{Type: "N", Name: "TestInt", Value: "-99", SetValues: []string(nil)}, - dynamodb.Attribute{Type: "N", Name: "TestInt32", Value: "999", SetValues: []string(nil)}, - dynamodb.Attribute{Type: "N", Name: "TestInt64", Value: "9999", SetValues: []string(nil)}, - dynamodb.Attribute{Type: "N", Name: "TestUint", Value: "99", SetValues: []string(nil)}, - dynamodb.Attribute{Type: "N", Name: "TestFloat32", Value: "9.9999", SetValues: []string(nil)}, - dynamodb.Attribute{Type: "N", Name: "TestFloat64", Value: "99.999999", SetValues: []string(nil)}, - dynamodb.Attribute{Type: "S", Name: "TestString", Value: "test", SetValues: []string(nil)}, - dynamodb.Attribute{Type: "S", Name: "TestByteArray", Value: "Ynl0ZXM=", SetValues: []string(nil)}, - dynamodb.Attribute{Type: "SS", Name: "TestStringArray", Value: "", SetValues: []string{"test1", "test2", "test3", "test4"}}, - dynamodb.Attribute{Type: "NS", Name: "TestIntArray", Value: "", SetValues: []string{"0", "1", "12", "123", "1234", "12345"}}, - dynamodb.Attribute{Type: "NS", Name: "TestInt8Array", Value: "", SetValues: []string{"0", "1", "12", "123"}}, - dynamodb.Attribute{Type: "NS", Name: "TestFloatArray", Value: "", SetValues: []string{"0.1", "1.1", "1.2", "1.23", "1.234", "1.2345"}}, - dynamodb.Attribute{Type: "S", Name: "TestSub", Value: `{"SubBool":true,"SubInt":2,"SubString":"subtest","SubStringArray":["sub1","sub2","sub3"]}`, SetValues: []string(nil)}, - } -} - -func testAttrsTime() []dynamodb.Attribute { - return []dynamodb.Attribute{ - dynamodb.Attribute{Type: "S", Name: "TestTime", Value: "\"2003-03-03T17:03:00Z\"", SetValues: []string(nil)}, - } -} - -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)}, - dynamodb.Attribute{Type: "N", Name: "TestInt", Value: "-99", SetValues: []string(nil)}, - dynamodb.Attribute{Type: "N", Name: "TestInt32", Value: "999", SetValues: []string(nil)}, - dynamodb.Attribute{Type: "N", Name: "TestInt64", Value: "9999", SetValues: []string(nil)}, - dynamodb.Attribute{Type: "N", Name: "TestUint", Value: "99", SetValues: []string(nil)}, - dynamodb.Attribute{Type: "N", Name: "TestFloat32", Value: "9.9999", SetValues: []string(nil)}, - dynamodb.Attribute{Type: "N", Name: "TestFloat64", Value: "99.999999", SetValues: []string(nil)}, - dynamodb.Attribute{Type: "S", Name: "TestString", Value: "test", SetValues: []string(nil)}, - dynamodb.Attribute{Type: "S", Name: "TestByteArray", Value: "Ynl0ZXM=", SetValues: []string(nil)}, - dynamodb.Attribute{Type: "S", Name: "TestSub", Value: `{"SubBool":true,"SubInt":2,"SubString":"subtest","SubStringArray":["sub1","sub2","sub3"]}`, SetValues: []string(nil)}, - } -} - -type MarshallerSuite struct { -} - -var _ = Suite(&MarshallerSuite{}) - -func (s *MarshallerSuite) TestMarshal(c *C) { - testObj := testObject() - attrs, err := dynamodb.MarshalAttributes(testObj) - if err != nil { - c.Errorf("Error from dynamodb.MarshalAttributes: %#v", err) - } - - expected := testAttrs() - c.Check(attrs, DeepEquals, expected) -} - -func (s *MarshallerSuite) TestUnmarshal(c *C) { - testObj := &TestStruct{} - - attrMap := map[string]*dynamodb.Attribute{} - attrs := testAttrs() - for i, _ := range attrs { - attrMap[attrs[i].Name] = &attrs[i] - } - - err := dynamodb.UnmarshalAttributes(&attrMap, testObj) - if err != nil { - c.Fatalf("Error from dynamodb.UnmarshalAttributes: %#v (Built: %#v)", err, testObj) - } - - expected := testObject() - c.Check(testObj, DeepEquals, expected) -} - -func (s *MarshallerSuite) TestMarshalTime(c *C) { - testObj := testObjectTime() - attrs, err := dynamodb.MarshalAttributes(testObj) - if err != nil { - c.Errorf("Error from dynamodb.MarshalAttributes: %#v", err) - } - - expected := testAttrsTime() - c.Check(attrs, DeepEquals, expected) -} - -func (s *MarshallerSuite) TestUnmarshalTime(c *C) { - testObj := &TestStructTime{} - - attrMap := map[string]*dynamodb.Attribute{} - attrs := testAttrsTime() - for i, _ := range attrs { - attrMap[attrs[i].Name] = &attrs[i] - } - - err := dynamodb.UnmarshalAttributes(&attrMap, testObj) - if err != nil { - c.Fatalf("Error from dynamodb.UnmarshalAttributes: %#v (Built: %#v)", err, testObj) - } - - expected := testObjectTime() - c.Check(testObj, DeepEquals, expected) -} - -func (s *MarshallerSuite) TestMarshalNilSets(c *C) { - testObj := testObjectWithNilSets() - attrs, err := dynamodb.MarshalAttributes(testObj) - if err != nil { - c.Errorf("Error from dynamodb.MarshalAttributes: %#v", err) - } - - expected := testAttrsWithNilSets() - c.Check(attrs, DeepEquals, expected) -} - -func (s *MarshallerSuite) TestMarshalZeroValues(c *C) { - testObj := testObjectWithZeroValues() - attrs, err := dynamodb.MarshalAttributes(testObj) - if err != nil { - c.Errorf("Error from dynamodb.MarshalAttributes: %#v", err) - } - - expected := testAttrsWithZeroValues() - c.Check(attrs, DeepEquals, expected) -} - -func (s *MarshallerSuite) TestMarshalEmptySets(c *C) { - testObj := testObjectWithEmptySets() - attrs, err := dynamodb.MarshalAttributes(testObj) - if err != nil { - c.Errorf("Error from dynamodb.MarshalAttributes: %#v", err) - } - - expected := testAttrsWithNilSets() - c.Check(attrs, DeepEquals, expected) -} - -func (s *MarshallerSuite) TestUnmarshalEmptySets(c *C) { - testObj := &TestStruct{} - - attrMap := map[string]*dynamodb.Attribute{} - attrs := testAttrsWithNilSets() - for i, _ := range attrs { - attrMap[attrs[i].Name] = &attrs[i] - } - - err := dynamodb.UnmarshalAttributes(&attrMap, testObj) - if err != nil { - c.Fatalf("Error from dynamodb.UnmarshalAttributes: %#v (Built: %#v)", err, testObj) - } - - expected := testObjectWithNilSets() - c.Check(testObj, DeepEquals, expected) -} diff --git a/vendor/github.com/goamz/goamz/dynamodb/query.go b/vendor/github.com/goamz/goamz/dynamodb/query.go deleted file mode 100644 index 453e38733..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/query.go +++ /dev/null @@ -1,111 +0,0 @@ -package dynamodb - -import ( - "errors" - "fmt" - simplejson "github.com/bitly/go-simplejson" -) - -func (t *Table) Query(attributeComparisons []AttributeComparison) ([]map[string]*Attribute, error) { - q := NewQuery(t) - q.AddKeyConditions(attributeComparisons) - return runQuery(q, t) -} - -func (t *Table) QueryOnIndex(attributeComparisons []AttributeComparison, indexName string) ([]map[string]*Attribute, error) { - q := NewQuery(t) - q.AddKeyConditions(attributeComparisons) - q.AddIndex(indexName) - return runQuery(q, t) -} - -func (t *Table) QueryOnIndexDescending(attributeComparisons []AttributeComparison, indexName string) ([]map[string]*Attribute, error) { - q := NewQuery(t) - q.AddKeyConditions(attributeComparisons) - q.AddIndex(indexName) - q.ScanIndexDescending() - return runQuery(q, t) -} - -func (t *Table) LimitedQuery(attributeComparisons []AttributeComparison, limit int64) ([]map[string]*Attribute, error) { - q := NewQuery(t) - q.AddKeyConditions(attributeComparisons) - q.AddLimit(limit) - return runQuery(q, t) -} - -func (t *Table) LimitedQueryOnIndex(attributeComparisons []AttributeComparison, indexName string, limit int64) ([]map[string]*Attribute, error) { - q := NewQuery(t) - q.AddKeyConditions(attributeComparisons) - q.AddIndex(indexName) - q.AddLimit(limit) - return runQuery(q, t) -} - -func (t *Table) LimitedQueryDescending(attributeComparisons []AttributeComparison, limit int64) ([]map[string]*Attribute, error) { - q := NewQuery(t) - q.AddKeyConditions(attributeComparisons) - q.AddLimit(limit) - q.ScanIndexDescending() - return runQuery(q, t) -} - -func (t *Table) LimitedQueryOnIndexDescending(attributeComparisons []AttributeComparison, indexName string, limit int64) ([]map[string]*Attribute, error) { - q := NewQuery(t) - q.AddKeyConditions(attributeComparisons) - q.AddIndex(indexName) - q.AddLimit(limit) - q.ScanIndexDescending() - return runQuery(q, t) -} - -func (t *Table) CountQuery(attributeComparisons []AttributeComparison) (int64, error) { - q := NewQuery(t) - q.AddKeyConditions(attributeComparisons) - q.AddSelect("COUNT") - jsonResponse, err := t.Server.queryServer("DynamoDB_20120810.Query", q) - if err != nil { - return 0, err - } - json, err := simplejson.NewJson(jsonResponse) - if err != nil { - return 0, err - } - - itemCount, err := json.Get("Count").Int64() - if err != nil { - return 0, err - } - - return itemCount, nil -} - -func runQuery(q *Query, t *Table) ([]map[string]*Attribute, error) { - jsonResponse, err := t.Server.queryServer("DynamoDB_20120810.Query", q) - if err != nil { - return nil, err - } - - json, err := simplejson.NewJson(jsonResponse) - if err != nil { - return nil, err - } - - itemCount, err := json.Get("Count").Int() - if err != nil { - message := fmt.Sprintf("Unexpected response %s", jsonResponse) - return nil, errors.New(message) - } - - results := make([]map[string]*Attribute, itemCount) - - for i, _ := range results { - item, err := json.Get("Items").GetIndex(i).Map() - if err != nil { - message := fmt.Sprintf("Unexpected response %s", jsonResponse) - return nil, errors.New(message) - } - results[i] = parseAttributes(item) - } - return results, nil -} diff --git a/vendor/github.com/goamz/goamz/dynamodb/query_builder.go b/vendor/github.com/goamz/goamz/dynamodb/query_builder.go deleted file mode 100644 index 47a90bb1c..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/query_builder.go +++ /dev/null @@ -1,362 +0,0 @@ -package dynamodb - -import ( - "encoding/json" - "sort" -) - -type msi map[string]interface{} -type Query struct { - buffer msi -} - -func NewEmptyQuery() *Query { - return &Query{msi{}} -} - -func NewQuery(t *Table) *Query { - q := &Query{msi{}} - q.addTable(t) - return q -} - -// This way of specifing the key is used when doing a Get. -// If rangeKey is "", it is assumed to not want to be used -func (q *Query) AddKey(t *Table, key *Key) { - k := t.Key - keymap := msi{ - k.KeyAttribute.Name: msi{ - k.KeyAttribute.Type: key.HashKey}, - } - if k.HasRange() { - keymap[k.RangeAttribute.Name] = msi{k.RangeAttribute.Type: key.RangeKey} - } - - q.buffer["Key"] = keymap -} - -func keyAttributes(t *Table, key *Key) msi { - k := t.Key - - out := msi{} - out[k.KeyAttribute.Name] = msi{k.KeyAttribute.Type: key.HashKey} - if k.HasRange() { - out[k.RangeAttribute.Name] = msi{k.RangeAttribute.Type: key.RangeKey} - } - return out -} - -func (q *Query) AddAttributesToGet(attributes []string) { - if len(attributes) == 0 { - return - } - - q.buffer["AttributesToGet"] = attributes -} - -func (q *Query) ConsistentRead(c bool) { - if c == true { - q.buffer["ConsistentRead"] = "true" //String "true", not bool true - } -} - -func (q *Query) AddGetRequestItems(tableKeys map[*Table][]Key) { - requestitems := msi{} - for table, keys := range tableKeys { - keyslist := []msi{} - for _, key := range keys { - keyslist = append(keyslist, keyAttributes(table, &key)) - } - requestitems[table.Name] = msi{"Keys": keyslist} - } - q.buffer["RequestItems"] = requestitems -} - -func (q *Query) AddWriteRequestItems(tableItems map[*Table]map[string][][]Attribute) { - b := q.buffer - - b["RequestItems"] = func() msi { - out := msi{} - for table, itemActions := range tableItems { - out[table.Name] = func() interface{} { - out2 := []interface{}{} - - // here breaks an order of array.... - // For now, we iterate over sorted key by action for stable testing - keys := []string{} - for k := range itemActions { - keys = append(keys, k) - } - sort.Strings(keys) - - for ki := range keys { - action := keys[ki] - items := itemActions[action] - for _, attributes := range items { - Item_or_Key := map[bool]string{true: "Item", false: "Key"}[action == "Put"] - out2 = append(out2, msi{action + "Request": msi{Item_or_Key: attributeList(attributes)}}) - } - } - return out2 - }() - } - return out - }() -} - -func (q *Query) AddCreateRequestTable(description TableDescriptionT) { - b := q.buffer - - attDefs := []interface{}{} - for _, attr := range description.AttributeDefinitions { - attDefs = append(attDefs, msi{ - "AttributeName": attr.Name, - "AttributeType": attr.Type, - }) - } - b["AttributeDefinitions"] = attDefs - b["KeySchema"] = description.KeySchema - b["TableName"] = description.TableName - b["ProvisionedThroughput"] = msi{ - "ReadCapacityUnits": int(description.ProvisionedThroughput.ReadCapacityUnits), - "WriteCapacityUnits": int(description.ProvisionedThroughput.WriteCapacityUnits), - } - - if description.StreamSpecification.StreamEnabled { - b["StreamSpecification"] = msi{ - "StreamEnabled": "true", - "StreamViewType": description.StreamSpecification.StreamViewType, - } - } - - localSecondaryIndexes := []interface{}{} - - for _, ind := range description.LocalSecondaryIndexes { - localSecondaryIndexes = append(localSecondaryIndexes, msi{ - "IndexName": ind.IndexName, - "KeySchema": ind.KeySchema, - "Projection": ind.Projection, - }) - } - - globalSecondaryIndexes := []interface{}{} - intmax := func(x, y int64) int64 { - if x > y { - return x - } - return y - } - for _, ind := range description.GlobalSecondaryIndexes { - rec := msi{ - "IndexName": ind.IndexName, - "KeySchema": ind.KeySchema, - "Projection": ind.Projection, - } - // need at least one unit, and since go's max() is float based. - rec["ProvisionedThroughput"] = msi{ - "ReadCapacityUnits": intmax(1, ind.ProvisionedThroughput.ReadCapacityUnits), - "WriteCapacityUnits": intmax(1, ind.ProvisionedThroughput.WriteCapacityUnits), - } - globalSecondaryIndexes = append(globalSecondaryIndexes, rec) - } - - if len(localSecondaryIndexes) > 0 { - b["LocalSecondaryIndexes"] = localSecondaryIndexes - } - - if len(globalSecondaryIndexes) > 0 { - b["GlobalSecondaryIndexes"] = globalSecondaryIndexes - } -} - -func (q *Query) AddDeleteRequestTable(description TableDescriptionT) { - b := q.buffer - b["TableName"] = description.TableName -} - -func (q *Query) AddUpdateRequestTable(description TableDescriptionT) { - b := q.buffer - - attDefs := []interface{}{} - for _, attr := range description.AttributeDefinitions { - attDefs = append(attDefs, msi{ - "AttributeName": attr.Name, - "AttributeType": attr.Type, - }) - } - if len(attDefs) > 0 { - b["AttributeDefinitions"] = attDefs - } - b["TableName"] = description.TableName - b["ProvisionedThroughput"] = msi{ - "ReadCapacityUnits": int(description.ProvisionedThroughput.ReadCapacityUnits), - "WriteCapacityUnits": int(description.ProvisionedThroughput.WriteCapacityUnits), - } - -} - -func (q *Query) AddKeyConditions(comparisons []AttributeComparison) { - q.buffer["KeyConditions"] = buildComparisons(comparisons) -} - -func (q *Query) AddLimit(limit int64) { - q.buffer["Limit"] = limit -} -func (q *Query) AddSelect(value string) { - q.buffer["Select"] = value -} - -func (q *Query) AddIndex(value string) { - q.buffer["IndexName"] = value -} - -func (q *Query) ScanIndexDescending() { - q.buffer["ScanIndexForward"] = "false" -} - -/* - "ScanFilter":{ - "AttributeName1":{"AttributeValueList":[{"S":"AttributeValue"}],"ComparisonOperator":"EQ"} - }, -*/ -func (q *Query) AddScanFilter(comparisons []AttributeComparison) { - q.buffer["ScanFilter"] = buildComparisons(comparisons) -} - -func (q *Query) AddParallelScanConfiguration(segment int, totalSegments int) { - q.buffer["Segment"] = segment - q.buffer["TotalSegments"] = totalSegments -} - -func buildComparisons(comparisons []AttributeComparison) msi { - out := msi{} - - for _, c := range comparisons { - avlist := []interface{}{} - for _, attributeValue := range c.AttributeValueList { - avlist = append(avlist, msi{attributeValue.Type: attributeValue.Value}) - } - out[c.AttributeName] = msi{ - "AttributeValueList": avlist, - "ComparisonOperator": c.ComparisonOperator, - } - } - - return out -} - -// The primary key must be included in attributes. -func (q *Query) AddItem(attributes []Attribute) { - q.buffer["Item"] = attributeList(attributes) -} - -func (q *Query) AddUpdates(attributes []Attribute, action string) { - updates := msi{} - for _, a := range attributes { - au := msi{ - "Value": msi{ - a.Type: map[bool]interface{}{true: a.SetValues, false: a.Value}[a.SetType()], - }, - "Action": action, - } - // Delete 'Value' from AttributeUpdates if Type is not Set - if action == "DELETE" && !a.SetType() { - delete(au, "Value") - } - updates[a.Name] = au - } - - q.buffer["AttributeUpdates"] = updates -} - -func (q *Query) AddExpected(attributes []Attribute) { - expected := msi{} - for _, a := range attributes { - value := msi{} - if a.Exists != "" { - value["Exists"] = a.Exists - } - // If set Exists to false, we must remove Value - if value["Exists"] != "false" { - value["Value"] = msi{a.Type: map[bool]interface{}{true: a.SetValues, false: a.Value}[a.SetType()]} - } - expected[a.Name] = value - } - q.buffer["Expected"] = expected -} - -// Add the ReturnValues parameter, used in UpdateItem queries. -func (q *Query) AddReturnValues(returnValues ReturnValues) { - q.buffer["ReturnValues"] = string(returnValues) -} - -// Add the UpdateExpression parameter, used in UpdateItem queries. -func (q *Query) AddUpdateExpression(expression string) { - q.buffer["UpdateExpression"] = expression -} - -// Add the ConditionExpression parameter, used in UpdateItem queries. -func (q *Query) AddConditionExpression(expression string) { - q.buffer["ConditionExpression"] = expression -} - -func (q *Query) AddExpressionAttributes(attributes []Attribute) { - existing, ok := q.buffer["ExpressionAttributes"].(msi) - if !ok { - existing = msi{} - q.buffer["ExpressionAttributes"] = existing - } - for key, val := range attributeList(attributes) { - existing[key] = val - } -} - -func (q *Query) AddExclusiveStartStreamArn(arn string) { - q.buffer["ExclusiveStartStreamArn"] = arn -} - -func (q *Query) AddStreamArn(arn string) { - q.buffer["StreamArn"] = arn -} - -func (q *Query) AddExclusiveStartShardId(shardId string) { - q.buffer["ExclusiveStartShardId"] = shardId -} - -func (q *Query) AddShardId(shardId string) { - q.buffer["ShardId"] = shardId -} - -func (q *Query) AddShardIteratorType(shardIteratorType string) { - q.buffer["ShardIteratorType"] = shardIteratorType -} - -func (q *Query) AddSequenceNumber(sequenceNumber string) { - q.buffer["SequenceNumber"] = sequenceNumber -} - -func (q *Query) AddShardIterator(shardIterator string) { - q.buffer["ShardIterator"] = shardIterator -} - -func attributeList(attributes []Attribute) msi { - b := msi{} - for _, a := range attributes { - //UGH!! (I miss the query operator) - b[a.Name] = msi{a.Type: map[bool]interface{}{true: a.SetValues, false: a.Value}[a.SetType()]} - } - return b -} - -func (q *Query) addTable(t *Table) { - q.addTableByName(t.Name) -} - -func (q *Query) addTableByName(tableName string) { - q.buffer["TableName"] = tableName -} - -func (q *Query) String() string { - bytes, _ := json.Marshal(q.buffer) - return string(bytes) -} diff --git a/vendor/github.com/goamz/goamz/dynamodb/query_builder_test.go b/vendor/github.com/goamz/goamz/dynamodb/query_builder_test.go deleted file mode 100755 index 9a1f6f2c5..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/query_builder_test.go +++ /dev/null @@ -1,380 +0,0 @@ -package dynamodb_test - -import ( - simplejson "github.com/bitly/go-simplejson" - "github.com/goamz/goamz/aws" - "github.com/goamz/goamz/dynamodb" - . "gopkg.in/check.v1" -) - -type QueryBuilderSuite struct { - server *dynamodb.Server -} - -var _ = Suite(&QueryBuilderSuite{}) - -func (s *QueryBuilderSuite) SetUpSuite(c *C) { - auth := &aws.Auth{AccessKey: "", SecretKey: "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY"} - s.server = &dynamodb.Server{*auth, aws.USEast} -} - -func (s *QueryBuilderSuite) TestEmptyQuery(c *C) { - q := dynamodb.NewEmptyQuery() - queryString := q.String() - expectedString := "{}" - c.Check(queryString, Equals, expectedString) - - if expectedString != queryString { - c.Fatalf("Unexpected Query String : %s\n", queryString) - } -} - -func (s *QueryBuilderSuite) TestAddWriteRequestItems(c *C) { - primary := dynamodb.NewStringAttribute("WidgetFoo", "") - secondary := dynamodb.NewNumericAttribute("Created", "") - key := dynamodb.PrimaryKey{primary, secondary} - table := s.server.NewTable("FooData", key) - - primary2 := dynamodb.NewStringAttribute("TestHashKey", "") - secondary2 := dynamodb.NewNumericAttribute("TestRangeKey", "") - key2 := dynamodb.PrimaryKey{primary2, secondary2} - table2 := s.server.NewTable("TestTable", key2) - - q := dynamodb.NewEmptyQuery() - - attribute1 := dynamodb.NewNumericAttribute("testing", "4") - attribute2 := dynamodb.NewNumericAttribute("testingbatch", "2111") - attribute3 := dynamodb.NewStringAttribute("testingstrbatch", "mystr") - item1 := []dynamodb.Attribute{*attribute1, *attribute2, *attribute3} - - attribute4 := dynamodb.NewNumericAttribute("testing", "444") - attribute5 := dynamodb.NewNumericAttribute("testingbatch", "93748249272") - attribute6 := dynamodb.NewStringAttribute("testingstrbatch", "myotherstr") - item2 := []dynamodb.Attribute{*attribute4, *attribute5, *attribute6} - - attributeDel1 := dynamodb.NewStringAttribute("TestHashKeyDel", "DelKey") - attributeDel2 := dynamodb.NewNumericAttribute("TestRangeKeyDel", "7777777") - itemDel := []dynamodb.Attribute{*attributeDel1, *attributeDel2} - - attributeTest1 := dynamodb.NewStringAttribute("TestHashKey", "MyKey") - attributeTest2 := dynamodb.NewNumericAttribute("TestRangeKey", "0193820384293") - itemTest := []dynamodb.Attribute{*attributeTest1, *attributeTest2} - - tableItems := map[*dynamodb.Table]map[string][][]dynamodb.Attribute{} - actionItems := make(map[string][][]dynamodb.Attribute) - actionItems["Put"] = [][]dynamodb.Attribute{item1, item2} - actionItems["Delete"] = [][]dynamodb.Attribute{itemDel} - tableItems[table] = actionItems - - actionItems2 := make(map[string][][]dynamodb.Attribute) - actionItems2["Put"] = [][]dynamodb.Attribute{itemTest} - tableItems[table2] = actionItems2 - - q.AddWriteRequestItems(tableItems) - - queryJson, err := simplejson.NewJson([]byte(q.String())) - if err != nil { - c.Fatal(err) - } - - expectedJson, err := simplejson.NewJson([]byte(` -{ - "RequestItems": { - "TestTable": [ - { - "PutRequest": { - "Item": { - "TestRangeKey": { - "N": "0193820384293" - }, - "TestHashKey": { - "S": "MyKey" - } - } - } - } - ], - "FooData": [ - { - "DeleteRequest": { - "Key": { - "TestRangeKeyDel": { - "N": "7777777" - }, - "TestHashKeyDel": { - "S": "DelKey" - } - } - } - }, - { - "PutRequest": { - "Item": { - "testingstrbatch": { - "S": "mystr" - }, - "testingbatch": { - "N": "2111" - }, - "testing": { - "N": "4" - } - } - } - }, - { - "PutRequest": { - "Item": { - "testingstrbatch": { - "S": "myotherstr" - }, - "testingbatch": { - "N": "93748249272" - }, - "testing": { - "N": "444" - } - } - } - } - ] - } -} - `)) - if err != nil { - c.Fatal(err) - } - c.Check(queryJson, DeepEquals, expectedJson) -} - -func (s *QueryBuilderSuite) TestAddExpectedQuery(c *C) { - primary := dynamodb.NewStringAttribute("domain", "") - key := dynamodb.PrimaryKey{primary, nil} - table := s.server.NewTable("sites", key) - - q := dynamodb.NewQuery(table) - q.AddKey(table, &dynamodb.Key{HashKey: "test"}) - - expected := []dynamodb.Attribute{ - *dynamodb.NewStringAttribute("domain", "expectedTest").SetExists(true), - *dynamodb.NewStringAttribute("testKey", "").SetExists(false), - } - q.AddExpected(expected) - - queryJson, err := simplejson.NewJson([]byte(q.String())) - if err != nil { - c.Fatal(err) - } - - expectedJson, err := simplejson.NewJson([]byte(` - { - "Expected": { - "domain": { - "Exists": "true", - "Value": { - "S": "expectedTest" - } - }, - "testKey": { - "Exists": "false" - } - }, - "Key": { - "domain": { - "S": "test" - } - }, - "TableName": "sites" - } - `)) - if err != nil { - c.Fatal(err) - } - c.Check(queryJson, DeepEquals, expectedJson) -} - -func (s *QueryBuilderSuite) TestGetItemQuery(c *C) { - primary := dynamodb.NewStringAttribute("domain", "") - key := dynamodb.PrimaryKey{primary, nil} - table := s.server.NewTable("sites", key) - - q := dynamodb.NewQuery(table) - q.AddKey(table, &dynamodb.Key{HashKey: "test"}) - - { - queryJson, err := simplejson.NewJson([]byte(q.String())) - if err != nil { - c.Fatal(err) - } - - expectedJson, err := simplejson.NewJson([]byte(` - { - "Key": { - "domain": { - "S": "test" - } - }, - "TableName": "sites" - } - `)) - if err != nil { - c.Fatal(err) - } - c.Check(queryJson, DeepEquals, expectedJson) - } - - // Use ConsistentRead - { - q.ConsistentRead(true) - queryJson, err := simplejson.NewJson([]byte(q.String())) - if err != nil { - c.Fatal(err) - } - - expectedJson, err := simplejson.NewJson([]byte(` - { - "ConsistentRead": "true", - "Key": { - "domain": { - "S": "test" - } - }, - "TableName": "sites" - } - `)) - if err != nil { - c.Fatal(err) - } - c.Check(queryJson, DeepEquals, expectedJson) - } -} - -func (s *QueryBuilderSuite) TestUpdateQuery(c *C) { - primary := dynamodb.NewStringAttribute("domain", "") - rangek := dynamodb.NewNumericAttribute("time", "") - key := dynamodb.PrimaryKey{primary, rangek} - table := s.server.NewTable("sites", key) - - countAttribute := dynamodb.NewNumericAttribute("count", "4") - attributes := []dynamodb.Attribute{*countAttribute} - - q := dynamodb.NewQuery(table) - q.AddKey(table, &dynamodb.Key{HashKey: "test", RangeKey: "1234"}) - q.AddUpdates(attributes, "ADD") - - queryJson, err := simplejson.NewJson([]byte(q.String())) - if err != nil { - c.Fatal(err) - } - expectedJson, err := simplejson.NewJson([]byte(` -{ - "AttributeUpdates": { - "count": { - "Action": "ADD", - "Value": { - "N": "4" - } - } - }, - "Key": { - "domain": { - "S": "test" - }, - "time": { - "N": "1234" - } - }, - "TableName": "sites" -} - `)) - if err != nil { - c.Fatal(err) - } - c.Check(queryJson, DeepEquals, expectedJson) -} - -func (s *QueryBuilderSuite) TestAddUpdates(c *C) { - primary := dynamodb.NewStringAttribute("domain", "") - key := dynamodb.PrimaryKey{primary, nil} - table := s.server.NewTable("sites", key) - - q := dynamodb.NewQuery(table) - q.AddKey(table, &dynamodb.Key{HashKey: "test"}) - - attr := dynamodb.NewStringSetAttribute("StringSet", []string{"str", "str2"}) - - q.AddUpdates([]dynamodb.Attribute{*attr}, "ADD") - - queryJson, err := simplejson.NewJson([]byte(q.String())) - if err != nil { - c.Fatal(err) - } - expectedJson, err := simplejson.NewJson([]byte(` -{ - "AttributeUpdates": { - "StringSet": { - "Action": "ADD", - "Value": { - "SS": ["str", "str2"] - } - } - }, - "Key": { - "domain": { - "S": "test" - } - }, - "TableName": "sites" -} - `)) - if err != nil { - c.Fatal(err) - } - c.Check(queryJson, DeepEquals, expectedJson) -} - -func (s *QueryBuilderSuite) TestAddKeyConditions(c *C) { - primary := dynamodb.NewStringAttribute("domain", "") - key := dynamodb.PrimaryKey{primary, nil} - table := s.server.NewTable("sites", key) - - q := dynamodb.NewQuery(table) - acs := []dynamodb.AttributeComparison{ - *dynamodb.NewStringAttributeComparison("domain", "EQ", "example.com"), - *dynamodb.NewStringAttributeComparison("path", "EQ", "/"), - } - q.AddKeyConditions(acs) - queryJson, err := simplejson.NewJson([]byte(q.String())) - - if err != nil { - c.Fatal(err) - } - - expectedJson, err := simplejson.NewJson([]byte(` -{ - "KeyConditions": { - "domain": { - "AttributeValueList": [ - { - "S": "example.com" - } - ], - "ComparisonOperator": "EQ" - }, - "path": { - "AttributeValueList": [ - { - "S": "/" - } - ], - "ComparisonOperator": "EQ" - } - }, - "TableName": "sites" -} - `)) - if err != nil { - c.Fatal(err) - } - c.Check(queryJson, DeepEquals, expectedJson) -} diff --git a/vendor/github.com/goamz/goamz/dynamodb/scan.go b/vendor/github.com/goamz/goamz/dynamodb/scan.go deleted file mode 100644 index e8ed62363..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/scan.go +++ /dev/null @@ -1,51 +0,0 @@ -package dynamodb - -import ( - "errors" - "fmt" - simplejson "github.com/bitly/go-simplejson" -) - -func (t *Table) FetchResults(query *Query) ([]map[string]*Attribute, error) { - jsonResponse, err := t.Server.queryServer(target("Scan"), query) - if err != nil { - return nil, err - } - - json, err := simplejson.NewJson(jsonResponse) - if err != nil { - return nil, err - } - - itemCount, err := json.Get("Count").Int() - if err != nil { - message := fmt.Sprintf("Unexpected response %s", jsonResponse) - return nil, errors.New(message) - } - - results := make([]map[string]*Attribute, itemCount) - - for i, _ := range results { - item, err := json.Get("Items").GetIndex(i).Map() - if err != nil { - message := fmt.Sprintf("Unexpected response %s", jsonResponse) - return nil, errors.New(message) - } - results[i] = parseAttributes(item) - } - return results, nil - -} - -func (t *Table) Scan(attributeComparisons []AttributeComparison) ([]map[string]*Attribute, error) { - q := NewQuery(t) - q.AddScanFilter(attributeComparisons) - return t.FetchResults(q) -} - -func (t *Table) ParallelScan(attributeComparisons []AttributeComparison, segment int, totalSegments int) ([]map[string]*Attribute, error) { - q := NewQuery(t) - q.AddScanFilter(attributeComparisons) - q.AddParallelScanConfiguration(segment, totalSegments) - return t.FetchResults(q) -} diff --git a/vendor/github.com/goamz/goamz/dynamodb/stream.go b/vendor/github.com/goamz/goamz/dynamodb/stream.go deleted file mode 100644 index 57f3a145f..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/stream.go +++ /dev/null @@ -1,307 +0,0 @@ -package dynamodb - -import ( - "encoding/json" - "errors" - "fmt" - "reflect" - - simplejson "github.com/bitly/go-simplejson" -) - -type Stream struct { - Server *Server - Arn string -} - -type StreamListItemT struct { - StreamArn string - StreamLabel string - TableName string -} - -type SequenceNumberRangeT struct { - EndingSequenceNumber string - StartingSequenceNumber string -} - -type ShardT struct { - ParentShardId string - SequenceNumberRange SequenceNumberRangeT - ShardId string -} - -type StreamDescriptionT struct { - CreationDateTime float64 - KeySchema []KeySchemaT - LastEvaluatedShardId string - Shards []ShardT - StreamArn string - StreamLabel string - StreamStatus string - StreamViewType string - TableName string -} - -type RecordT struct { - AwsRegion string - EventID string - EventName string - EventSource string - EventVersion string - StreamRecord *StreamRecordT -} - -type StreamRecordT struct { - Keys map[string]*Attribute - NewImage map[string]*Attribute - OldImage map[string]*Attribute - SequenceNumber string - StreamViewType string - SizeBytes int64 -} - -type listStreamsResponse struct { - Streams []StreamListItemT -} - -type describeStreamResponse struct { - StreamDescription StreamDescriptionT -} - -var ErrNoRecords = errors.New("No records") - -func (s *Server) ListStreams(startArn string) ([]StreamListItemT, error) { - return s.LimitedListTableStreams("", startArn, 0) -} - -func (s *Server) LimitedListStreams(startArn string, limit int64) ([]StreamListItemT, error) { - return s.LimitedListTableStreams("", startArn, limit) -} - -func (s *Server) ListTableStreams(table, startArn string) ([]StreamListItemT, error) { - return s.LimitedListTableStreams(table, startArn, 0) -} - -func (s *Server) LimitedListTableStreams(table, startArn string, limit int64) ([]StreamListItemT, error) { - query := NewEmptyQuery() - - if len(table) != 0 { - query.addTableByName(table) - } - - if len(startArn) != 0 { - query.AddExclusiveStartStreamArn(startArn) - } - - if limit > 0 { - query.AddLimit(limit) - } - - jsonResponse, err := s.queryServer(streamsTarget("ListStreams"), query) - if err != nil { - return nil, err - } - - var r listStreamsResponse - err = json.Unmarshal(jsonResponse, &r) - if err != nil { - return nil, err - } - - return r.Streams, nil -} - -func (s *Server) DescribeStream(arn, startShardId string) (*StreamDescriptionT, error) { - return s.LimitedDescribeStream(arn, startShardId, 0) -} - -func (s *Server) LimitedDescribeStream(arn, startShardId string, limit int64) (*StreamDescriptionT, error) { - query := NewEmptyQuery() - query.AddStreamArn(arn) - - if len(startShardId) != 0 { - query.AddExclusiveStartShardId(startShardId) - } - - if limit > 0 { - query.AddLimit(limit) - } - - jsonResponse, err := s.queryServer(streamsTarget("DescribeStream"), query) - if err != nil { - return nil, err - } - - var r describeStreamResponse - err = json.Unmarshal(jsonResponse, &r) - if err != nil { - return nil, err - } - - return &r.StreamDescription, nil -} - -func (s *Server) NewStream(streamArn string) *Stream { - return &Stream{s, streamArn} -} - -func (s *Stream) DescribeStream(startShardId string) (*StreamDescriptionT, error) { - return s.Server.DescribeStream(s.Arn, startShardId) -} - -func (s *Stream) LimitedDescribeStream(startShardId string, limit int64) (*StreamDescriptionT, error) { - return s.Server.LimitedDescribeStream(s.Arn, startShardId, limit) -} - -func (s *Server) GetShardIterator(streamArn, shardId, shardIteratorType, sequenceNumber string) (string, error) { - query := NewEmptyQuery() - query.AddStreamArn(streamArn) - query.AddShardId(shardId) - query.AddShardIteratorType(shardIteratorType) - - if len(sequenceNumber) != 0 { - query.AddSequenceNumber(sequenceNumber) - } - - jsonResponse, err := s.queryServer(streamsTarget("GetShardIterator"), query) - - if err != nil { - return "unknown", err - } - - json, err := simplejson.NewJson(jsonResponse) - - if err != nil { - return "unknown", err - } - - return json.Get("ShardIterator").MustString(), nil -} - -func (s *Stream) GetShardIterator(shardId, shardIteratorType, sequenceNumber string) (string, error) { - return s.Server.GetShardIterator(s.Arn, shardId, shardIteratorType, sequenceNumber) -} - -func (s *Server) GetRecords(shardIterator string) (string, []*RecordT, error) { - return s.LimitedGetRecords(shardIterator, 0) -} - -func (s *Server) LimitedGetRecords(shardIterator string, limit int64) (string, []*RecordT, error) { - query := NewEmptyQuery() - query.AddShardIterator(shardIterator) - - if limit > 0 { - query.AddLimit(limit) - } - - jsonResponse, err := s.queryServer(streamsTarget("GetRecords"), query) - if err != nil { - return "", nil, err - } - - jsonParsed, err := simplejson.NewJson(jsonResponse) - if err != nil { - return "", nil, err - } - - nextShardIt := "" - nextShardItJson, ok := jsonParsed.CheckGet("NextShardIterator") - if ok { - nextShardIt, err = nextShardItJson.String() - if err != nil { - message := fmt.Sprintf("Unexpected response %s", jsonResponse) - return "", nil, errors.New(message) - } - } - - recordsJson, ok := jsonParsed.CheckGet("Records") - if !ok { - return nextShardIt, nil, ErrNoRecords - } - - recordsArray, err := recordsJson.Array() - if err != nil { - message := fmt.Sprintf("Unexpected response %s", jsonResponse) - return nextShardIt, nil, errors.New(message) - } - - var records []*RecordT - for _, record := range recordsArray { - if recordMap, ok := record.(map[string]interface{}); ok { - r := parseRecord(recordMap) - records = append(records, r) - } - } - - return nextShardIt, records, nil -} - -func (s *Stream) GetRecords(shardIterator string) (string, []*RecordT, error) { - return s.Server.GetRecords(shardIterator) -} - -func (s *Stream) LimitedGetRecords(shardIterator string, limit int64) (string, []*RecordT, error) { - return s.Server.LimitedGetRecords(shardIterator, limit) -} - -func parseRecord(r map[string]interface{}) *RecordT { - record := RecordT{} - rValue := reflect.ValueOf(&record) - - keys := []string{"awsRegion", "eventID", "eventName", "eventSource", "eventVersion"} - for i, key := range keys { - if value, ok := r[key]; ok { - if valueStr, ok := value.(string); ok { - rValue.Elem().Field(i).SetString(valueStr) - } - } - } - - if streamRecord, ok := r["dynamodb"]; ok { - if streamRecordMap, ok := streamRecord.(map[string]interface{}); ok { - record.StreamRecord = parseStreamRecord(streamRecordMap) - } - } - - return &record -} - -func parseStreamRecord(s map[string]interface{}) *StreamRecordT { - sr := StreamRecordT{} - rValue := reflect.ValueOf(&sr) - - attrKeys := []string{"Keys", "NewImage", "OldImage"} - numAttrKeys := len(attrKeys) - for i, key := range attrKeys { - if value, ok := s[key]; ok { - if valueMap, ok := value.(map[string]interface{}); ok { - attrs := parseAttributes(valueMap) - rValue.Elem().Field(i).Set(reflect.ValueOf(attrs)) - } - } - } - - strKeys := []string{"SequenceNumber", "StreamViewType"} - numStrKeys := len(strKeys) - for i, key := range strKeys { - if value, ok := s[key]; ok { - if valueStr, ok := value.(string); ok { - rValue.Elem().Field(i + numAttrKeys).SetString(valueStr) - } - } - } - - intKeys := []string{"SizeBytes"} - for i, key := range intKeys { - if value, ok := s[key]; ok { - if valueNumber, ok := value.(json.Number); ok { - if valueInt, err := valueNumber.Int64(); err == nil { - rValue.Elem().Field(i + numAttrKeys + numStrKeys).SetInt(valueInt) - } - } - } - } - - return &sr -} diff --git a/vendor/github.com/goamz/goamz/dynamodb/stream_test.go b/vendor/github.com/goamz/goamz/dynamodb/stream_test.go deleted file mode 100755 index a982ffa65..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/stream_test.go +++ /dev/null @@ -1,198 +0,0 @@ -package dynamodb_test - -import ( - "strconv" - - "github.com/goamz/goamz/dynamodb" - . "gopkg.in/check.v1" -) - -type StreamSuite struct { - TableDescriptionT dynamodb.TableDescriptionT - DynamoDBTest -} - -func (s *StreamSuite) SetUpSuite(c *C) { - setUpAuth(c) - s.DynamoDBTest.TableDescriptionT = s.TableDescriptionT - s.server = &dynamodb.Server{dynamodb_auth, dynamodb_region} - pk, err := s.TableDescriptionT.BuildPrimaryKey() - if err != nil { - c.Skip(err.Error()) - } - s.table = s.server.NewTable(s.TableDescriptionT.TableName, pk) - - // Cleanup - s.TearDownSuite(c) - _, err = s.server.CreateTable(s.TableDescriptionT) - if err != nil { - c.Fatal(err) - } - s.WaitUntilStatus(c, "ACTIVE") -} - -var stream_suite_keys_only = &StreamSuite{ - TableDescriptionT: dynamodb.TableDescriptionT{ - TableName: "StreamTable", - AttributeDefinitions: []dynamodb.AttributeDefinitionT{ - dynamodb.AttributeDefinitionT{"TestHashKey", "S"}, - dynamodb.AttributeDefinitionT{"TestRangeKey", "N"}, - }, - KeySchema: []dynamodb.KeySchemaT{ - dynamodb.KeySchemaT{"TestHashKey", "HASH"}, - dynamodb.KeySchemaT{"TestRangeKey", "RANGE"}, - }, - ProvisionedThroughput: dynamodb.ProvisionedThroughputT{ - ReadCapacityUnits: 1, - WriteCapacityUnits: 1, - }, - StreamSpecification: dynamodb.StreamSpecificationT{ - StreamEnabled: true, - StreamViewType: "KEYS_ONLY", - }, - }, -} - -var stream_suite_new_image = &StreamSuite{ - TableDescriptionT: dynamodb.TableDescriptionT{ - TableName: "StreamTable", - AttributeDefinitions: []dynamodb.AttributeDefinitionT{ - dynamodb.AttributeDefinitionT{"TestHashKey", "S"}, - dynamodb.AttributeDefinitionT{"TestRangeKey", "N"}, - }, - KeySchema: []dynamodb.KeySchemaT{ - dynamodb.KeySchemaT{"TestHashKey", "HASH"}, - dynamodb.KeySchemaT{"TestRangeKey", "RANGE"}, - }, - ProvisionedThroughput: dynamodb.ProvisionedThroughputT{ - ReadCapacityUnits: 1, - WriteCapacityUnits: 1, - }, - StreamSpecification: dynamodb.StreamSpecificationT{ - StreamEnabled: true, - StreamViewType: "NEW_IMAGE", - }, - }, -} - -var _ = Suite(stream_suite_keys_only) -var _ = Suite(stream_suite_new_image) - -func (s *StreamSuite) TestStream(c *C) { - checkStream(s.table, c) -} - -func checkStream(table *dynamodb.Table, c *C) { - // list the table's streams - streams, err := table.ListStreams("") - if err != nil { - c.Fatal(err) - } - c.Check(len(streams), Not(Equals), 0) - c.Check(streams[0].TableName, Equals, table.Name) - - // stick a couple of items in the table - attrs := []dynamodb.Attribute{ - *dynamodb.NewStringAttribute("TestAttr", "0"), - } - if ok, err := table.PutItem("0", "0", attrs); !ok { - c.Fatal(err) - } - attrs = []dynamodb.Attribute{ - *dynamodb.NewStringAttribute("TestAttr", "1"), - } - if ok, err := table.PutItem("1", "1", attrs); !ok { - c.Fatal(err) - } - - // create a stream object - stream := table.Server.NewStream(streams[0].StreamArn) - - // describe the steam - desc, err := stream.DescribeStream("") - if err != nil { - c.Fatal(err) - } - - tableDesc, err := table.DescribeTable() - if err != nil { - c.Fatal(err) - } - - c.Check(desc.KeySchema[0], Equals, tableDesc.KeySchema[0]) - c.Check(desc.StreamArn, Equals, streams[0].StreamArn) - c.Check(desc.StreamStatus, Equals, "ENABLED") - c.Check(desc.StreamViewType, Equals, tableDesc.StreamSpecification.StreamViewType) - c.Check(desc.TableName, Equals, table.Name) - c.Check(len(desc.Shards), Equals, 1) - - // get a shard iterator - shardIt, err := stream.GetShardIterator(desc.Shards[0].ShardId, "TRIM_HORIZON", "") - if err != nil { - c.Fatal(err) - } - c.Check(len(shardIt), Not(Equals), 0) - - // poll for records - nextIt, records, err := stream.GetRecords(shardIt) - if err != nil { - c.Fatal(err) - } - c.Check(len(nextIt), Not(Equals), 0) - c.Check(len(records), Equals, 2) - - for index, record := range records { - c.Check(record.EventSource, Equals, "aws:dynamodb") - c.Check(record.EventName, Equals, "INSERT") - c.Check(len(record.EventID), Not(Equals), 0) - - // look at the actual record - streamRec := record.StreamRecord - c.Check(streamRec.StreamViewType, Equals, desc.StreamViewType) - c.Check(len(streamRec.SequenceNumber), Not(Equals), 0) - if streamRec.SizeBytes <= 0 { - c.Errorf("Expected greater-than-zero size, got: %d", streamRec.SizeBytes) - } - // check the keys - if streamRec.StreamViewType == "KEYS_ONLY" { - checkKeys(streamRec.Keys, index, c) - } - // check the image - if streamRec.StreamViewType == "NEW_IMAGE" { - checkNewImage(streamRec.NewImage, index, c) - } - } -} - -func checkKeys(keys map[string]*dynamodb.Attribute, expect int, c *C) { - c.Check(len(keys), Equals, 2) - value, err := strconv.Atoi(keys["TestHashKey"].Value) - if err != nil { - c.Fatal(err) - } - c.Check(value, Equals, expect) - value, err = strconv.Atoi(keys["TestRangeKey"].Value) - if err != nil { - c.Fatal(err) - } - c.Check(value, Equals, expect) -} - -func checkNewImage(image map[string]*dynamodb.Attribute, expect int, c *C) { - c.Check(len(image), Equals, 3) - value, err := strconv.Atoi(image["TestHashKey"].Value) - if err != nil { - c.Fatal(err) - } - c.Check(value, Equals, expect) - value, err = strconv.Atoi(image["TestRangeKey"].Value) - if err != nil { - c.Fatal(err) - } - c.Check(value, Equals, expect) - value, err = strconv.Atoi(image["TestAttr"].Value) - if err != nil { - c.Fatal(err) - } - c.Check(value, Equals, expect) -} diff --git a/vendor/github.com/goamz/goamz/dynamodb/table.go b/vendor/github.com/goamz/goamz/dynamodb/table.go deleted file mode 100755 index 541433c13..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/table.go +++ /dev/null @@ -1,259 +0,0 @@ -package dynamodb - -import ( - "encoding/json" - "errors" - "fmt" - simplejson "github.com/bitly/go-simplejson" -) - -type Table struct { - Server *Server - Name string - Key PrimaryKey -} - -type AttributeDefinitionT struct { - Name string `json:"AttributeName"` - Type string `json:"AttributeType"` -} - -type KeySchemaT struct { - AttributeName string - KeyType string -} - -type ProjectionT struct { - ProjectionType string -} - -type GlobalSecondaryIndexT struct { - IndexName string - IndexSizeBytes int64 - ItemCount int64 - KeySchema []KeySchemaT - Projection ProjectionT - ProvisionedThroughput ProvisionedThroughputT -} - -type LocalSecondaryIndexT struct { - IndexName string - IndexSizeBytes int64 - ItemCount int64 - KeySchema []KeySchemaT - Projection ProjectionT -} - -type ProvisionedThroughputT struct { - NumberOfDecreasesToday int64 - ReadCapacityUnits int64 - WriteCapacityUnits int64 -} - -type StreamSpecificationT struct { - StreamEnabled bool - StreamViewType string -} - -type TableDescriptionT struct { - AttributeDefinitions []AttributeDefinitionT - CreationDateTime float64 - ItemCount int64 - KeySchema []KeySchemaT - GlobalSecondaryIndexes []GlobalSecondaryIndexT - LocalSecondaryIndexes []LocalSecondaryIndexT - ProvisionedThroughput ProvisionedThroughputT - StreamSpecification StreamSpecificationT - TableName string - TableSizeBytes int64 - TableStatus string - LatestStreamArn string - LatestStreamLabel string -} - -type describeTableResponse struct { - Table TableDescriptionT -} - -func findAttributeDefinitionByName(ads []AttributeDefinitionT, name string) *AttributeDefinitionT { - for _, a := range ads { - if a.Name == name { - return &a - } - } - return nil -} - -func (a *AttributeDefinitionT) GetEmptyAttribute() *Attribute { - switch a.Type { - case "S": - return NewStringAttribute(a.Name, "") - case "N": - return NewNumericAttribute(a.Name, "") - case "B": - return NewBinaryAttribute(a.Name, "") - default: - return nil - } -} - -func (t *TableDescriptionT) BuildPrimaryKey() (pk PrimaryKey, err error) { - for _, k := range t.KeySchema { - var attr *Attribute - ad := findAttributeDefinitionByName(t.AttributeDefinitions, k.AttributeName) - if ad == nil { - return pk, errors.New("An inconsistency found in TableDescriptionT") - } - attr = ad.GetEmptyAttribute() - if attr == nil { - return pk, errors.New("An inconsistency found in TableDescriptionT") - } - - switch k.KeyType { - case "HASH": - pk.KeyAttribute = attr - case "RANGE": - pk.RangeAttribute = attr - } - } - return -} - -func (s *Server) NewTable(name string, key PrimaryKey) *Table { - return &Table{s, name, key} -} - -func (s *Server) ListTables() ([]string, error) { - var tables []string - - query := NewEmptyQuery() - - jsonResponse, err := s.queryServer(target("ListTables"), query) - - if err != nil { - return nil, err - } - - json, err := simplejson.NewJson(jsonResponse) - - if err != nil { - return nil, err - } - - response, err := json.Get("TableNames").Array() - - if err != nil { - message := fmt.Sprintf("Unexpected response %s", jsonResponse) - return nil, errors.New(message) - } - - for _, value := range response { - if t, ok := (value).(string); ok { - tables = append(tables, t) - } - } - - return tables, nil -} - -func (s *Server) CreateTable(tableDescription TableDescriptionT) (string, error) { - query := NewEmptyQuery() - query.AddCreateRequestTable(tableDescription) - - jsonResponse, err := s.queryServer(target("CreateTable"), query) - - if err != nil { - return "unknown", err - } - - json, err := simplejson.NewJson(jsonResponse) - - if err != nil { - return "unknown", err - } - - return json.Get("TableDescription").Get("TableStatus").MustString(), nil -} - -func (s *Server) DeleteTable(tableDescription TableDescriptionT) (string, error) { - query := NewEmptyQuery() - query.AddDeleteRequestTable(tableDescription) - - jsonResponse, err := s.queryServer(target("DeleteTable"), query) - - if err != nil { - return "unknown", err - } - - json, err := simplejson.NewJson(jsonResponse) - - if err != nil { - return "unknown", err - } - - return json.Get("TableDescription").Get("TableStatus").MustString(), nil -} - -func (t *Table) DescribeTable() (*TableDescriptionT, error) { - return t.Server.DescribeTable(t.Name) -} - -func (s *Server) DescribeTable(name string) (*TableDescriptionT, error) { - q := NewEmptyQuery() - q.addTableByName(name) - - jsonResponse, err := s.queryServer(target("DescribeTable"), q) - if err != nil { - return nil, err - } - - var r describeTableResponse - err = json.Unmarshal(jsonResponse, &r) - if err != nil { - return nil, err - } - - return &r.Table, nil -} - -func (s *Server) UpdateTable(tableDescription TableDescriptionT) (string, error) { - query := NewEmptyQuery() - query.AddUpdateRequestTable(tableDescription) - - jsonResponse, err := s.queryServer(target("UpdateTable"), query) - - if err != nil { - return "unknown", err - } - - json, err := simplejson.NewJson(jsonResponse) - - if err != nil { - return "unknown", err - } - - return json.Get("TableDescription").Get("TableStatus").MustString(), nil -} - -func (t *Table) ListStreams(startArn string) ([]StreamListItemT, error) { - return t.Server.ListTableStreams(t.Name, startArn) -} - -func (t *Table) LimitedListStreams(startArn string, limit int64) ([]StreamListItemT, error) { - return t.Server.LimitedListTableStreams(t.Name, startArn, limit) -} - -func keyParam(k *PrimaryKey, hashKey string, rangeKey string) string { - value := fmt.Sprintf("{\"HashKeyElement\":{%s}", keyValue(k.KeyAttribute.Type, hashKey)) - - if k.RangeAttribute != nil { - value = fmt.Sprintf("%s,\"RangeKeyElement\":{%s}", value, - keyValue(k.RangeAttribute.Type, rangeKey)) - } - - return fmt.Sprintf("\"Key\":%s}", value) -} - -func keyValue(key string, value string) string { - return fmt.Sprintf("\"%s\":\"%s\"", key, value) -} diff --git a/vendor/github.com/goamz/goamz/dynamodb/table_test.go b/vendor/github.com/goamz/goamz/dynamodb/table_test.go deleted file mode 100755 index 8925bdc1b..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/table_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package dynamodb_test - -import ( - "github.com/goamz/goamz/dynamodb" - . "gopkg.in/check.v1" -) - -type TableSuite struct { - TableDescriptionT dynamodb.TableDescriptionT - DynamoDBTest -} - -func (s *TableSuite) SetUpSuite(c *C) { - setUpAuth(c) - s.DynamoDBTest.TableDescriptionT = s.TableDescriptionT - s.server = &dynamodb.Server{dynamodb_auth, dynamodb_region} - pk, err := s.TableDescriptionT.BuildPrimaryKey() - if err != nil { - c.Skip(err.Error()) - } - s.table = s.server.NewTable(s.TableDescriptionT.TableName, pk) - - // Cleanup - s.TearDownSuite(c) -} - -var table_suite = &TableSuite{ - TableDescriptionT: dynamodb.TableDescriptionT{ - TableName: "DynamoDBTestMyTable", - AttributeDefinitions: []dynamodb.AttributeDefinitionT{ - dynamodb.AttributeDefinitionT{"TestHashKey", "S"}, - dynamodb.AttributeDefinitionT{"TestRangeKey", "N"}, - dynamodb.AttributeDefinitionT{"TestSecKey", "N"}, - }, - KeySchema: []dynamodb.KeySchemaT{ - dynamodb.KeySchemaT{"TestHashKey", "HASH"}, - dynamodb.KeySchemaT{"TestRangeKey", "RANGE"}, - }, - GlobalSecondaryIndexes: []dynamodb.GlobalSecondaryIndexT{ - dynamodb.GlobalSecondaryIndexT{ - IndexName: "gsiTest", - KeySchema: []dynamodb.KeySchemaT{ - dynamodb.KeySchemaT{"TestHashKey", "HASH"}, - dynamodb.KeySchemaT{"TestSecKey", "RANGE"}, - }, - Projection: dynamodb.ProjectionT{"ALL"}, - ProvisionedThroughput: dynamodb.ProvisionedThroughputT{ - ReadCapacityUnits: 1, - WriteCapacityUnits: 1, - }, - }, - }, - ProvisionedThroughput: dynamodb.ProvisionedThroughputT{ - ReadCapacityUnits: 1, - WriteCapacityUnits: 1, - }, - }, -} - -var _ = Suite(table_suite) - -func (s *TableSuite) TestCreateListTable(c *C) { - status, err := s.server.CreateTable(s.TableDescriptionT) - if err != nil { - c.Fatal(err) - } - if status != "ACTIVE" && status != "CREATING" { - c.Error("Expect status to be ACTIVE or CREATING") - } - - s.WaitUntilStatus(c, "ACTIVE") - - tables, err := s.server.ListTables() - if err != nil { - c.Fatal(err) - } - c.Check(len(tables), Not(Equals), 0) - c.Check(findTableByName(tables, s.TableDescriptionT.TableName), Equals, true) -} diff --git a/vendor/github.com/goamz/goamz/dynamodb/update_item.go b/vendor/github.com/goamz/goamz/dynamodb/update_item.go deleted file mode 100644 index 280eb4bed..000000000 --- a/vendor/github.com/goamz/goamz/dynamodb/update_item.go +++ /dev/null @@ -1,94 +0,0 @@ -package dynamodb - -import simplejson "github.com/bitly/go-simplejson" - -/* -Construct an update item query. - -The query can be composed via chaining and then executed via Execute() - -Usage: - update := table.UpdateItem(key) - .ReturnValues(dynamodb.UPDATED_NEW) - .UpdateExpression("SET Counter = Counter + :incr") - .UpdateCondition("Counter < :checkVal") - .ExpressionAttributes(NewNumberAttribute(":incr", "1"), NewNumberAttribute(":checkVal", 42)) - result, err := update.Execute() - if err == nil { - log.Printf("Counter is now %v", result.Attributes["Counter"].Value) - } - -*/ -func (t *Table) UpdateItem(key *Key) *UpdateItem { - q := NewQuery(t) - q.AddKey(t, key) - return &UpdateItem{table: t, query: q} -} - -type UpdateItem struct { - table *Table - query *Query - hasReturnValues bool -} - -// Specify how return values are to be provided. -func (u *UpdateItem) ReturnValues(returnValues ReturnValues) *UpdateItem { - u.hasReturnValues = (returnValues != NONE) - u.query.AddReturnValues(returnValues) - return u -} - -/* -Specify an update expression and optional attribute settings at the same time. - - update.UpdateExpression("SET Foo = Foo + :incr", dynamodb.NewNumberAttribute(":incr", "7")) - -is equivalent to - - update.UpdateExpression("SET Foo = Foo + :incr") - .ExpressionAttributes(NewNumberAttribute(":incr", "7")) - -*/ -func (u *UpdateItem) UpdateExpression(expression string, attributes ...Attribute) *UpdateItem { - u.query.AddUpdateExpression(expression) - u.ExpressionAttributes(attributes...) - return u -} - -// Specify attribute substitutions to be used in expressions. -func (u *UpdateItem) ExpressionAttributes(attributes ...Attribute) *UpdateItem { - u.query.AddExpressionAttributes(attributes) - return u -} - -// Specify a check condition for conditional updates. -func (u *UpdateItem) ConditionExpression(expression string) *UpdateItem { - u.query.AddConditionExpression(expression) - return u -} - -// Execute this query. -func (u *UpdateItem) Execute() (*UpdateResult, error) { - jsonResponse, err := u.table.Server.queryServer(target("UpdateItem"), u.query) - - if err != nil { - return nil, err - } - - if u.hasReturnValues { - resp, err := simplejson.NewJson(jsonResponse) - if err != nil { - return nil, err - } - attrib, err := resp.Get("Attributes").Map() - if err != nil { - return nil, err - } - return &UpdateResult{parseAttributes(attrib)}, nil - } - return nil, nil -} - -type UpdateResult struct { - Attributes map[string]*Attribute -} |