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