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
71 changes: 71 additions & 0 deletions databaseutil/databaseutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package databaseutil
import (
"database/sql"
"errors"
"strconv"
"time"

"github.com/lib/pq"
Expand Down Expand Up @@ -306,6 +307,76 @@ func StoreNoteCategoryRelationship(noteId int64, category string) error {
return nil
}

func StoreNewPublication(authorId int64, creationTime time.Time) (int64, error) {
sqlQuery := `
INSERT INTO publication (author_id, creation_time)
VALUES ($1, $2)
RETURNING id`

rows, err := db.Query(sqlQuery, authorId, creationTime)
if err != nil {
return -1, convertPostgresError(err)
}
defer rows.Close()

var lastInsertId int64
for rows.Next() {

if lastInsertId != 0 {
return -1, QueryResultContainedMultipleRowsError
}

if err := rows.Scan(&lastInsertId); err != nil {
return -1, convertPostgresError(err)
}
}

if lastInsertId == 0 {
return -1, QueryResultContainedNoRowsError
}

if err := rows.Err(); err != nil {
return -1, convertPostgresError(err)
}

return lastInsertId, nil

}

func StorePublicationNoteRelationship(publication_id int64, noteIds []int64) error {
sqlQuery := `
INSERT INTO note_to_publication_relationship (publication_id, note_id)
VALUES ($1, $2)`

values := make([]interface{}, len(noteIds)*2, len(noteIds)*2)
values[0] = publication_id
values[1] = noteIds[0]

for index, noteId := range noteIds {
if index == 0 {
continue
}
sqlQuery += ", ($" + strconv.Itoa(2*index+1) + ", $" + strconv.Itoa((2*index)+2) + ")"
values[2*index] = publication_id
values[(2*index)+1] = noteId
}

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

if err := rows.Err(); err != nil {
return convertPostgresError(err)
}

return nil

}

// -----------------------------------------------------------------------

// PRIVATE
func returnNotes(rows *sql.Rows) ([]*NoteData, error) {
var notes []*NoteData = make([]*NoteData, 0, 10)
Expand Down
37 changes: 37 additions & 0 deletions handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/atmiguel/cerealnotes/models"
"github.com/atmiguel/cerealnotes/paths"
"github.com/atmiguel/cerealnotes/services/noteservice"
"github.com/atmiguel/cerealnotes/services/publicationservice"
"github.com/atmiguel/cerealnotes/services/userservice"
"github.com/dgrijalva/jwt-go"
)
Expand Down Expand Up @@ -214,6 +215,36 @@ func HandleSessionApiRequest(
}
}

func HandlePublicationApiRequest(
responseWriter http.ResponseWriter,
request *http.Request,
userId models.UserId,
) {
switch request.Method {
case http.MethodPost:
myUnpublishedNotes, err := noteservice.GetMyUnpublishedNotes(userId)
if err != nil {
http.Error(responseWriter, err.Error(), http.StatusInternalServerError)
return
}

if len(myUnpublishedNotes) == 0 {
http.Error(responseWriter, "Can't publish if you have no unpublished notes", http.StatusBadRequest)
return
}

if err := publicationservice.CreateAndPublishNotes(userId, myUnpublishedNotes); err != nil {
http.Error(responseWriter, err.Error(), http.StatusInternalServerError)
return
}

responseWriter.WriteHeader(http.StatusCreated)

default:
respondWithMethodNotAllowed(responseWriter, http.MethodPost)
}
}

func HandleNoteApiRequest(
responseWriter http.ResponseWriter,
request *http.Request,
Expand All @@ -232,6 +263,10 @@ func HandleNoteApiRequest(
fmt.Println(len(publishedNotes))

myUnpublishedNotes, err := noteservice.GetMyUnpublishedNotes(userId)
if err != nil {
http.Error(responseWriter, err.Error(), http.StatusInternalServerError)
return
}

fmt.Println("number of unpublished notes")
fmt.Println(len(myUnpublishedNotes))
Expand Down Expand Up @@ -318,6 +353,8 @@ func HandleNoteApiRequest(
return
}

responseWriter.WriteHeader(http.StatusOK)

default:
respondWithMethodNotAllowed(responseWriter, http.MethodGet, http.MethodPost, http.MethodDelete)
}
Expand Down
9 changes: 9 additions & 0 deletions models/publication.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ import "time"
type PublicationId int64

type Publication struct {
Id int64 `json:"id"`
AuthorId UserId `json:"authorId"`
CreationTime time.Time `json:"creationTime"`
}

func CreateNewPublication(userId UserId) *Publication {
return &Publication{
Id: -1,
AuthorId: userId,
CreationTime: time.Now().UTC(),
}
}
7 changes: 4 additions & 3 deletions paths/paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ const (
HomePage = "/home"
NotesPage = "/notes"

UserApi = "/api/user"
SessionApi = "/api/session"
NoteApi = "/api/note"
UserApi = "/api/user"
SessionApi = "/api/session"
NoteApi = "/api/note"
PublicationApi = "/api/publication"
)
1 change: 1 addition & 0 deletions routers/routers.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func DefineRoutes() http.Handler {
mux.HandleFunc(paths.SessionApi, handlers.HandleSessionApiRequest)

handleAuthenticated(mux, paths.NoteApi, handlers.HandleNoteApiRequest)
handleAuthenticated(mux, paths.PublicationApi, handlers.HandlePublicationApiRequest)

return mux
}
Expand Down
65 changes: 65 additions & 0 deletions services/publicationservice/publicationservice.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
Package noteservice handles interactions with database layer.
*/
package publicationservice

import (
"errors"

"github.com/atmiguel/cerealnotes/databaseutil"
"github.com/atmiguel/cerealnotes/models"
)

var PublicationIdNotSet error = errors.New("The PublicationId was not set")
var PublicationAuthorDiffersFromUserAuthor error = errors.New("A note under this publication has a different author than the publication")

func CreateAndPublishNotes(userId models.UserId, notes []*models.Note) error {
publication := models.CreateNewPublication(userId)
if err := StoreNewPublication(publication); err != nil {
return err
}

if err := PublishNotes(publication, notes); err != nil {
return err
}

return nil
}

func StoreNewPublication(publication *models.Publication) error {
id, err := databaseutil.StoreNewPublication(int64(publication.AuthorId), publication.CreationTime)
if err != nil {
return err
}

publication.Id = id

if publication.Id < 0 {
return PublicationIdNotSet
}

return nil
}

func PublishNotes(publication *models.Publication, notes []*models.Note) error {
if publication.Id < 0 {
return PublicationIdNotSet
}

noteIds := make([]int64, 0, 10)

for _, note := range notes {

if publication.AuthorId != note.AuthorId {
return PublicationAuthorDiffersFromUserAuthor
}

noteIds = append(noteIds, note.Id)
}

if err := databaseutil.StorePublicationNoteRelationship(publication.Id, noteIds); err != nil {
return err
}

return nil
}