// Get retrieves the record based on the provided key. // func (goal *Goal) Get(c context.Context) (err error) { key := datastore.NewKey(c, "Goal", util.StringKey(goal.Name), 0, nil) err = datastore.Get(c, key, goal) if err != nil && err.Error() == "datastore: no such entity" { err = types.ErrorNoMatch } return }
// Delete deletes the record based on the provided key. // func (goal *Goal) Delete(c context.Context) (err error) { // TODO: need to check for existance before deleting. if NOT exists, then throw ErrorNoMatch error (err = ErrorNoMatch) if err = goal.Get(c); err == types.ErrorNoMatch { return } key := datastore.NewKey(c, "Goal", util.StringKey(goal.Name), 0, nil) err = datastore.Delete(c, key) return }
// Put saves the goal record to database. In this case to Google Appengine Datastore. If already exists, the record will be overwritten. func (goal *Goal) Put(c context.Context) error { // generate the key key := datastore.NewKey(c, "Goal", util.StringKey(goal.Name), 0, nil) // put the record into the database and capture the key key, err := datastore.Put(c, key, goal) if err != nil { return err } // read from database into the same variable if err = datastore.Get(c, key, goal); err != nil { return err } return err }
// HandleGoalPut handles the PUT operation on the Goal entity type. // Pass the goal string key in the URI // And pass the json body with all the fields of goal struct. // Pass all the fields. if a field is not changed, pass the unchanged value. Any missing fields will result in updating the database with the respective zero value, so Make sure you pass all the fields, even though the value is not changed. func HandleGoalPut(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) goal := model.Goal{} if err := json.NewDecoder(r.Body).Decode(&goal); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } params := mux.Vars(r) // if the goal name (string key) provided in the URI doesn't exist in database, then return goalSrc := model.Goal{} goalSrc.Name = params["goal"] if err := goalSrc.Get(c); err == types.ErrorNoMatch { http.Error(w, err.Error(), http.StatusBadRequest) return } else if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // if goal name from body has a value other than the actual goal name in db; i.e if goal name is being changed, dont allow if goal.Name != "" && util.StringKey(goal.Name) != params["goal"] { // TODO: Bug: changing the goal name to its equivalent string key is permitted. need to troubleshoot and fix so that any change is not allowed. http.Error(w, "cannot update key column - Goal Name", http.StatusBadRequest) return } // goal.ModifiedOn = time.Now() // update if err := goal.Put(c); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if err := json.NewEncoder(w).Encode(goal); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusCreated) }