var ( ErrRecordNotFound = errors.New("record not found") ErrEditConflict = errors.New("edit conflict") )
func (m MovieModel) Update(movie *Movie) error { query := `UPDATE movie SET title = $1, year = $2, runtime = $3, genres = $4, version = version + 1 WHERE id = $5 AND version = $6 RETURNING version` args := []any{ movie.Title, movie.Year, movie.Runtime, pq.Array(movie.Genres), movie.ID, movie.Version, // Add the expected 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 (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) }
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.Movie.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 } if input.Title != nil { movie.Title = *input.Title } if input.Year != nil { movie.Year = *input.Year } if input.Runtime != nil { movie.Runtime = *input.Runtime } if input.Genres != nil { movie.Genres = input.Genres // Note that we don't need to dereference a slice. } v := validator.New() if data.ValidateMovie(v, movie); !v.Valid() { app.failedValidationResponse(w, r, v.Errors) return } err = app.models.Movie.Update(movie) if err != nil { switch { case errors.Is(err, data.ErrEditConflict): app.editConflictResponse(w, r) default: app.serverErrorResponse(w, r, err) } return } err = app.writeJSON(w, http.StatusOK, envelope{"movie": movie}, nil) if err != nil { app.serverErrorResponse(w, r, err) } }
zzh@ZZHPC:~$ xargs -I % -P8 curl -X PATCH -d '{"runtime": "97 mins"}' "localhost:4000/v1/movies/4" < <(printf '%s\n' {1..8}) { "movie": { "id": 4, "title": "The Breakfast Club", "year": 1985, "runtime": "97 mins", "genres": [ "drama" ], "version": 3 } } { "movie": { "id": 4, "title": "The Breakfast Club", "year": 1985, "runtime": "97 mins", "genres": [ "drama" ], "version": 4 } } { "error": "unable to update the record due to an edit conflict, please try again" { } "error": "unable to update the record due to an edit conflict, please try again" } { "error": "unable to update the record due to an edit conflict, please try again" } { "movie": { "id": 4, "title": "The Breakfast Club", "year": 1985, "runtime": "97 mins", "genres": [ "drama" ], "version": 5 } } { "error": "unable to update the record due to an edit conflict, please try again" } { "movie": { "id": 4, "title": "The Breakfast Club", "year": 1985, "runtime": "97 mins", "genres": [ "drama" ], "version": 6 } }
-P max-procs, --max-procs=max-procs
Run up to max-procs processes at a time; the default is 1. If max-procs is 0, xargs will run as many processes as possible at a time.
标签:Chapter,Operations,nil,err,movie,app,CRUD,version,input From: https://www.cnblogs.com/zhangzhihui/p/18549794