add handler, html templates, Makefile and migrations
This commit is contained in:
commit
a06e8db2ff
22 changed files with 1001 additions and 0 deletions
58
postgres/comment_store.go
Normal file
58
postgres/comment_store.go
Normal 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
87
postgres/post_store.go
Normal 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
30
postgres/store.go
Normal 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
56
postgres/thread_store.go
Normal 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
|
||||
}
|
Reference in a new issue