add handler, html templates, Makefile and migrations

This commit is contained in:
Philipp 2021-08-29 16:37:20 +02:00
commit a06e8db2ff
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS.
GPG key ID: 276B613AF9DBE9C3
22 changed files with 1001 additions and 0 deletions

58
postgres/comment_store.go Normal file
View file

@ -0,0 +1,58 @@
package postgres
import (
"fmt"
"git.snrd.de/Spaenny/goddit"
"github.com/google/uuid"
"github.com/jmoiron/sqlx"
)
type CommentStore struct {
*sqlx.DB
}
func (s *CommentStore) Comment(id uuid.UUID) (goddit.Comment, error) {
var c goddit.Comment
if err := s.Get(&c, `SELECT * FROM comments WHERE id = $1`, id); err != nil {
return goddit.Comment{}, fmt.Errorf("error getting comment: %w", err)
}
return c, nil
}
func (s *CommentStore) CommentsByPost(postID uuid.UUID) ([]goddit.Comment, error) {
var cc []goddit.Comment
if err := s.Select(&cc, `SELECT * FROM comments WHERE post_id = $1 ORDER BY votes DESC`, postID); err != nil {
return []goddit.Comment{}, fmt.Errorf("error getting comments: %w", err)
}
return cc, nil
}
func (s *CommentStore) CreateComment(c *goddit.Comment) error {
if err := s.Get(c, `INSERT INTO comments VALUES($1, $2, $3, $4) RETURNING *`,
c.ID,
c.PostID,
c.Content,
c.Votes); err != nil {
return fmt.Errorf("error creating comment: %w", err)
}
return nil
}
func (s *CommentStore) UpdateComment(c *goddit.Comment) error {
if err := s.Get(c, `UPDATE comments SET post_id = $1, content = $2, votes = $3 WHERE id = $4 RETURNING *`,
c.PostID,
c.Content,
c.Votes,
c.ID); err != nil {
return fmt.Errorf("error updating comments: %w", err)
}
return nil
}
func (s *CommentStore) DeleteComment(id uuid.UUID) error {
if _, err := s.Exec(`DELETE FROM comments WHERE id = $1`, id); err != nil {
return fmt.Errorf("error deleting comment: %w", err)
}
return nil
}

87
postgres/post_store.go Normal file
View file

@ -0,0 +1,87 @@
package postgres
import (
"fmt"
"git.snrd.de/Spaenny/goddit"
"github.com/google/uuid"
"github.com/jmoiron/sqlx"
)
type PostStore struct {
*sqlx.DB
}
func (s *PostStore) Post(id uuid.UUID) (goddit.Post, error) {
var p goddit.Post
if err := s.Get(&p, `SELECT * FROM posts WHERE id = $1`, id); err != nil {
return goddit.Post{}, fmt.Errorf("error getting post: %w", err)
}
return p, nil
}
func (s *PostStore) PostsByThread(threadID uuid.UUID) ([]goddit.Post, error) {
var pp []goddit.Post
var query = `
SELECT
posts.*,
COUNT(comments.*) AS comments_count
FROM posts
LEFT JOIN comments ON comments.post_id = posts.id
WHERE thread_ID = $1
GROUP BY posts.id
ORDER BY votes DESC`
if err := s.Select(&pp, query, threadID); err != nil {
return []goddit.Post{}, fmt.Errorf("error gettings posts: %w", err)
}
return pp, nil
}
func (s *PostStore) Posts() ([]goddit.Post, error) {
var pp []goddit.Post
var query = `
SELECT
posts.*,
COUNT(comments.*) AS comments_count,
threads.title AS thread_title
FROM posts
LEFT JOIN comments ON comments.post_id = posts.id
JOIN threads ON threads.id = posts.thread_id
GROUP BY posts.id, threads.title
ORDER BY votes DESC`
if err := s.Select(&pp, query); err != nil {
return []goddit.Post{}, fmt.Errorf("error gettings posts: %w", err)
}
return pp, nil
}
func (s *PostStore) CreatePost(p *goddit.Post) error {
if err := s.Get(p, `INSERT INTO posts VALUES($1, $2, $3, $4, $5) RETURNING *`,
p.ID,
p.ThreadID,
p.Title,
p.Content,
p.Votes); err != nil {
return fmt.Errorf("error creating post: %w", err)
}
return nil
}
func (s *PostStore) UpdatePost(p *goddit.Post) error {
if err := s.Get(p, `UPDATE posts set thread_id = $1, title = $2, content = $3, votes = $4 WHERE id = $5 RETURNING *`,
p.ThreadID,
p.Title,
p.Content,
p.Votes,
p.ID); err != nil {
return fmt.Errorf("error updating post: %w", err)
}
return nil
}
func (s *PostStore) DeletePost(id uuid.UUID) error {
if _, err := s.Exec(`DELETE FROM posts WHERE id = $1`, id); err != nil {
return fmt.Errorf("error deleting post: %w", err)
}
return nil
}

30
postgres/store.go Normal file
View file

@ -0,0 +1,30 @@
package postgres
import (
"fmt"
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
)
func NewStore(dataSourceName string) (*Store, error) {
db, err := sqlx.Open("postgres", dataSourceName)
if err != nil {
return nil, fmt.Errorf("error opening database: %w", err)
}
if err := db.Ping(); err != nil {
return nil, fmt.Errorf("error connecting to database: %w", err)
}
return &Store{
ThreadStore: &ThreadStore{DB: db},
PostStore: &PostStore{DB: db},
CommentStore: &CommentStore{DB: db},
}, nil
}
type Store struct {
*ThreadStore
*PostStore
*CommentStore
}

56
postgres/thread_store.go Normal file
View file

@ -0,0 +1,56 @@
package postgres
import (
"fmt"
"git.snrd.de/Spaenny/goddit"
"github.com/google/uuid"
"github.com/jmoiron/sqlx"
)
type ThreadStore struct {
*sqlx.DB
}
func (s *ThreadStore) Thread(id uuid.UUID) (goddit.Thread, error) {
var t goddit.Thread
if err := s.Get(&t, `SELECT * FROM threads WHERE id = $1`, id); err != nil {
return goddit.Thread{}, fmt.Errorf("error getting thread: %w", err)
}
return t, nil
}
func (s *ThreadStore) Threads() ([]goddit.Thread, error) {
var tt []goddit.Thread
if err := s.Select(&tt, `SELECT * FROM threads`); err != nil {
return []goddit.Thread{}, fmt.Errorf("error getting threads: %w", err)
}
return tt, nil
}
func (s *ThreadStore) CreateThread(t *goddit.Thread) error {
if err := s.Get(t, `INSERT INTO threads VALUES($1, $2, $3) RETURNING *`,
t.ID,
t.Title,
t.Description); err != nil {
return fmt.Errorf("error creating thread: %w", err)
}
return nil
}
func (s *ThreadStore) UpdateThread(t *goddit.Thread) error {
if err := s.Get(t, `UPDATE INTO threads SET title = $1,description = $2 WHERE id = $3) RETURNING *`,
t.Title,
t.Description,
t.ID); err != nil {
return fmt.Errorf("error updating thread: %w", err)
}
return nil
}
func (s *ThreadStore) DeleteThread(id uuid.UUID) error {
if _, err := s.Exec(`DELETE FROM threads WHERE id = $1`, id); err != nil {
return fmt.Errorf("error deleteing thread: %w", err)
}
return nil
}