gifs/api
2014-10-17
Parent:d3ba1115bfd0
gifs/api/datastore.go
Upload is no longer async, memstorage is parallel-safe. Upload no longer needs to be run async (it can be run inside a goroutine), so it now returns stuff instead of taking a channel as an argument. This will make it easier to implement, as all the async stuff is an abstraction above, and therefore doesn't need to be worried about for each reimplementation. The memstorage type is no longer exported and can now be safely used by multiple goroutines, thanks to the sync package.
| paddy@0 | 1 package api |
| paddy@0 | 2 |
| paddy@0 | 3 import ( |
| paddy@0 | 4 "errors" |
| paddy@0 | 5 "time" |
| paddy@0 | 6 "unicode" |
| paddy@0 | 7 |
| paddy@0 | 8 "code.google.com/p/go.text/unicode/norm" |
| paddy@1 | 9 "code.secondbit.org/uuid.hg" |
| paddy@0 | 10 ) |
| paddy@0 | 11 |
| paddy@0 | 12 var ( |
| paddy@1 | 13 ErrCollectionNotFound = errors.New("collection not found") |
| paddy@1 | 14 ErrDomainNotFound = errors.New("domain not found") |
| paddy@1 | 15 ErrDomainAlreadyExists = errors.New("domain already attached to a collection") |
| paddy@1 | 16 ErrItemNotFound = errors.New("item not found") |
| paddy@1 | 17 ErrItemAlreadyExists = errors.New("item already exists") |
| paddy@0 | 18 ) |
| paddy@0 | 19 |
| paddy@0 | 20 type Datastore interface { |
| paddy@0 | 21 CreateCollection(c Collection) error |
| paddy@1 | 22 UpdateCollection(id uuid.ID, change CollectionChange) error |
| paddy@0 | 23 GetCollectionByDomain(domain string) (Collection, error) |
| paddy@0 | 24 GetCollectionByID(id uuid.ID) (Collection, error) |
| paddy@0 | 25 GetCollectionsByUser(id uuid.ID) ([]Collection, error) |
| paddy@0 | 26 AddDomainToCollection(id uuid.ID, domain string) error |
| paddy@0 | 27 RemoveDomainFromCollection(id uuid.ID, domain string) error |
| paddy@0 | 28 GetDomainsByCollection(id uuid.ID) ([]Domain, error) |
| paddy@0 | 29 DeleteCollection(c Collection) error |
| paddy@0 | 30 |
| paddy@0 | 31 GetItemsByCollectionDomain(domain string, num, offset int) ([]Item, error) |
| paddy@0 | 32 GetItemsByCollectionID(id uuid.ID, num, offset int) ([]Item, error) |
| paddy@0 | 33 AddItemToCollection(id uuid.ID, item Item) error |
| paddy@0 | 34 GetItemByName(collectionID uuid.ID, name string) (Item, error) |
| paddy@0 | 35 DeleteItem(item Item) error |
| paddy@0 | 36 } |
| paddy@0 | 37 |
| paddy@0 | 38 func slugify(in string) string { |
| paddy@0 | 39 buf := make([]rune, 0, len(in)) |
| paddy@0 | 40 needsDash := false |
| paddy@0 | 41 for _, r := range norm.NFKD.String(in) { |
| paddy@0 | 42 if unicode.IsSpace(r) || unicode.IsPunct(r) { |
| paddy@0 | 43 if needsDash { |
| paddy@0 | 44 buf = append(buf, '-') |
| paddy@0 | 45 needsDash = false |
| paddy@0 | 46 } |
| paddy@0 | 47 } else { |
| paddy@0 | 48 buf = append(buf, r) |
| paddy@0 | 49 needsDash = true |
| paddy@0 | 50 } |
| paddy@0 | 51 } |
| paddy@0 | 52 return string(buf) |
| paddy@0 | 53 } |
| paddy@0 | 54 |
| paddy@0 | 55 type Collection struct { |
| paddy@0 | 56 ID uuid.ID |
| paddy@0 | 57 Name string |
| paddy@0 | 58 Owner uuid.ID |
| paddy@0 | 59 Created time.Time |
| paddy@0 | 60 } |
| paddy@0 | 61 |
| paddy@1 | 62 func (c *Collection) ApplyChange(change CollectionChange) { |
| paddy@1 | 63 if change.Name != nil { |
| paddy@1 | 64 c.Name = *change.Name |
| paddy@1 | 65 } |
| paddy@1 | 66 } |
| paddy@1 | 67 |
| paddy@1 | 68 type CollectionChange struct { |
| paddy@1 | 69 Name *string |
| paddy@1 | 70 } |
| paddy@1 | 71 |
| paddy@0 | 72 type Domain struct { |
| paddy@0 | 73 Domain string |
| paddy@0 | 74 CollectionID uuid.ID |
| paddy@0 | 75 Created time.Time |
| paddy@0 | 76 } |
| paddy@0 | 77 |
| paddy@0 | 78 type Item struct { |
| paddy@0 | 79 Blob string |
| paddy@0 | 80 Bucket string |
| paddy@0 | 81 CollectionID uuid.ID |
| paddy@0 | 82 Name string |
| paddy@0 | 83 } |