/
dynamo.go
132 lines (117 loc) · 2.92 KB
/
dynamo.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package user
import (
"errors"
"time"
"bitbucket.org/backend/core/entities"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
)
type dynamo struct {
svc *dynamodb.DynamoDB
}
// New isntanciates a session dynamo session to query information
// about users
func New(sess *session.Session) Storage {
d := &dynamo{
svc: dynamodb.New(sess),
}
return d
}
const (
// TableName is the table used to store the data
TableName = "trinacia"
)
var (
// ErrorUserAlreadyExists returned when a new user is updating an already existing user
ErrorUserAlreadyExists = errors.New("the user can't be created because it already exists")
// ErrorInvalidUser user not found
ErrorInvalidUser = errors.New("Invalid User ID")
// ErrorMissingUserID missing user ID
ErrorMissingUserID = errors.New("Missing User ID")
// ErrorMissingUser nil pointer reference to User
ErrorMissingUser = errors.New("Nil pointer reference passed as User")
)
func (d *dynamo) StoreUser(u *entities.User) error {
if u == nil {
return ErrorMissingUser
}
if u.ID == "" {
return ErrorMissingUserID
}
if us, err := d.GetUser(u.ID); us != nil || err != ErrorInvalidUser && err != nil {
switch {
case us != nil:
return ErrorUserAlreadyExists
default:
return err
}
}
var creationTime = time.Now().String()
u.CreationTime = creationTime
in := &dynamodb.UpdateItemInput{
TableName: aws.String(TableName),
Key: map[string]*dynamodb.AttributeValue{
"partition": {
S: aws.String("users"),
},
"key": {
S: aws.String(u.ID),
},
},
ExpressionAttributeNames: map[string]*string{
"#id": aws.String("id"),
"#name": aws.String("name"),
"#email": aws.String("email"),
"#creation_time": aws.String("creation_time"),
"#sort": aws.String("sort"),
},
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":id": {
S: aws.String(u.ID),
},
":name": {
S: aws.String(u.Name),
},
":email": {
S: aws.String(u.Email),
},
":creation_time": {
S: aws.String(creationTime),
},
},
UpdateExpression: aws.String("set #id=:id, #name=:name, #email=:email, #sort=:creation_time, #creation_time=:creation_time"),
}
_, err := d.svc.UpdateItem(in)
return err
}
func (d *dynamo) GetUser(userID string) (*entities.User, error) {
if userID == "" {
return nil, ErrorMissingUserID
}
u := &entities.User{}
in := &dynamodb.GetItemInput{
TableName: aws.String(TableName),
Key: map[string]*dynamodb.AttributeValue{
"partition": {
S: aws.String("users"),
},
"key": {
S: aws.String(userID),
},
},
}
out, err := d.svc.GetItem(in)
if err != nil {
return nil, err
}
err = dynamodbattribute.UnmarshalMap(out.Item, u)
if err != nil {
return nil, err
}
if u.ID == "" {
return nil, ErrorInvalidUser
}
return u, nil
}