# HG changeset patch # User Sascha L. Teichmann # Date 1543565747 -3600 # Node ID 286a3306f6bf98beedccfeaeb7f1f600e357877b # Parent 5e1218b5a123dabaacfd4791420e88c184f07c2f Import bulk review: Cleaned up input JSON document handling. Added proper error handling. diff -r 5e1218b5a123 -r 286a3306f6bf pkg/controllers/importqueue.go --- a/pkg/controllers/importqueue.go Thu Nov 29 12:09:01 2018 +0100 +++ b/pkg/controllers/importqueue.go Fri Nov 30 09:15:47 2018 +0100 @@ -66,15 +66,6 @@ DELETE FROM waterway.imports WHERE id = $1` ) -type Review struct { - ID int64 `json:"id"` - State string `json:"state"` -} - -func (r Review) String() string { - return fmt.Sprintf("%d %s", r.ID, r.State) -} - func toTextArray(txt string, allowed []string) *pgtype.TextArray { parts := strings.Split(txt, ",") var accepted []string @@ -344,17 +335,35 @@ ) func reviewImports( - _ interface{}, + reviews interface{}, req *http.Request, conn *sql.Conn, -) (jr JSONResult, err error) { - decoder := json.NewDecoder(req.Body) - var reviews []Review - decoder.Decode(&reviews) - for _, review := range reviews { - updateImport(req, conn, review.ID, review.State) +) (JSONResult, error) { + + rs := reviews.([]*models.Review) + + type reviewResult struct { + ID int64 `json:"id"` + Message string `json:"message,omitempty"` + Error string `json:"error,omitempty"` } - return + + results := make([]reviewResult, len(rs)) + + for i, rev := range rs { + msg, err := decideImport(req, conn, rev.ID, string(rev.State)) + var errString string + if err != nil { + errString = err.Error() + } + results[i] = reviewResult{ + ID: rev.ID, + Message: msg, + Error: errString, + } + } + + return JSONResult{Result: results}, nil } func reviewImport( @@ -366,15 +375,28 @@ vars := mux.Vars(req) id, _ := strconv.ParseInt(vars["id"], 10, 64) state := vars["state"] - return updateImport(req, conn, id, state) + + var msg string + if msg, err = decideImport(req, conn, id, state); err != nil { + return + } + + result := struct { + Message string `json:"message"` + }{ + Message: msg, + } + + jr = JSONResult{Result: &result} + return } -func updateImport( +func decideImport( req *http.Request, conn *sql.Conn, id int64, state string, -) (jr JSONResult, err error) { +) (message string, err error) { ctx := req.Context() var tx *sql.Tx if tx, err = conn.BeginTx(ctx, nil); err != nil { @@ -438,13 +460,8 @@ return } - result := struct { - Message string `json:"message"` - }{ - Message: fmt.Sprintf("Import #%d successfully changed to state '%s'.", - id, state), - } + message = fmt.Sprintf( + "Import #%d successfully changed to state '%s'.", id, state) - jr = JSONResult{Result: &result} return } diff -r 5e1218b5a123 -r 286a3306f6bf pkg/controllers/routes.go --- a/pkg/controllers/routes.go Thu Nov 29 12:09:01 2018 +0100 +++ b/pkg/controllers/routes.go Fri Nov 30 09:15:47 2018 +0100 @@ -183,6 +183,7 @@ })).Methods(http.MethodGet) api.Handle("/imports", waterwayAdmin(&JSONHandler{ + Input: func() interface{} { return []*models.Review{} }, Handle: reviewImports, })).Methods(http.MethodPatch) diff -r 5e1218b5a123 -r 286a3306f6bf pkg/models/import.go --- a/pkg/models/import.go Thu Nov 29 12:09:01 2018 +0100 +++ b/pkg/models/import.go Fri Nov 30 09:15:47 2018 +0100 @@ -15,6 +15,7 @@ import ( "encoding/json" + "errors" "time" ) @@ -36,8 +37,29 @@ Kind string `json:"kind"` Message string `json:"message"` } + + ReviewState string + + Review struct { + ID int64 `json:"id"` + State ReviewState `json:"state"` + } ) +var errInvalidReviewState = errors.New("state is wether 'accepted' nor 'declined'") + +func (rs *ReviewState) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + if s != "accepted" && s != "declined" { + return errInvalidReviewState + } + *rs = ReviewState(s) + return nil +} + func (it ImportTime) MarshalJSON() ([]byte, error) { return json.Marshal(it.Format("2006-01-02T15:04:05")) }