summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/goamz/goamz/dynamodb/dynamodb.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/goamz/goamz/dynamodb/dynamodb.go')
-rwxr-xr-xvendor/github.com/goamz/goamz/dynamodb/dynamodb.go142
1 files changed, 142 insertions, 0 deletions
diff --git a/vendor/github.com/goamz/goamz/dynamodb/dynamodb.go b/vendor/github.com/goamz/goamz/dynamodb/dynamodb.go
new file mode 100755
index 000000000..7881e8dc1
--- /dev/null
+++ b/vendor/github.com/goamz/goamz/dynamodb/dynamodb.go
@@ -0,0 +1,142 @@
+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)
+}