|
|
|
@ -3,6 +3,8 @@ package data
|
|
|
|
import (
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"context"
|
|
|
|
"errors"
|
|
|
|
"errors"
|
|
|
|
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"log/slog"
|
|
|
|
"time"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
|
|
"git.runcible.io/learning/pulley/internal/database"
|
|
|
|
"git.runcible.io/learning/pulley/internal/database"
|
|
|
|
@ -31,6 +33,7 @@ type Movie struct {
|
|
|
|
|
|
|
|
|
|
|
|
type MovieModel struct {
|
|
|
|
type MovieModel struct {
|
|
|
|
db database.PgxIface
|
|
|
|
db database.PgxIface
|
|
|
|
|
|
|
|
logger *slog.Logger
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (m MovieModel) Insert(ctx context.Context, movie *Movie) error {
|
|
|
|
func (m MovieModel) Insert(ctx context.Context, movie *Movie) error {
|
|
|
|
@ -189,12 +192,19 @@ func (m MovieModel) GetAll(ctx context.Context, title string, genres []string, f
|
|
|
|
// example, the query term 'the' & 'club' will match rows which contain both lexemes
|
|
|
|
// example, the query term 'the' & 'club' will match rows which contain both lexemes
|
|
|
|
// 'the' and 'club'.
|
|
|
|
// 'the' and 'club'.
|
|
|
|
|
|
|
|
|
|
|
|
query := `
|
|
|
|
// query := `
|
|
|
|
|
|
|
|
// SELECT id, created_at, title, year, runtime, genres, version
|
|
|
|
|
|
|
|
// FROM movies
|
|
|
|
|
|
|
|
// WHERE (to_tsvector('simple', title) @@ plainto_tsquery('simple', $1) OR $1 = '')
|
|
|
|
|
|
|
|
// AND (genres @> $2 OR $2 = '{}')
|
|
|
|
|
|
|
|
// ORDER BY id`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
query := fmt.Sprintf(`
|
|
|
|
SELECT id, created_at, title, year, runtime, genres, version
|
|
|
|
SELECT id, created_at, title, year, runtime, genres, version
|
|
|
|
FROM movies
|
|
|
|
FROM movies
|
|
|
|
WHERE (to_tsvector('simple', title) @@ plainto_tsquery('simple', $1) OR $1 = '')
|
|
|
|
WHERE (to_tsvector('simple', title) @@ plainto_tsquery('simple', $1) OR $1 = '')
|
|
|
|
AND (genres @> $2 OR $2 = '{}')
|
|
|
|
AND (genres @> $2 OR $2 = '{}')
|
|
|
|
ORDER BY id`
|
|
|
|
ORDER BY %s %s`, filters.sortColumn(), filters.sortDirection())
|
|
|
|
|
|
|
|
|
|
|
|
// ctx want some timeout for queries. When used in the handler the context passed should
|
|
|
|
// ctx want some timeout for queries. When used in the handler the context passed should
|
|
|
|
// be the r.Context. Since cancel functions are inherited it will cancel on client
|
|
|
|
// be the r.Context. Since cancel functions are inherited it will cancel on client
|
|
|
|
@ -202,6 +212,8 @@ func (m MovieModel) GetAll(ctx context.Context, title string, genres []string, f
|
|
|
|
ctxTimeout, cancel := context.WithTimeout(ctx, 3*time.Second)
|
|
|
|
ctxTimeout, cancel := context.WithTimeout(ctx, 3*time.Second)
|
|
|
|
defer cancel()
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m.logger.Debug(query)
|
|
|
|
|
|
|
|
|
|
|
|
rows, err := m.db.Query(ctxTimeout, query, title, genres)
|
|
|
|
rows, err := m.db.Query(ctxTimeout, query, title, genres)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
return nil, err
|
|
|
|
|