From df5af93c40233cf7adb58dfe7604991a16c28194 Mon Sep 17 00:00:00 2001 From: G Date: Wed, 29 Aug 2018 10:57:57 -0700 Subject: [PATCH 1/6] delete --- databaseutil/databaseutil.go | 54 +++++++++++++++++++++++++++++ handlers/handlers.go | 29 +++++++++++++++- migrations/0000_createDbs.sql | 8 ++--- services/noteservice/noteservice.go | 20 +++++++++++ static/js/base.js | 19 ++++++++++ templates/base.tmpl | 1 + 6 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 static/js/base.js diff --git a/databaseutil/databaseutil.go b/databaseutil/databaseutil.go index 210f4e1..08f51d2 100644 --- a/databaseutil/databaseutil.go +++ b/databaseutil/databaseutil.go @@ -94,6 +94,60 @@ func GetPasswordForUserWithEmailAddress(emailAddress string) ([]byte, error) { return password, nil } +func GetNote(id int64) (int64, int64, string, time.Time, error) { + + sqlQuery := ` + SELECT id, author_id, content, creation_time FROM note + WHERE id = $1` + + rows, err := db.Query(sqlQuery, id) + if err != nil { + return -1, -1, "", time.Time{}, convertPostgresError(err) + } + + defer rows.Close() + + var db_id int64 = -1 + var authorId int64 = -1 + var content string + var creationTime time.Time + + for rows.Next() { + if db_id >= 0 { + return -1, -1, "", time.Time{}, QueryResultContainedMultipleRowsError + } + + if err := rows.Scan(&db_id, &authorId, &content, &creationTime); err != nil { + return -1, -1, "", time.Time{}, err + } + } + + if db_id < 0 { + return -1, -1, "", time.Time{}, QueryResultContainedNoRowsError + } + + return db_id, authorId, content, creationTime, nil + // return -1, -1, "", time.Time{}, nil +} + +func DeleteNote(id int64) error { + sqlQuery := ` + DELETE FROM note + WHERE 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 StoreNewNote(authorId int64, content string, creationTime time.Time) (int64, error) { sqlQuery := ` INSERT INTO note (author_id, content, creation_time) diff --git a/handlers/handlers.go b/handlers/handlers.go index d853a63..523efc4 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -5,6 +5,7 @@ import ( "fmt" "html/template" "net/http" + "strconv" "strings" "time" @@ -292,8 +293,34 @@ func HandleNoteApiRequest( responseWriter.WriteHeader(http.StatusCreated) + case http.MethodDelete: + + id, err := strconv.ParseInt(request.URL.Query().Get("id"), 10, 64) + if err != nil { + http.Error(responseWriter, err.Error(), http.StatusBadRequest) + return + } + + note, err := noteservice.GetNoteById(id) + if err != nil { + http.Error(responseWriter, err.Error(), http.StatusInternalServerError) + return + } + + if note.AuthorId != userId { + errorString := "You are not the author of this note. you are only allowed to delete your own notes" + http.Error(responseWriter, errorString, http.StatusUnauthorized) + return + } + + err = noteservice.DeleteNoteById(note.Id) + if err != nil { + http.Error(responseWriter, err.Error(), http.StatusInternalServerError) + return + } + default: - respondWithMethodNotAllowed(responseWriter, http.MethodGet, http.MethodPost) + respondWithMethodNotAllowed(responseWriter, http.MethodGet, http.MethodPost, http.MethodDelete) } } diff --git a/migrations/0000_createDbs.sql b/migrations/0000_createDbs.sql index 8f12770..c6589f9 100644 --- a/migrations/0000_createDbs.sql +++ b/migrations/0000_createDbs.sql @@ -19,17 +19,17 @@ CREATE TABLE IF NOT EXISTS publication ( CREATE TABLE IF NOT EXISTS note ( id bigserial PRIMARY KEY, - author_id bigint references app_user(id) NOT NULL, + author_id bigint references app_user(id) NOT NULL ON DELETE CASCADE, content text NOT NULL, creation_time timestamp NOT NULL ); CREATE TABLE IF NOT EXISTS note_to_publication_relationship ( - note_id bigint PRIMARY KEY references note(id), - publication_id bigint references publication(id) NOT NULL + note_id bigint PRIMARY KEY references note(id) ON DELETE CASCADE, + publication_id bigint references publication(id) NOT NULL ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS note_to_category_relationship ( - note_id bigint PRIMARY KEY references note(id), + note_id bigint PRIMARY KEY references note(id) ON DELETE CASCADE, type category NOT NULL ); \ No newline at end of file diff --git a/services/noteservice/noteservice.go b/services/noteservice/noteservice.go index 8278f7a..62c7bfc 100644 --- a/services/noteservice/noteservice.go +++ b/services/noteservice/noteservice.go @@ -30,6 +30,26 @@ func StoreNewNote( return nil } +func GetNoteById(id int64) (*models.Note, error) { + db_id, authorid, content, creationTime, err := databaseutil.GetNote(id) + + if err != nil { + return nil, err + } + + return &models.Note{ + Id: db_id, + AuthorId: models.UserId(authorid), + Content: content, + CreationTime: creationTime, + }, + nil +} + +func DeleteNoteById(id int64) error { + return databaseutil.DeleteNote(id) +} + func StoreNoteCategoryRelationship( note *models.Note, category models.Category, diff --git a/static/js/base.js b/static/js/base.js new file mode 100644 index 0000000..933c71e --- /dev/null +++ b/static/js/base.js @@ -0,0 +1,19 @@ +$(function() { + jQuery.each( [ "put", "delete" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + return jQuery.ajax({ + url: url, + type: method, + dataType: type, + data: data, + success: callback + }); + }; + }); +}); \ No newline at end of file diff --git a/templates/base.tmpl b/templates/base.tmpl index 02de033..443b271 100644 --- a/templates/base.tmpl +++ b/templates/base.tmpl @@ -20,6 +20,7 @@ + {{ block "js" . }} {{ end }} From 7e4c0b9e3681264862852ba1435e415c28604442 Mon Sep 17 00:00:00 2001 From: G Date: Wed, 29 Aug 2018 10:58:56 -0700 Subject: [PATCH 2/6] delete api` --- migrations/tools/drop_everything.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/tools/drop_everything.sql b/migrations/tools/drop_everything.sql index b7b2cb1..fdb9d26 100644 --- a/migrations/tools/drop_everything.sql +++ b/migrations/tools/drop_everything.sql @@ -6,6 +6,6 @@ DROP TABLE publication CASCADE; DROP TABLE note CASCADE; -DROP TABLE note_to_type_relationship CASCADE; +DROP TABLE note_to_category_relationship CASCADE; DROP TABLE note_to_publication_relationship CASCADE; \ No newline at end of file From 2a630c653db7be715fab412eaee7fe15fcb8375c Mon Sep 17 00:00:00 2001 From: G Date: Wed, 29 Aug 2018 11:00:39 -0700 Subject: [PATCH 3/6] delete api --- migrations/0000_createDbs.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/0000_createDbs.sql b/migrations/0000_createDbs.sql index c6589f9..336bc33 100644 --- a/migrations/0000_createDbs.sql +++ b/migrations/0000_createDbs.sql @@ -19,14 +19,14 @@ CREATE TABLE IF NOT EXISTS publication ( CREATE TABLE IF NOT EXISTS note ( id bigserial PRIMARY KEY, - author_id bigint references app_user(id) NOT NULL ON DELETE CASCADE, + author_id bigint references app_user(id) ON DELETE CASCADE NOT NULL, content text NOT NULL, creation_time timestamp NOT NULL ); CREATE TABLE IF NOT EXISTS note_to_publication_relationship ( note_id bigint PRIMARY KEY references note(id) ON DELETE CASCADE, - publication_id bigint references publication(id) NOT NULL ON DELETE CASCADE + publication_id bigint references publication(id) ON DELETE CASCADE NOT NULL ); CREATE TABLE IF NOT EXISTS note_to_category_relationship ( From 84d000531f6deb54a1b81064de092b4f09ddf141 Mon Sep 17 00:00:00 2001 From: G Date: Wed, 29 Aug 2018 11:05:09 -0700 Subject: [PATCH 4/6] delete api --- static/js/base.js | 1 + 1 file changed, 1 insertion(+) diff --git a/static/js/base.js b/static/js/base.js index 933c71e..6a1130a 100644 --- a/static/js/base.js +++ b/static/js/base.js @@ -1,4 +1,5 @@ $(function() { + // http://stepansuvorov.com/blog/2014/04/jquery-put-and-delete/ jQuery.each( [ "put", "delete" ], function( i, method ) { jQuery[ method ] = function( url, data, callback, type ) { if ( jQuery.isFunction( data ) ) { From 7978bf8feb8ed8ce73780fafa0e907e068012513 Mon Sep 17 00:00:00 2001 From: G Date: Wed, 29 Aug 2018 11:37:33 -0700 Subject: [PATCH 5/6] 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 10222d899fbd135cf5d0aed8210f4eea7c014626 Mon Sep 17 00:00:00 2001 From: G Date: Mon, 17 Sep 2018 16:09:09 -0700 Subject: [PATCH 6/6] added getDOM method --- static/js/base.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/static/js/base.js b/static/js/base.js index 6a1130a..2143555 100644 --- a/static/js/base.js +++ b/static/js/base.js @@ -17,4 +17,16 @@ $(function() { }); }; }); + + jQuery.prototype.getDOM = function() { + if (this.length === 1) { + return this[0]; + } + + if (this.length === 0) { + throw "jQuery object is empty" + } + throw "jQuery Object contains more than 1 object"; + }; + }); \ No newline at end of file