gifs/api

Paddy 2014-08-27 Child:96aac3ae74e6

0:08ec88016e2f Go to Latest

gifs/api/memstore.go

Spike out functionality and tests. Create our interfaces around storing data and retrieving it. Create an in-memory implementation of our interfaces, for testing and rapid dev purposes. Begin sketching out what our unit tests look like. Create our Google Cloud Storage datastore implementation. Sketch out an idea for a usage collection process to keep track of which users are actually using stuff.

History
1 package api
3 import (
4 "time"
6 "secondbit.org/uuid"
7 )
9 type Memstore struct {
10 collections map[string]Collection
11 domains map[string]Domain
12 items map[string]Item
13 users map[string]User
14 logins map[string]Login
15 }
17 func NewMemstore() Memstore {
18 return Memstore{
19 collections: map[string]Collection{},
20 domains: map[string]Domain{},
21 items: map[string]Item{},
22 users: map[string]User{},
23 logins: map[string]Login{},
24 }
25 }
27 func (m Memstore) CreateCollection(c Collection) error {
28 m.collections[c.ID.String()] = c
29 return nil
30 }
32 func (m Memstore) UpdateCollection(c Collection) error {
33 if _, ok := m.collections[c.ID.String()]; !ok {
34 return CollectionNotFoundError
35 }
36 m.collections[c.ID.String()] = c
37 return nil
38 }
40 func (m Memstore) GetCollectionByDomain(domain string) (Collection, error) {
41 d, ok := m.domains[domain]
42 if !ok {
43 return Collection{}, CollectionNotFoundError
44 }
45 return m.GetCollectionByID(d.CollectionID)
46 }
48 func (m Memstore) GetCollectionByID(id uuid.ID) (Collection, error) {
49 if c, ok := m.collections[id.String()]; ok {
50 return c, nil
51 }
52 return Collection{}, CollectionNotFoundError
53 }
55 func (m Memstore) GetCollectionsByUser(id uuid.ID) ([]Collection, error) {
56 collections := []Collection{}
57 for _, c := range m.collections {
58 if c.Owner.Equal(id) {
59 collections = append(collections, c)
60 }
61 }
62 return collections, nil
63 }
65 func (m Memstore) AddDomainToCollection(id uuid.ID, domain string) error {
66 if _, ok := m.domains[domain]; ok {
67 return DomainAlreadyExistsError
68 }
69 m.domains[domain] = Domain{
70 Domain: domain,
71 CollectionID: id,
72 Created: time.Now(),
73 }
74 return nil
75 }
77 func (m Memstore) RemoveDomainFromCollection(id uuid.ID, domain string) error {
78 if _, ok := m.domains[domain]; !ok {
79 return DomainNotFoundError
80 }
81 delete(m.domains, domain)
82 return nil
83 }
85 func (m Memstore) GetDomainsByCollection(id uuid.ID) ([]Domain, error) {
86 domains := []Domain{}
87 for _, d := range m.domains {
88 if d.CollectionID.Equal(id) {
89 domains = append(domains, d)
90 }
91 }
92 return domains, nil
93 }
95 func (m Memstore) DeleteCollection(c Collection) error {
96 if _, ok := m.collections[c.ID.String()]; !ok {
97 return CollectionNotFoundError
98 }
99 delete(m.collections, c.ID.String())
100 return nil
101 }
103 func (m Memstore) GetItemsByCollectionDomain(domain string, num, offset int) ([]Item, error) {
104 collection, err := m.GetCollectionByDomain(domain)
105 if err != nil {
106 return []Item{}, err
107 }
108 return m.GetItemsByCollectionID(collection.ID, num, offset)
109 }
111 func (m Memstore) GetItemsByCollectionID(id uuid.ID, num, offset int) ([]Item, error) {
112 if _, ok := m.collections[id.String()]; !ok {
113 return []Item{}, CollectionNotFoundError
114 }
115 items := []Item{}
116 for _, item := range m.items {
117 if item.CollectionID.Equal(id) {
118 items = append(items, item)
119 }
120 }
121 if len(items) < offset {
122 return []Item{}, nil
123 }
124 end := offset + num
125 if len(items) < end {
126 end = len(items)
127 }
128 return items[offset:end], nil
129 }
131 func (m Memstore) AddItemToCollection(id uuid.ID, item Item) error {
132 if _, ok := m.collections[id.String()]; !ok {
133 return CollectionNotFoundError
134 }
135 if _, ok := m.items[id.String()+"/"+item.Name]; ok {
136 return ItemAlreadyExistsError
137 }
138 item.CollectionID = id
139 m.items[id.String()+"/"+item.Name] = item
140 return nil
141 }
143 func (m Memstore) GetItemByName(collectionID uuid.ID, name string) (Item, error) {
144 if _, ok := m.collections[collectionID.String()]; !ok {
145 return Item{}, CollectionNotFoundError
146 }
147 if item, ok := m.items[collectionID.String()+"/"+name]; ok {
148 return item, nil
149 }
150 return Item{}, ItemNotFoundError
151 }
153 func (m Memstore) DeleteItem(item Item) error {
154 if _, ok := m.items[item.CollectionID.String()+"/"+item.Name]; !ok {
155 return ItemNotFoundError
156 }
157 delete(m.items, item.CollectionID.String()+"/"+item.Name)
158 return nil
159 }
161 func (m Memstore) GetUserByID(id uuid.ID) (User, error) {
162 if u, ok := m.users[id.String()]; ok {
163 return u, nil
164 }
165 return User{}, UserNotFoundError
166 }
168 func (m Memstore) GetUserByLogin(loginType, value, passphrase string) (User, error) {
169 login, ok := m.logins[loginType+":"+value]
170 if !ok {
171 return User{}, UserNotFoundError
172 }
173 user, err := m.GetUserByID(login.UserID)
174 if err != nil {
175 return user, err
176 }
177 if user.Passphrase != passphrase {
178 return User{}, UserNotFoundError
179 }
180 return user, nil
181 }
183 func (m Memstore) CreateUser(u User) error {
184 m.users[u.ID.String()] = u
185 return nil
186 }
188 func (m Memstore) AddLoginToUser(login Login, user uuid.ID) error {
189 if _, ok := m.logins[login.Type+":"+login.Value]; ok {
190 return LoginAlreadyExistsError
191 }
192 m.logins[login.Type+":"+login.Value] = login
193 return nil
194 }
196 func (m Memstore) RemoveLoginFromUser(loginType, value string, user uuid.ID) error {
197 if _, ok := m.logins[loginType+":"+value]; !ok {
198 return LoginNotFoundError
199 }
200 delete(m.logins, loginType+":"+value)
201 return nil
202 }
204 func (m Memstore) GetLoginsByUser(user uuid.ID) ([]Login, error) {
205 logins := []Login{}
206 for _, login := range m.logins {
207 if login.UserID.Equal(user) {
208 logins = append(logins, login)
209 }
210 }
211 return logins, nil
212 }
214 func (m Memstore) UpdateUser(u User) error {
215 if _, ok := m.users[u.ID.String()]; !ok {
216 return UserNotFoundError
217 }
218 m.users[u.ID.String()] = u
219 return nil
220 }
222 func (m Memstore) DeleteUser(u User) error {
223 if _, ok := m.users[u.ID.String()]; !ok {
224 return UserNotFoundError
225 }
226 delete(m.users, u.ID.String())
227 return nil
228 }