func (d DynamoDB) putItem(item map[string]Value) error { now := time.Now() transport := http.DefaultTransport m := make(map[string]sType) for key, value := range item { switch value.Type { case S: m[key] = sType{S: value.S} case N: m[key] = sType{N: fmt.Sprintf("%f", value.N)} default: return errors.New("illegal type") } } content, err := json.MarshalIndent(putRequest{TableName: d.Table, Item: m}, "", " ") if err != nil { return err } req, err := http.NewRequest("POST", "https://dynamodb.us-east-1.amazonaws.com/", bytes.NewReader(content)) if err != nil { return err } req.Header.Add("Date", formatTime(now)) req.Header.Add("X-Amz-Target", "DynamoDB_20111205.PutItem") req.Header.Add("Content-Type", "application/x-amz-json-1.0") keys := d.keys() svc := aws.Service{Name: "dynamodb", Region: "us-east-1"} err = svc.Sign(&keys, req) if err != nil { return err } resp, err := transport.RoundTrip(req) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode != 200 { return errors.New("status " + resp.Status) } return nil }
func (d DynamoDB) incItem(key, attr string, v float64) error { now := time.Now() transport := http.DefaultTransport kt := keyType{HashKeyElement: sType{S: key}} update := make(map[string]attrUpdate) update[attr] = attrUpdate{Value: sType{N: fmt.Sprintf("%f", v)}, Action: "ADD"} content, err := json.MarshalIndent(updateRequest{TableName: d.Table, Key: kt, AttributeUpdates: update}, "", " ") if err != nil { return err } req, err := http.NewRequest("POST", "https://dynamodb.us-east-1.amazonaws.com/", bytes.NewReader(content)) if err != nil { return err } req.Header.Add("Date", formatTime(now)) req.Header.Add("X-Amz-Target", "DynamoDB_20111205.UpdateItem") req.Header.Add("Content-Type", "application/x-amz-json-1.0") keys := d.keys() svc := aws.Service{Name: "dynamodb", Region: "us-east-1"} err = svc.Sign(&keys, req) if err != nil { return err } resp, err := transport.RoundTrip(req) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode != 200 { return errors.New("status " + resp.Status) } return nil }
func (d DynamoDB) deleteItem(mykey string) error { now := time.Now() transport := http.DefaultTransport myid := sType{S: mykey} key := keyType{myid} content, err := json.Marshal(deleteRequest{TableName: d.Table, Key: key}) if err != nil { return err } req, err := http.NewRequest("POST", "https://dynamodb.us-east-1.amazonaws.com/", bytes.NewReader(content)) if err != nil { return err } req.Header.Add("Date", formatTime(now)) req.Header.Add("X-Amz-Target", "DynamoDB_20111205.DeleteItem") req.Header.Add("Content-Type", "application/x-amz-json-1.0") keys := d.keys() svc := aws.Service{Name: "dynamodb", Region: "us-east-1"} err = svc.Sign(&keys, req) if err != nil { return err } resp, err := transport.RoundTrip(req) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode != 200 { return errors.New("status " + resp.Status) } return nil }
func (d DynamoDB) getItem(mykey string) (out map[string]Value, hasItem bool, err error) { out = make(map[string]Value) hasItem = true now := time.Now() transport := http.DefaultTransport myid := sType{S: mykey} key := keyType{myid} content, err := json.Marshal(getRequest{TableName: d.Table, Key: key, ConsistentRead: true}) if err != nil { return } req, err := http.NewRequest("POST", "https://dynamodb.us-east-1.amazonaws.com/", bytes.NewReader(content)) if err != nil { return } req.Header.Add("Date", formatTime(now)) req.Header.Add("X-Amz-Target", "DynamoDB_20111205.GetItem") req.Header.Add("Content-Type", "application/x-amz-json-1.0") keys := d.keys() svc := aws.Service{Name: "dynamodb", Region: "us-east-1"} err = svc.Sign(&keys, req) if err != nil { return } resp, err := transport.RoundTrip(req) if err != nil { return } defer resp.Body.Close() if resp.StatusCode != 200 { err = errors.New("status " + resp.Status) return } var buf bytes.Buffer buf.ReadFrom(resp.Body) var v map[string]interface{} err = json.Unmarshal(buf.Bytes(), &v) if err != nil { return } item, ok := v["Item"].(map[string]interface{}) if !ok { hasItem = false return } for key, value := range item { v, ok := value.(map[string]interface{}) if !ok { err = errors.New("bad kv") return } switch { case v["N"] != nil: n, err2 := strconv.ParseFloat(v["N"].(string), 64) if err2 != nil { err = err2 return } out[key] = Value{Type: N, N: n} case v["S"] != nil: out[key] = Value{Type: S, S: v["S"].(string)} } } return }