From 7978bf8feb8ed8ce73780fafa0e907e068012513 Mon Sep 17 00:00:00 2001 From: G Date: Wed, 29 Aug 2018 11:37:33 -0700 Subject: [PATCH 1/5] more generic get notes --- databaseutil/databaseutil.go | 50 +++++++++++++++++++---------- services/noteservice/noteservice.go | 10 +++--- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/databaseutil/databaseutil.go b/databaseutil/databaseutil.go index 08f51d2..f430a72 100644 --- a/databaseutil/databaseutil.go +++ b/databaseutil/databaseutil.go @@ -94,7 +94,29 @@ func GetPasswordForUserWithEmailAddress(emailAddress string) ([]byte, error) { return password, nil } -func GetNote(id int64) (int64, int64, string, time.Time, error) { +type NoteData struct { + Id int64 + AuthorId int64 + Content string + CreationTime time.Time +} + +func returnNotes(rows *sql.Rows) ([]*NoteData, error) { + var notes []*NoteData = make([]*NoteData, 0, 10) + + for rows.Next() { + note := &NoteData{} + if err := rows.Scan(¬e.Id, ¬e.AuthorId, ¬e.Content, ¬e.CreationTime); err != nil { + return nil, err + } + + notes = append(notes, note) + } + + return notes, nil +} + +func GetNote(id int64) (*NoteData, error) { sqlQuery := ` SELECT id, author_id, content, creation_time FROM note @@ -102,32 +124,26 @@ func GetNote(id int64) (int64, int64, string, time.Time, error) { rows, err := db.Query(sqlQuery, id) if err != nil { - return -1, -1, "", time.Time{}, convertPostgresError(err) + return nil, convertPostgresError(err) } defer rows.Close() - var db_id int64 = -1 - var authorId int64 = -1 - var content string - var creationTime time.Time + notes, err := returnNotes(rows) + if err != nil { + return nil, err + } - for rows.Next() { - if db_id >= 0 { - return -1, -1, "", time.Time{}, QueryResultContainedMultipleRowsError - } + if len(notes) > 1 { - if err := rows.Scan(&db_id, &authorId, &content, &creationTime); err != nil { - return -1, -1, "", time.Time{}, err - } + return nil, QueryResultContainedMultipleRowsError } - if db_id < 0 { - return -1, -1, "", time.Time{}, QueryResultContainedNoRowsError + if len(notes) < 1 { + return nil, QueryResultContainedNoRowsError } - return db_id, authorId, content, creationTime, nil - // return -1, -1, "", time.Time{}, nil + return notes[0], nil } func DeleteNote(id int64) error { diff --git a/services/noteservice/noteservice.go b/services/noteservice/noteservice.go index 62c7bfc..12df5b2 100644 --- a/services/noteservice/noteservice.go +++ b/services/noteservice/noteservice.go @@ -31,17 +31,17 @@ func StoreNewNote( } func GetNoteById(id int64) (*models.Note, error) { - db_id, authorid, content, creationTime, err := databaseutil.GetNote(id) + noteData, err := databaseutil.GetNote(id) if err != nil { return nil, err } return &models.Note{ - Id: db_id, - AuthorId: models.UserId(authorid), - Content: content, - CreationTime: creationTime, + Id: noteData.Id, + AuthorId: models.UserId(noteData.AuthorId), + Content: noteData.Content, + CreationTime: noteData.CreationTime, }, nil } From 0384a7b3b044ca25c351b794158de99aceb64daf Mon Sep 17 00:00:00 2001 From: G Date: Wed, 29 Aug 2018 12:14:34 -0700 Subject: [PATCH 2/5] notes pages prints all published notes and all of my unpublished notes --- databaseutil/databaseutil.go | 45 ++++++++++++++++++++++++++ handlers/handlers.go | 41 +++++++++++++++-------- services/noteservice/noteservice.go | 50 +++++++++++++++++++++++++---- 3 files changed, 116 insertions(+), 20 deletions(-) diff --git a/databaseutil/databaseutil.go b/databaseutil/databaseutil.go index f430a72..7e76cd9 100644 --- a/databaseutil/databaseutil.go +++ b/databaseutil/databaseutil.go @@ -116,6 +116,51 @@ func returnNotes(rows *sql.Rows) ([]*NoteData, error) { return notes, nil } +func GetMyUnpublishedNotes(userId int64) ([]*NoteData, error) { + + sqlQuery := ` + SELECT id, author_id, content, creation_time FROM note + LEFT OUTER JOIN note_to_publication_relationship AS note2pub + ON note.id = note2pub.note_id + WHERE note2pub.note_id is NULL AND note.author_id = $1` + + rows, err := db.Query(sqlQuery, userId) + if err != nil { + return nil, convertPostgresError(err) + } + + defer rows.Close() + + notes, err := returnNotes(rows) + if err != nil { + return nil, err + } + + return notes, nil +} + +func GetAllPublishedNotes() ([]*NoteData, error) { + + sqlQuery := ` + SELECT id, author_id, content, creation_time FROM note + INNER JOIN note_to_publication_relationship AS note2pub + ON note.id = note2pub.note_id` + + rows, err := db.Query(sqlQuery) + if err != nil { + return nil, convertPostgresError(err) + } + + defer rows.Close() + + notes, err := returnNotes(rows) + if err != nil { + return nil, err + } + + return notes, nil +} + func GetNote(id int64) (*NoteData, error) { sqlQuery := ` diff --git a/handlers/handlers.go b/handlers/handlers.go index 523efc4..6b0bfe6 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -223,23 +223,38 @@ func HandleNoteApiRequest( ) { switch request.Method { case http.MethodGet: - note1 := &models.Note{ - Id: 1, - AuthorId: 1, - Content: "This is an example note.", - CreationTime: time.Now().Add(-oneWeek).UTC(), - } - note2 := &models.Note{ - Id: 2, - AuthorId: 2, - Content: "What is this site for?", - CreationTime: time.Now().Add(-60 * 12).UTC(), + publishedNotes, err := noteservice.GetAllPublishedNotes() + if err != nil { + http.Error(responseWriter, err.Error(), http.StatusInternalServerError) + return } - notes := [2]*models.Note{note1, note2} + fmt.Println("number of published notes") + fmt.Println(len(publishedNotes)) + + myUnpublishedNotes, err := noteservice.GetMyUnpublishedNotes(userId) + + fmt.Println("number of unpublished notes") + fmt.Println(len(myUnpublishedNotes)) + + // note1 := &models.Note{ + // Id: 1, + // AuthorId: 1, + // Content: "This is an example note.", + // CreationTime: time.Now().Add(-oneWeek).UTC(), + // } + + // note2 := &models.Note{ + // Id: 2, + // AuthorId: 2, + // Content: "What is this site for?", + // CreationTime: time.Now().Add(-60 * 12).UTC(), + // } + + allNotes := append(publishedNotes, myUnpublishedNotes...) - notesInJson, err := json.Marshal(notes) + notesInJson, err := json.Marshal(allNotes) if err != nil { http.Error(responseWriter, err.Error(), http.StatusInternalServerError) return diff --git a/services/noteservice/noteservice.go b/services/noteservice/noteservice.go index 12df5b2..c3c05bc 100644 --- a/services/noteservice/noteservice.go +++ b/services/noteservice/noteservice.go @@ -30,6 +30,48 @@ func StoreNewNote( return nil } +func GetAllPublishedNotes() ([]*models.Note, error) { + + noteData, err := databaseutil.GetAllPublishedNotes() + if err != nil { + return nil, err + } + + var notes []*models.Note = make([]*models.Note, len(noteData), len(noteData)) + + for index, noteDatum := range noteData { + notes[index] = noteDateToNote(noteDatum) + } + + return notes, nil +} + +func noteDateToNote(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) { + + noteData, err := databaseutil.GetMyUnpublishedNotes(int64(userId)) + if err != nil { + return nil, err + } + + var notes []*models.Note = make([]*models.Note, len(noteData), len(noteData)) + + for index, noteDatum := range noteData { + notes[index] = noteDateToNote(noteDatum) + } + + return notes, nil +} + func GetNoteById(id int64) (*models.Note, error) { noteData, err := databaseutil.GetNote(id) @@ -37,13 +79,7 @@ func GetNoteById(id int64) (*models.Note, error) { return nil, err } - return &models.Note{ - Id: noteData.Id, - AuthorId: models.UserId(noteData.AuthorId), - Content: noteData.Content, - CreationTime: noteData.CreationTime, - }, - nil + return noteDateToNote(noteData), nil } func DeleteNoteById(id int64) error { From ca20ca93601c6808823e9bfd67d17ae63b258a9f Mon Sep 17 00:00:00 2001 From: G Date: Wed, 29 Aug 2018 12:31:46 -0700 Subject: [PATCH 3/5] real users are now displayed --- databaseutil/databaseutil.go | 97 +++++++++++++++++++---------- handlers/handlers.go | 16 +++-- services/userservice/userservice.go | 14 +++++ 3 files changed, 88 insertions(+), 39 deletions(-) diff --git a/databaseutil/databaseutil.go b/databaseutil/databaseutil.go index 7e76cd9..8f2afc9 100644 --- a/databaseutil/databaseutil.go +++ b/databaseutil/databaseutil.go @@ -94,26 +94,70 @@ func GetPasswordForUserWithEmailAddress(emailAddress string) ([]byte, error) { return password, nil } -type NoteData struct { - Id int64 - AuthorId int64 - Content string - CreationTime time.Time +func GetIdForUserWithEmailAddress(emailAddress string) (int64, error) { + sqlQuery := ` + SELECT id FROM app_user + WHERE email_address = $1` + + rows, err := db.Query(sqlQuery, emailAddress) + if err != nil { + return 0, convertPostgresError(err) + } + defer rows.Close() + + var userId int64 + for rows.Next() { + if userId != 0 { + return 0, QueryResultContainedMultipleRowsError + } + + if err := rows.Scan(&userId); err != nil { + return 0, err + } + } + + if userId == 0 { + return 0, QueryResultContainedNoRowsError + } + + return userId, nil } -func returnNotes(rows *sql.Rows) ([]*NoteData, error) { - var notes []*NoteData = make([]*NoteData, 0, 10) +type UserData struct { + Id int64 + DisplayName string +} + +func GetAllUserData() ([]*UserData, error) { + sqlQuery := ` + SELECT id, display_name FROM app_user` + + rows, err := db.Query(sqlQuery) + if err != nil { + return nil, convertPostgresError(err) + } + + defer rows.Close() + + var users []*UserData = make([]*UserData, 0, 10) for rows.Next() { - note := &NoteData{} - if err := rows.Scan(¬e.Id, ¬e.AuthorId, ¬e.Content, ¬e.CreationTime); err != nil { + user := &UserData{} + if err := rows.Scan(&user.Id, &user.DisplayName); err != nil { return nil, err } - notes = append(notes, note) + users = append(users, user) } - return notes, nil + return users, nil +} + +type NoteData struct { + Id int64 + AuthorId int64 + Content string + CreationTime time.Time } func GetMyUnpublishedNotes(userId int64) ([]*NoteData, error) { @@ -262,37 +306,22 @@ func StoreNoteCategoryRelationship(noteId int64, category string) error { return nil } -func GetIdForUserWithEmailAddress(emailAddress string) (int64, error) { - sqlQuery := ` - SELECT id FROM app_user - WHERE email_address = $1` - - rows, err := db.Query(sqlQuery, emailAddress) - if err != nil { - return 0, convertPostgresError(err) - } - defer rows.Close() +// PRIVATE +func returnNotes(rows *sql.Rows) ([]*NoteData, error) { + var notes []*NoteData = make([]*NoteData, 0, 10) - var userId int64 for rows.Next() { - if userId != 0 { - return 0, QueryResultContainedMultipleRowsError - } - - if err := rows.Scan(&userId); err != nil { - return 0, err + note := &NoteData{} + if err := rows.Scan(¬e.Id, ¬e.AuthorId, ¬e.Content, ¬e.CreationTime); err != nil { + return nil, err } - } - if userId == 0 { - return 0, QueryResultContainedNoRowsError + notes = append(notes, note) } - return userId, nil + return notes, nil } -// PRIVATE - func convertPostgresError(err error) error { const uniqueConstraintErrorCode = "23505" diff --git a/handlers/handlers.go b/handlers/handlers.go index 6b0bfe6..4e8d07e 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -110,12 +110,18 @@ func HandleUserApiRequest( return } - user1 := models.User{"Adrian"} - user2 := models.User{"Evan"} + // user1 := models.User{"Adrian"} + // user2 := models.User{"Evan"} - usersById := map[models.UserId]models.User{ - 1: user1, - 2: user2, + // usersById := map[models.UserId]models.User{ + // 1: user1, + // 2: user2, + // } + + usersById, err := userservice.GetUsersById() + if err != nil { + http.Error(responseWriter, err.Error(), http.StatusInternalServerError) + return } usersByIdJson, err := json.Marshal(usersById) diff --git a/services/userservice/userservice.go b/services/userservice/userservice.go index fab7356..cf2e2a6 100644 --- a/services/userservice/userservice.go +++ b/services/userservice/userservice.go @@ -46,6 +46,20 @@ func StoreNewUser( return nil } +func GetUsersById() (map[models.UserId]*models.User, error) { + userData, err := databaseutil.GetAllUserData() + if err != nil { + return nil, err + } + + usersById := make(map[models.UserId]*models.User) + for _, userDatum := range userData { + usersById[models.UserId(userDatum.Id)] = &models.User{DisplayName: userDatum.DisplayName} + } + + return usersById, nil +} + func AuthenticateUserCredentials(emailAddress *models.EmailAddress, password string) error { storedHashedPassword, err := databaseutil.GetPasswordForUserWithEmailAddress(emailAddress.String()) if err != nil { From c026bc40f3d75cc5ef97fa1a275286c429a69671 Mon Sep 17 00:00:00 2001 From: G Date: Wed, 29 Aug 2018 12:32:23 -0700 Subject: [PATCH 4/5] removed commented out code --- handlers/handlers.go | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/handlers/handlers.go b/handlers/handlers.go index 4e8d07e..9acbfe3 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -110,14 +110,6 @@ func HandleUserApiRequest( return } - // user1 := models.User{"Adrian"} - // user2 := models.User{"Evan"} - - // usersById := map[models.UserId]models.User{ - // 1: user1, - // 2: user2, - // } - usersById, err := userservice.GetUsersById() if err != nil { http.Error(responseWriter, err.Error(), http.StatusInternalServerError) @@ -244,20 +236,6 @@ func HandleNoteApiRequest( fmt.Println("number of unpublished notes") fmt.Println(len(myUnpublishedNotes)) - // note1 := &models.Note{ - // Id: 1, - // AuthorId: 1, - // Content: "This is an example note.", - // CreationTime: time.Now().Add(-oneWeek).UTC(), - // } - - // note2 := &models.Note{ - // Id: 2, - // AuthorId: 2, - // Content: "What is this site for?", - // CreationTime: time.Now().Add(-60 * 12).UTC(), - // } - allNotes := append(publishedNotes, myUnpublishedNotes...) notesInJson, err := json.Marshal(allNotes) From d48310f5cd44854e257be79b49ed4361358f2260 Mon Sep 17 00:00:00 2001 From: G Date: Thu, 30 Aug 2018 14:26:04 -0700 Subject: [PATCH 5/5] added db code to get all properly categorized code --- databaseutil/databaseutil.go | 71 ++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/databaseutil/databaseutil.go b/databaseutil/databaseutil.go index 8f2afc9..d4a3ed1 100644 --- a/databaseutil/databaseutil.go +++ b/databaseutil/databaseutil.go @@ -160,6 +160,14 @@ type NoteData struct { CreationTime time.Time } +type ExtendedNoteData struct { + Id int64 + AuthorId int64 + Content string + CreationTime time.Time + PublicationIssue int64 +} + func GetMyUnpublishedNotes(userId int64) ([]*NoteData, error) { sqlQuery := ` @@ -205,6 +213,69 @@ func GetAllPublishedNotes() ([]*NoteData, error) { return notes, nil } +func GetAllNotesPublishedInIssueSmallerThanOrEqualTo(publictionIssueNumber int) ([]*ExtendedNoteData, error) { + sqlQuery := ` + SELECT + note.id, + note.author_id, + note.content, + note.creation_time, + filtered_pubs.rank AS publication_issue + FROM (SELECT *, + Rank() + OVER( + partition BY pub.author_id + ORDER BY pub.creation_time) + FROM publication AS pub) filtered_pubs + INNER JOIN note_to_publication_relationship AS note2pub + ON note2pub.publication_id = filtered_pubs.id + INNER JOIN note + ON note.id = note2pub.note_id + WHERE rank <= ($1)` + + // sqlQuery2 := ` + // SELECT + // note.id, + // note.author_id, + // note.content, + // note.creation_time, + // note2cat.type AS category, + // filtered_pubs.rank AS publication_issue + // FROM (SELECT *, + // Rank() + // OVER( + // partition BY pub.author_id + // ORDER BY pub.creation_time) + // FROM publication AS pub) filtered_pubs + // INNER JOIN note_to_publication_relationship AS note2pub + // ON note2pub.publication_id = filtered_pubs.id + // INNER JOIN note + // ON note.id = note2pub.note_id + // LEFT OUTER JOIN note_to_category_relationship AS note2cat + // ON note.id = note2cat.note_id + // WHERE rank <= ($1)` + + rows, err := db.Query(sqlQuery, publictionIssueNumber) + if err != nil { + return nil, convertPostgresError(err) + } + + defer rows.Close() + + var notes []*NoteData = make([]*NoteData, 0, 10) + + for rows.Next() { + note := &ExtendedNoteData{} + if err := rows.Scan(¬e.Id, ¬e.AuthorId, ¬e.Content, ¬e.CreationTime, ¬e.PublicationIssue); err != nil { + return nil, err + } + + notes = append(notes, note) + } + + return notes, nil +} + func GetNote(id int64) (*NoteData, error) { sqlQuery := `