update a command through the api

This commit is contained in:
lyx0 2022-08-17 20:57:25 +02:00
parent 8e0a307b11
commit 5e3ee66bae
5 changed files with 103 additions and 3 deletions

View file

@ -73,6 +73,71 @@ func (app *application) createCommandHandler(w http.ResponseWriter, r *http.Requ
} }
} }
func (app *application) updateCommandHandler(w http.ResponseWriter, r *http.Request) {
name, err := app.readCommandNameParam(r)
if err != nil {
app.notFoundResponse(w, r)
return
}
command, err := app.Models.Commands.Get(name)
if err != nil {
switch {
case errors.Is(err, data.ErrRecordNotFound):
app.notFoundResponse(w, r)
default:
app.serverErrorResponse(w, r, err)
}
return
}
var input struct {
Name *string `json:"name"`
Text *string `json:"text"`
Category *string `json:"category"`
Level *int `json:"level"`
}
err = app.readJSON(w, r, &input)
if err != nil {
app.badRequestResponse(w, r, err)
return
}
// There is a name since we successfully queried the database for
// a command, so no need to check != nil.
command.Name = *input.Name
if input.Text != nil {
command.Text = *input.Text
}
if input.Category != nil {
command.Category = *input.Category
}
if input.Level != nil {
command.Level = *input.Level
}
err = app.Models.Commands.Update(command)
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{"command": command}, nil)
if err != nil {
app.serverErrorResponse(w, r, err)
}
}
func (app *application) deleteCommandHandler(w http.ResponseWriter, r *http.Request) { func (app *application) deleteCommandHandler(w http.ResponseWriter, r *http.Request) {
name, err := app.readCommandNameParam(r) name, err := app.readCommandNameParam(r)
if err != nil { if err != nil {

View file

@ -38,3 +38,8 @@ func (app *application) notFoundResponse(w http.ResponseWriter, r *http.Request)
message := "the requested resource could not be found" message := "the requested resource could not be found"
app.errorResponse(w, r, http.StatusNotFound, message) app.errorResponse(w, r, http.StatusNotFound, message)
} }
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)
}

View file

@ -11,6 +11,7 @@ func (app *application) routes() *httprouter.Router {
router.HandlerFunc(http.MethodGet, "/v1/commands/:name", app.showCommandHandler) router.HandlerFunc(http.MethodGet, "/v1/commands/:name", app.showCommandHandler)
router.HandlerFunc(http.MethodPost, "/v1/commands", app.createCommandHandler) router.HandlerFunc(http.MethodPost, "/v1/commands", app.createCommandHandler)
router.HandlerFunc(http.MethodPatch, "/v1/commands/:name", app.updateCommandHandler)
router.HandlerFunc(http.MethodDelete, "/v1/commands/:name", app.deleteCommandHandler) router.HandlerFunc(http.MethodDelete, "/v1/commands/:name", app.deleteCommandHandler)
return router return router
} }

View file

@ -8,9 +8,9 @@ import (
type Command struct { type Command struct {
ID int `json:"id"` ID int `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Text string `json:"text"` Text string `json:"text,omitempty"`
Category string `json:"category"` Category string `json:"category,omitempty"`
Level int `json:"level"` Level int `json:"level,omitempty"`
} }
type CommandModel struct { type CommandModel struct {
@ -46,6 +46,33 @@ func (c CommandModel) Get(name string) (*Command, error) {
return &command, nil return &command, nil
} }
func (c CommandModel) Update(command *Command) error {
query := `
UPDATE commands
SET text = $2, category = $3, level = $4
WHERE name = $1
RETURNING id`
args := []interface{}{
command.Name,
command.Text,
command.Category,
command.Level,
}
err := c.DB.QueryRow(query, args...).Scan(&command.ID)
if err != nil {
switch {
case errors.Is(err, sql.ErrNoRows):
return ErrEditConflict
default:
return err
}
}
return nil
}
// SetCategory queries the database for an entry with the provided name, // SetCategory queries the database for an entry with the provided name,
// if there is one it updates the categories level with the provided level. // if there is one it updates the categories level with the provided level.
func (c CommandModel) SetCategory(name string, category string) error { func (c CommandModel) SetCategory(name string, category string) error {

View file

@ -8,6 +8,7 @@ import (
var ( var (
ErrRecordNotFound = errors.New("record not found") ErrRecordNotFound = errors.New("record not found")
ErrChannelRecordAlreadyExists = errors.New("channel already in database") ErrChannelRecordAlreadyExists = errors.New("channel already in database")
ErrEditConflict = errors.New("edit conflict")
ErrCommandRecordAlreadyExists = errors.New("command already exists") ErrCommandRecordAlreadyExists = errors.New("command already exists")
ErrUserAlreadyExists = errors.New("user already in database") ErrUserAlreadyExists = errors.New("user already in database")
) )
@ -31,6 +32,7 @@ type Models struct {
Commands interface { Commands interface {
Get(name string) (*Command, error) Get(name string) (*Command, error)
Insert(command *Command) error Insert(command *Command) error
Update(command *Command) error
SetLevel(name string, level int) error SetLevel(name string, level int) error
SetCategory(name, category string) error SetCategory(name, category string) error
Delete(name string) error Delete(name string) error