ducky/subscriptions
ducky/subscriptions/subscription_memstore.go
Add comments, move ChangingSystemProperties to the api package. Add comments to all our exported types and variables in subscription.go, both to make golint happy and because it's good to have comments. Move the subscriptions.ChangingSystemProperties helper to api.changingSystemProperties, because it returns API-specific strings and there's no real reason it has to be in the subscriptions package--everything it needs to work on is exported.
| paddy@0 | 1 package subscriptions |
| paddy@0 | 2 |
| paddy@0 | 3 import ( |
| paddy@0 | 4 "code.secondbit.org/uuid.hg" |
| paddy@0 | 5 ) |
| paddy@0 | 6 |
| paddy@2 | 7 func stripeSubscriptionInMemstore(stripeSubscription string, m *Memstore) bool { |
| paddy@0 | 8 for _, sub := range m.subscriptions { |
| paddy@2 | 9 if sub.StripeSubscription == stripeSubscription { |
| paddy@0 | 10 return true |
| paddy@0 | 11 } |
| paddy@0 | 12 } |
| paddy@0 | 13 return false |
| paddy@0 | 14 } |
| paddy@0 | 15 |
| paddy@3 | 16 func (m *Memstore) CreateSubscription(sub Subscription) error { |
| paddy@0 | 17 m.subscriptionLock.Lock() |
| paddy@0 | 18 defer m.subscriptionLock.Unlock() |
| paddy@0 | 19 |
| paddy@1 | 20 if _, ok := m.subscriptions[sub.UserID.String()]; ok { |
| paddy@0 | 21 return ErrSubscriptionAlreadyExists |
| paddy@0 | 22 } |
| paddy@2 | 23 if stripeSubscriptionInMemstore(sub.StripeSubscription, m) { |
| paddy@2 | 24 return ErrStripeSubscriptionAlreadyExists |
| paddy@0 | 25 } |
| paddy@1 | 26 m.subscriptions[sub.UserID.String()] = sub |
| paddy@0 | 27 return nil |
| paddy@0 | 28 } |
| paddy@0 | 29 |
| paddy@3 | 30 func (m *Memstore) UpdateSubscription(id uuid.ID, change SubscriptionChange) error { |
| paddy@0 | 31 if change.IsEmpty() { |
| paddy@0 | 32 return ErrSubscriptionChangeEmpty |
| paddy@0 | 33 } |
| paddy@0 | 34 |
| paddy@0 | 35 m.subscriptionLock.Lock() |
| paddy@0 | 36 defer m.subscriptionLock.Unlock() |
| paddy@0 | 37 |
| paddy@0 | 38 s, ok := m.subscriptions[id.String()] |
| paddy@0 | 39 if !ok { |
| paddy@0 | 40 return ErrSubscriptionNotFound |
| paddy@0 | 41 } |
| paddy@2 | 42 if change.StripeSubscription != nil { |
| paddy@2 | 43 if stripeSubscriptionInMemstore(*change.StripeSubscription, m) { |
| paddy@2 | 44 return ErrStripeSubscriptionAlreadyExists |
| paddy@0 | 45 } |
| paddy@0 | 46 } |
| paddy@0 | 47 s.ApplyChange(change) |
| paddy@0 | 48 m.subscriptions[id.String()] = s |
| paddy@0 | 49 return nil |
| paddy@0 | 50 } |
| paddy@0 | 51 |
| paddy@3 | 52 func (m *Memstore) DeleteSubscription(id uuid.ID) error { |
| paddy@0 | 53 m.subscriptionLock.Lock() |
| paddy@0 | 54 defer m.subscriptionLock.Unlock() |
| paddy@0 | 55 |
| paddy@0 | 56 _, ok := m.subscriptions[id.String()] |
| paddy@0 | 57 if !ok { |
| paddy@0 | 58 return ErrSubscriptionNotFound |
| paddy@0 | 59 } |
| paddy@0 | 60 delete(m.subscriptions, id.String()) |
| paddy@0 | 61 return nil |
| paddy@0 | 62 } |
| paddy@0 | 63 |
| paddy@3 | 64 func (m *Memstore) GetSubscriptions(ids []uuid.ID) (map[string]Subscription, error) { |
| paddy@0 | 65 if len(ids) < 1 { |
| paddy@0 | 66 return map[string]Subscription{}, ErrNoSubscriptionID |
| paddy@0 | 67 } |
| paddy@0 | 68 m.subscriptionLock.RLock() |
| paddy@0 | 69 defer m.subscriptionLock.RUnlock() |
| paddy@0 | 70 |
| paddy@0 | 71 result := map[string]Subscription{} |
| paddy@0 | 72 |
| paddy@0 | 73 for _, id := range ids { |
| paddy@0 | 74 s, ok := m.subscriptions[id.String()] |
| paddy@0 | 75 if !ok { |
| paddy@0 | 76 continue |
| paddy@0 | 77 } |
| paddy@1 | 78 result[s.UserID.String()] = s |
| paddy@0 | 79 } |
| paddy@0 | 80 return result, nil |
| paddy@0 | 81 } |
| paddy@0 | 82 |
| paddy@3 | 83 func (m *Memstore) GetSubscriptionStats() (SubscriptionStats, error) { |
| paddy@0 | 84 m.subscriptionLock.RLock() |
| paddy@0 | 85 defer m.subscriptionLock.RUnlock() |
| paddy@0 | 86 |
| paddy@2 | 87 stats := SubscriptionStats{ |
| paddy@2 | 88 Plans: map[string]int64{}, |
| paddy@2 | 89 } |
| paddy@1 | 90 |
| paddy@0 | 91 for _, subscription := range m.subscriptions { |
| paddy@1 | 92 stats.Number++ |
| paddy@2 | 93 stats.Plans[subscription.Plan]++ |
| paddy@0 | 94 |
| paddy@2 | 95 if subscription.Canceling { |
| paddy@2 | 96 stats.Canceling++ |
| paddy@2 | 97 } |
| paddy@2 | 98 if subscription.Status == "past_due" || subscription.Status == "unpaid" { |
| paddy@2 | 99 stats.Failing++ |
| paddy@2 | 100 } |
| paddy@1 | 101 } |
| paddy@1 | 102 return stats, nil |
| paddy@0 | 103 } |