-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathstorage_json.go
173 lines (135 loc) · 3.81 KB
/
storage_json.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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package main
import (
"encoding/json"
"fmt"
"strconv"
model "github.com/golang-bristol/beer-model"
"github.com/nanobox-io/golang-scribble"
)
const (
// CollectionBeer identifier for JSON collection about beers
CollectionBeer int = iota
// CollectionReview identifier for JSON collection about reviews
CollectionReview
)
// StorageJSON is the data storage type using JSON file
type StorageJSON struct {
db *scribble.Driver
}
func newStorageJSON(location string) (*StorageJSON, error) {
var err error
stg := new(StorageJSON)
stg.db, err = scribble.New(location, nil)
if err != nil {
return nil, err
}
return stg, nil
}
// SaveBeer insert new beers
func (s *StorageJSON) SaveBeer(beers ...model.Beer) error {
for _, beer := range beers {
var resource = strconv.Itoa(beer.ID)
var collection = strconv.Itoa(CollectionBeer)
allBeers := s.FindBeers()
for _, b := range allBeers {
if beer.Abv == b.Abv &&
beer.Brewery == b.Brewery &&
beer.Name == b.Name {
return fmt.Errorf("Beer already exists")
}
}
// TODO: Since delete function has not been implemented yet
// I think we can assume size of beers should always increase.
beer.ID = len(allBeers) + 1
if err := s.db.Write(collection, resource, beer); err != nil {
return err
}
}
return nil
}
// SaveReview insert reviews
func (s *StorageJSON) SaveReview(reviews ...model.Review) error {
for _, review := range reviews {
var resource = strconv.Itoa(review.ID)
var collection = strconv.Itoa(CollectionReview)
beerFound, err := s.FindBeer(model.Beer{ID: review.BeerID})
if err != nil {
return err
}
if len(beerFound) == 0 {
return fmt.Errorf("The beer selected for the review does not exist")
}
allReviews := s.FindReviews()
for _, r := range allReviews {
if review.BeerID == r.BeerID &&
review.FirstName == r.FirstName &&
review.LastName == r.LastName &&
review.Text == r.Text {
return fmt.Errorf("Review already exists")
}
}
// TODO: Since delete function has not been implemented yet
// I think we can assume size of reviews should always increase.
review.ID = len(allReviews) + 1
if err = s.db.Write(collection, resource, review); err != nil {
return err
}
}
return nil
}
// FindBeer locate full data set based on given criteria
func (s *StorageJSON) FindBeer(criteria model.Beer) ([]*model.Beer, error) {
var beers []*model.Beer
var beer model.Beer
var resource = strconv.Itoa(criteria.ID)
var collection = strconv.Itoa(CollectionBeer)
if err := s.db.Read(collection, resource, &beer); err != nil {
return beers, err
}
beers = append(beers, &beer)
return beers, nil
}
// FindReview locate full data set based on given criteria
func (s *StorageJSON) FindReview(criteria model.Review) ([]*model.Review, error) {
var reviews []*model.Review
var review model.Review
var resource = strconv.Itoa(criteria.ID)
var collection = strconv.Itoa(CollectionReview)
if err := s.db.Read(collection, resource, &review); err != nil {
return reviews, err
}
reviews = append(reviews, &review)
return reviews, nil
}
func (s *StorageJSON) FindBeers() []model.Beer {
var beers []model.Beer
var collection = strconv.Itoa(CollectionBeer)
records, err := s.db.ReadAll(collection)
if err != nil {
return beers
}
for _, b := range records {
var beer model.Beer
if err := json.Unmarshal([]byte(b), &beer); err != nil {
return beers
}
beers = append(beers, beer)
}
return beers
}
func (s *StorageJSON) FindReviews() []model.Review {
var reviews []model.Review
var collection = strconv.Itoa(CollectionReview)
records, err := s.db.ReadAll(collection)
if err != nil {
return reviews
}
for _, r := range records {
var review model.Review
if err := json.Unmarshal([]byte(r), &review); err != nil {
return reviews
}
reviews = append(reviews, review)
}
return reviews
}