From 63f6d49221940165d1c0723aaddd09cf3ef1859a Mon Sep 17 00:00:00 2001 From: lbenedar Date: Wed, 18 Mar 2026 13:16:06 +0300 Subject: [PATCH] ch7.4 --- cmd/api/movies.go | 55 ++++++++++++++++++++++++++++++++++++++++- cmd/api/routes.go | 1 + internal/data/movies.go | 16 +++++++++++- 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/cmd/api/movies.go b/cmd/api/movies.go index d874c99..dd7cc5c 100644 --- a/cmd/api/movies.go +++ b/cmd/api/movies.go @@ -71,7 +71,60 @@ func (app *application) showMovieHandler(w http.ResponseWriter, r *http.Request) err = app.writeJSON(w, http.StatusOK, envelope{"movie": movie}, nil) if err != nil { - app.logger.Print(err) + app.serverErrorResponse(w, r, err) + } +} + +func (app *application) updateMovieHandler(w http.ResponseWriter, r *http.Request) { + id, err := app.readIDParam(r) + if err != nil { + app.notFoundResponse(w, r) + return + } + + movie, err := app.models.Movies.Get(id) + if err != nil { + switch { + case errors.Is(err, data.ErrRecordNotFound): + app.notFoundResponse(w, r) + default: + app.serverErrorResponse(w, r, err) + } + return + } + + var input struct { + Title string `json:"title"` + Year int32 `json:"year"` + Runtime data.Runtime `json:"runtime"` + Genres []string `json:"genres"` + } + + err = app.readJSON(w, r, &input) + if err != nil { + app.badRequestResponse(w, r, err) + return + } + + movie.Title = input.Title + movie.Year = input.Year + movie.Runtime = input.Runtime + movie.Genres = input.Genres + + v := validator.New() + if data.ValidateMovie(v, movie); !v.Valid() { + app.failedValidationResponse(w, r, v.Errors) + return + } + + err = app.models.Movies.Update(movie) + if err != nil { + app.serverErrorResponse(w, r, err) + return + } + + err = app.writeJSON(w, http.StatusOK, envelope{"movie": movie}, nil) + if err != nil { app.serverErrorResponse(w, r, err) } } diff --git a/cmd/api/routes.go b/cmd/api/routes.go index d09bd9b..40121df 100644 --- a/cmd/api/routes.go +++ b/cmd/api/routes.go @@ -15,6 +15,7 @@ func (app *application) routes() *httprouter.Router { router.HandlerFunc(http.MethodGet, "/v1/healthcheck", app.healthcheckHandler) router.HandlerFunc(http.MethodPost, "/v1/movies", app.createMovieHandler) router.HandlerFunc(http.MethodGet, "/v1/movies/:id", app.showMovieHandler) + router.HandlerFunc(http.MethodPut, "/v1/movies/:id", app.updateMovieHandler) return router } diff --git a/internal/data/movies.go b/internal/data/movies.go index 577a587..1630fc5 100644 --- a/internal/data/movies.go +++ b/internal/data/movies.go @@ -67,7 +67,21 @@ func (m MovieModel) Get(id int64) (*Movie, error) { } func (m MovieModel) Update(movie *Movie) error { - return nil + query := ` + UPDATE movies + SET title=$1, year=$2, runtime=$3, genres=$4, version = version + 1 + WHERE id = $5 + RETURNING version` + + args := []any{ + movie.Title, + movie.Year, + movie.Runtime, + pq.Array(movie.Genres), + movie.ID, + } + + return m.DB.QueryRow(query, args...).Scan(&movie.Version) } func (m MovieModel) Delete(id int64) error {