From ce8dfb1522a98800903df1bd893cd3d0d324aba3 Mon Sep 17 00:00:00 2001 From: lbenedar Date: Wed, 18 Mar 2026 14:09:48 +0300 Subject: [PATCH] ch8.2 --- cmd/api/errors.go | 5 +++++ cmd/api/movies.go | 7 ++++++- internal/data/models.go | 1 + internal/data/movies.go | 15 +++++++++++++-- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/cmd/api/errors.go b/cmd/api/errors.go index ed507d6..ecd9c30 100644 --- a/cmd/api/errors.go +++ b/cmd/api/errors.go @@ -43,3 +43,8 @@ func (app *application) badRequestResponse(w http.ResponseWriter, r *http.Reques func (app *application) failedValidationResponse(w http.ResponseWriter, r *http.Request, errors map[string]string) { app.errorResponse(w, r, http.StatusUnprocessableEntity, errors) } + +func (app *application) editConflictResponse(w http.ResponseWriter, r *http.Request) { + message := "unable to update the record due to an edit conflict, please try again" + app.errorResponse(w, r, http.StatusConflict, message) +} diff --git a/cmd/api/movies.go b/cmd/api/movies.go index 81a171b..662bc79 100644 --- a/cmd/api/movies.go +++ b/cmd/api/movies.go @@ -127,7 +127,12 @@ func (app *application) updateMovieHandler(w http.ResponseWriter, r *http.Reques err = app.models.Movies.Update(movie) if err != nil { - app.serverErrorResponse(w, r, err) + switch { + case errors.Is(err, data.ErrEditConflict): + app.editConflictResponse(w, r) + default: + app.serverErrorResponse(w, r, err) + } return } diff --git a/internal/data/models.go b/internal/data/models.go index b549650..6106037 100644 --- a/internal/data/models.go +++ b/internal/data/models.go @@ -7,6 +7,7 @@ import ( var ( ErrRecordNotFound = errors.New("record not found") + ErrEditConflict = errors.New("edit conflict") ) type Models struct { diff --git a/internal/data/movies.go b/internal/data/movies.go index 8129ded..d55559c 100644 --- a/internal/data/movies.go +++ b/internal/data/movies.go @@ -70,7 +70,7 @@ func (m MovieModel) Update(movie *Movie) error { query := ` UPDATE movies SET title=$1, year=$2, runtime=$3, genres=$4, version = version + 1 - WHERE id = $5 + WHERE id = $5 AND version = $6 RETURNING version` args := []any{ @@ -79,9 +79,20 @@ func (m MovieModel) Update(movie *Movie) error { movie.Runtime, pq.Array(movie.Genres), movie.ID, + movie.Version, } - return m.DB.QueryRow(query, args...).Scan(&movie.Version) + err := m.DB.QueryRow(query, args...).Scan(&movie.Version) + if err != nil { + switch { + case errors.Is(err, sql.ErrNoRows): + return ErrEditConflict + default: + return err + } + } + + return nil } func (m MovieModel) Delete(id int64) error {