-
Notifications
You must be signed in to change notification settings - Fork 0
/
movie.go
121 lines (102 loc) · 3.31 KB
/
movie.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
package services
import (
"time"
"github.com/rwx-yxu/greenlight/internal/brokers"
"github.com/rwx-yxu/greenlight/internal/filter"
"github.com/rwx-yxu/greenlight/internal/models"
"github.com/rwx-yxu/greenlight/internal/validator"
)
type movie struct {
Broker brokers.MovieReadWriteDeleter
}
type MovieValidator interface {
Validate(input models.Movie) validator.Validator
}
type MovieReader interface {
FindByID(id int64) (*models.Movie, error)
FindAll(title string, genres []string, filters filter.Filter) ([]*models.Movie, filter.Metadata, error)
}
type MovieWriter interface {
Add(m *models.Movie) (*validator.Validator, error)
Edit(m *models.Movie) (*validator.Validator, error)
}
type MovieDeleter interface {
RemoveByID(id int64) error
}
type MovieReadWriteDeleter interface {
MovieValidator
MovieDeleter
MovieWriter
MovieReader
}
func NewMovie(b brokers.MovieReadWriteDeleter) MovieReadWriteDeleter {
return &movie{
Broker: b,
}
}
func (movie) Validate(input models.Movie) validator.Validator {
// Initialize a new Validator instance.
v := validator.New()
// Use the Check() method to execute our validation checks. This will add the
// provided key and error message to the errors map if the check does not evaluate
// to true. For example, in the first line here we "check that the title is not
// equal to the empty string". In the second, we "check that the length of the title
// is less than or equal to 500 bytes" and so on.
v.Check(input.Title != "", "title", "must be provided")
v.Check(len(input.Title) <= 500, "title", "must not be more than 500 bytes long")
v.Check(input.Year != 0, "year", "must be provided")
v.Check(input.Year >= 1888, "year", "must be greater than 1888")
v.Check(input.Year <= int32(time.Now().Year()), "year", "must not be in the future")
v.Check(input.Runtime != 0, "runtime", "must be provided")
v.Check(input.Runtime > 0, "runtime", "must be a positive integer")
v.Check(input.Genres != nil, "genres", "must be provided")
v.Check(len(input.Genres) >= 1, "genres", "must contain at least 1 genre")
v.Check(len(input.Genres) <= 5, "genres", "must not contain more than 5 genres")
// Note that we're using the Unique helper in the line below to check that all
// values in the input.Genres slice are unique.
v.Check(validator.Unique(input.Genres), "genres", "must not contain duplicate values")
return *v
}
func (m movie) FindByID(id int64) (*models.Movie, error) {
movie, err := m.Broker.GetByID(id)
if err != nil {
return nil, err
}
return movie, nil
}
func (m movie) Add(movie *models.Movie) (*validator.Validator, error) {
v := m.Validate(*movie)
if !v.Valid() {
return &v, nil
}
err := m.Broker.Insert(movie)
if err != nil {
return nil, err
}
return nil, nil
}
func (m movie) Edit(movie *models.Movie) (*validator.Validator, error) {
v := m.Validate(*movie)
if !v.Valid() {
return &v, nil
}
err := m.Broker.Update(movie)
if err != nil {
return nil, err
}
return nil, nil
}
func (m movie) RemoveByID(id int64) error {
err := m.Broker.DeleteByID(id)
if err != nil {
return err
}
return nil
}
func (m movie) FindAll(title string, genres []string, f filter.Filter) ([]*models.Movie, filter.Metadata, error) {
movies, metadata, err := m.Broker.GetAll(title, genres, f)
if err != nil {
return nil, filter.Metadata{}, err
}
return movies, metadata, nil
}