From c0cb65b61bd9d0585ddce3d14fdd97ee8d01daf7 Mon Sep 17 00:00:00 2001 From: G Date: Thu, 30 Aug 2018 10:37:05 -0700 Subject: [PATCH 1/2] you can update and delet note categories --- databaseutil/databaseutil.go | 90 +++++++++++++++++++++++++++++ handlers/handlers.go | 66 ++++++++++++++++++++- services/noteservice/noteservice.go | 39 +++++++++++-- 3 files changed, 189 insertions(+), 6 deletions(-) diff --git a/databaseutil/databaseutil.go b/databaseutil/databaseutil.go index 864d991..d005662 100644 --- a/databaseutil/databaseutil.go +++ b/databaseutil/databaseutil.go @@ -154,6 +154,96 @@ func GetAllUserData() ([]*UserData, error) { return users, nil } +// ================================== + +func UpdateNoteContent(id int64, content string) error { + sqlQuery := ` + UPDATE note SET content = ($2) WHERE id = ($1)` + + rows, err := db.Query(sqlQuery, id, content) + if err != nil { + return convertPostgresError(err) + } + defer rows.Close() + + if err := rows.Err(); err != nil { + return convertPostgresError(err) + } + + return nil + +} + +func UpdateNoteCategory(id int64, category string) error { + sqlQuery := ` + INSERT INTO note_to_category_relationship (note_id, type) + VALUES ($1, $2) + ON CONFLICT (note_id) DO UPDATE SET type = ($2)` + + rows, err := db.Query(sqlQuery, id, category) + if err != nil { + return convertPostgresError(err) + } + defer rows.Close() + + if err := rows.Err(); err != nil { + return convertPostgresError(err) + } + + return nil +} + +func DeleteNoteCategory(id int64) error { + sqlQuery := ` + DELETE FROM note_to_category_relationship + WHERE note_id = $1` + + rows, err := db.Query(sqlQuery, id) + if err != nil { + return convertPostgresError(err) + } + defer rows.Close() + + if err := rows.Err(); err != nil { + return convertPostgresError(err) + } + + return nil +} + +func GetNoteCategory(id int64) (string, error) { + sqlQuery := ` + SELECT type FROM note_to_category_relationship + WHERE note_id = $1` + + rows, err := db.Query(sqlQuery, id) + if err != nil { + return "", convertPostgresError(err) + } + defer rows.Close() + + var category string = "N/A" + for rows.Next() { + if category != "N/A" { + return "", QueryResultContainedMultipleRowsError + } + + if err := rows.Scan(&category); err != nil { + return "", err + } + } + + if category == "N/A" { + return "", QueryResultContainedNoRowsError + } + + return category, nil +} + +// INSERT INTO distributors (did, dname) +// VALUES (5, 'Gizmo Transglobal'), (6, 'Associated Computing, Inc') +// ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED.dname; + type NoteData struct { Id int64 AuthorId int64 diff --git a/handlers/handlers.go b/handlers/handlers.go index cdfab3e..7964202 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -355,8 +355,72 @@ func HandleNoteApiRequest( responseWriter.WriteHeader(http.StatusOK) + case http.MethodPut: + + type NoteForm struct { + Id int64 `json:"id"` + Content string `json:"content"` + Category string `json:"category"` + } + + noteForm := new(NoteForm) + + if err := json.NewDecoder(request.Body).Decode(noteForm); err != nil { + http.Error(responseWriter, err.Error(), http.StatusBadRequest) + return + } + + if noteForm.Id < 1 { + http.Error(responseWriter, "Invalid Note Id", http.StatusBadRequest) + return + } + + note, err := noteservice.GetNoteById(noteForm.Id) + if err != nil { + http.Error(responseWriter, err.Error(), http.StatusInternalServerError) + return + } + + if note.AuthorId != userId { + http.Error(responseWriter, "You can only edit notes of which you are the author", http.StatusUnauthorized) + return + } + + if len(strings.TrimSpace(noteForm.Content)) == 0 { + http.Error(responseWriter, "Note content cannot be empty or just whitespace", http.StatusBadRequest) + return + } + + if err := noteservice.UpdateContent(noteForm.Id, noteForm.Content); err != nil { + http.Error(responseWriter, err.Error(), http.StatusInternalServerError) + return + } + + if noteForm.Category != "" { + + category, err := models.DeserializeCategory(strings.ToLower(noteForm.Category)) + + if err != nil { + http.Error(responseWriter, err.Error(), http.StatusInternalServerError) + return + } + + if err := noteservice.UpdateCategory(noteForm.Id, category); err != nil { + http.Error(responseWriter, err.Error(), http.StatusInternalServerError) + return + } + + } else { + if err := noteservice.DeleteCategory(noteForm.Id); err != nil { + http.Error(responseWriter, err.Error(), http.StatusInternalServerError) + return + } + } + + responseWriter.WriteHeader(http.StatusOK) + default: - respondWithMethodNotAllowed(responseWriter, http.MethodGet, http.MethodPost, http.MethodDelete) + respondWithMethodNotAllowed(responseWriter, http.MethodGet, http.MethodPost, http.MethodDelete, http.MethodPut) } } diff --git a/services/noteservice/noteservice.go b/services/noteservice/noteservice.go index c3c05bc..82c1459 100644 --- a/services/noteservice/noteservice.go +++ b/services/noteservice/noteservice.go @@ -40,20 +40,19 @@ func GetAllPublishedNotes() ([]*models.Note, error) { var notes []*models.Note = make([]*models.Note, len(noteData), len(noteData)) for index, noteDatum := range noteData { - notes[index] = noteDateToNote(noteDatum) + notes[index] = noteDataToNote(noteDatum) } return notes, nil } -func noteDateToNote(noteDatum *databaseutil.NoteData) *models.Note { +func noteDataToNote(noteDatum *databaseutil.NoteData) *models.Note { return &models.Note{ Id: noteDatum.Id, AuthorId: models.UserId(noteDatum.AuthorId), Content: noteDatum.Content, CreationTime: noteDatum.CreationTime, } - } func GetMyUnpublishedNotes(userId models.UserId) ([]*models.Note, error) { @@ -66,7 +65,7 @@ func GetMyUnpublishedNotes(userId models.UserId) ([]*models.Note, error) { var notes []*models.Note = make([]*models.Note, len(noteData), len(noteData)) for index, noteDatum := range noteData { - notes[index] = noteDateToNote(noteDatum) + notes[index] = noteDataToNote(noteDatum) } return notes, nil @@ -79,13 +78,43 @@ func GetNoteById(id int64) (*models.Note, error) { return nil, err } - return noteDateToNote(noteData), nil + return noteDataToNote(noteData), nil } func DeleteNoteById(id int64) error { return databaseutil.DeleteNote(id) } +func UpdateContent(id int64, content string) error { + // TODO Do we allow content updates to published notes? + return databaseutil.UpdateNoteContent(id, content) +} + +func UpdateCategory(id int64, category models.Category) error { + // TODO Do we allow category updates to published notes? + return databaseutil.UpdateNoteCategory(id, category.String()) +} + +func DeleteCategory(id int64) error { + if _, err := GetCategory(id); err != nil { + if err == databaseutil.QueryResultContainedNoRowsError { + return nil + } + + return err + } + return databaseutil.DeleteNoteCategory(id) +} + +func GetCategory(id int64) (models.Category, error) { + categoryString, err := databaseutil.GetNoteCategory(id) + if err != nil { + return models.MARGINALIA, err + } + + return models.DeserializeCategory(categoryString) +} + func StoreNoteCategoryRelationship( note *models.Note, category models.Category, From 7a1a911bced216a0c74ae6bbe87f316970b12381 Mon Sep 17 00:00:00 2001 From: G Date: Thu, 30 Aug 2018 13:16:08 -0700 Subject: [PATCH 2/2] removed stale comments --- databaseutil/databaseutil.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/databaseutil/databaseutil.go b/databaseutil/databaseutil.go index d005662..e314ec7 100644 --- a/databaseutil/databaseutil.go +++ b/databaseutil/databaseutil.go @@ -240,10 +240,6 @@ func GetNoteCategory(id int64) (string, error) { return category, nil } -// INSERT INTO distributors (did, dname) -// VALUES (5, 'Gizmo Transglobal'), (6, 'Associated Computing, Inc') -// ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED.dname; - type NoteData struct { Id int64 AuthorId int64