Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
241 changes: 201 additions & 40 deletions databaseutil/databaseutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,40 +94,216 @@ func GetPasswordForUserWithEmailAddress(emailAddress string) ([]byte, error) {
return password, nil
}

func GetNote(id int64) (int64, int64, string, time.Time, error) {
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
}

type UserData struct {
Id int64
DisplayName string
}

func GetAllUserData() ([]*UserData, error) {
sqlQuery := `
SELECT id, author_id, content, creation_time FROM note
WHERE id = $1`
SELECT id, display_name FROM app_user`

rows, err := db.Query(sqlQuery, id)
rows, err := db.Query(sqlQuery)
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
var users []*UserData = make([]*UserData, 0, 10)

for rows.Next() {
if db_id >= 0 {
return -1, -1, "", time.Time{}, QueryResultContainedMultipleRowsError
user := &UserData{}
if err := rows.Scan(&user.Id, &user.DisplayName); err != nil {
return nil, err
}

if err := rows.Scan(&db_id, &authorId, &content, &creationTime); err != nil {
return -1, -1, "", time.Time{}, err
users = append(users, user)
}

return users, nil
}

type NoteData struct {
Id int64
AuthorId int64
Content string
CreationTime time.Time
}

type ExtendedNoteData struct {
Id int64
AuthorId int64
Content string
CreationTime time.Time
PublicationIssue int64
}

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 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(&note.Id, &note.AuthorId, &note.Content, &note.CreationTime, &note.PublicationIssue); err != nil {
return nil, err
}

notes = append(notes, note)
}

if db_id < 0 {
return -1, -1, "", time.Time{}, QueryResultContainedNoRowsError
return notes, nil
}

func GetNote(id int64) (*NoteData, error) {

sqlQuery := `
SELECT id, author_id, content, creation_time FROM note
WHERE id = $1`

rows, err := db.Query(sqlQuery, id)
if err != nil {
return nil, convertPostgresError(err)
}

return db_id, authorId, content, creationTime, nil
// return -1, -1, "", time.Time{}, nil
defer rows.Close()

notes, err := returnNotes(rows)
if err != nil {
return nil, err
}

if len(notes) > 1 {

return nil, QueryResultContainedMultipleRowsError
}

if len(notes) < 1 {
return nil, QueryResultContainedNoRowsError
}

return notes[0], nil
}

func DeleteNote(id int64) error {
Expand Down Expand Up @@ -201,37 +377,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(&note.Id, &note.AuthorId, &note.Content, &note.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"

Expand Down
37 changes: 18 additions & 19 deletions handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,10 @@ 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)
return
}

usersByIdJson, err := json.Marshal(usersById)
Expand Down Expand Up @@ -223,23 +221,24 @@ 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))

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
Expand Down
52 changes: 44 additions & 8 deletions services/noteservice/noteservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,56 @@ func StoreNewNote(
return nil
}

func GetNoteById(id int64) (*models.Note, error) {
db_id, authorid, content, creationTime, err := databaseutil.GetNote(id)
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: db_id,
AuthorId: models.UserId(authorid),
Content: content,
CreationTime: creationTime,
},
nil
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)

if err != nil {
return nil, err
}

return noteDateToNote(noteData), nil
}

func DeleteNoteById(id int64) error {
Expand Down
Loading