/
genresRepository.go
101 lines (82 loc) · 2.6 KB
/
genresRepository.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
package postgresrepository
import (
"context"
"errors"
"fmt"
"strings"
"github.com/Falokut/movies_service/internal/models"
_ "github.com/jackc/pgx/v5/stdlib"
"github.com/jmoiron/sqlx"
"github.com/opentracing/opentracing-go"
"github.com/sirupsen/logrus"
)
type GenresRepository struct {
db *sqlx.DB
logger *logrus.Logger
}
const (
moviesGenresTableName = "movies_genres"
genresTableName = "genres"
)
func NewGenresRepository(db *sqlx.DB, logger *logrus.Logger) *GenresRepository {
return &GenresRepository{db: db, logger: logger}
}
func (r *GenresRepository) GetGenres(ctx context.Context, movieId int32) (genres []string, err error) {
defer handleError(ctx, &err)
defer r.logError(err, "GetGenres")
query := fmt.Sprintf("SELECT name FROM %s JOIN %s ON genre_id=id WHERE movie_id=$1 ORDER BY id",
moviesGenresTableName, genresTableName)
err = r.db.SelectContext(ctx, &genres, query, movieId)
return
}
func (r *GenresRepository) GetAllGenres(ctx context.Context) (genres []models.Genre, err error) {
defer handleError(ctx, &err)
defer r.logError(err, "GetAllGenres")
query := fmt.Sprintf("SELECT * FROM %s ORDER BY id", genresTableName)
err = r.db.SelectContext(ctx, &genres, query)
return
}
func (r *GenresRepository) GetGenresForMovies(ctx context.Context, ids []string) (map[int32][]string, error) {
span, ctx := opentracing.StartSpanFromContext(ctx, "GenresRepository.GetGenresForMovies")
defer span.Finish()
var err error
defer span.SetTag("error", err != nil)
query := fmt.Sprintf("SELECT movie_id, ARRAY_AGG(name) FROM %s JOIN %s ON genre_id=id "+
"WHERE movie_id=ANY(ARRAY[%s]) GROUP BY movie_id",
moviesGenresTableName, genresTableName, strings.Join(ids, ","))
rows, err := r.db.QueryContext(ctx, query)
if err != nil {
r.logger.Errorf("error: %v query: %s", err, query)
return map[int32][]string{}, err
}
genres := make(map[int32][]string, len(ids))
for rows.Next() {
var id int32
var names string
rows.Scan(&id, &names)
genres[id] = strings.Split(strings.Trim(names, "{}"), ",")
}
return genres, nil
}
func (r *GenresRepository) logError(err error, functionName string) {
if err == nil {
return
}
var repoErr = &models.ServiceError{}
if errors.As(err, &repoErr) {
r.logger.WithFields(
logrus.Fields{
"error.function.name": functionName,
"error.msg": repoErr.Msg,
"error.code": repoErr.Code,
},
).Error("genres repository error occurred")
} else {
r.logger.WithFields(
logrus.Fields{
"error.function.name": functionName,
"error.msg": err.Error(),
},
).Error("genres repository error occurred")
}
}