Refactor Store into SessionStore; move domain SQL onto User/Question/Answer.
This commit is contained in:
+26
-17
@@ -3,6 +3,7 @@ package web
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"database/sql"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"html/template"
|
||||
@@ -30,7 +31,7 @@ type Config struct {
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
store store.DB
|
||||
db *sql.DB
|
||||
sessions *scs.SessionManager
|
||||
tmpl *template.Template
|
||||
cfg Config
|
||||
@@ -84,7 +85,7 @@ type voteCtx struct {
|
||||
Question store.RankedQuestion
|
||||
}
|
||||
|
||||
func New(st store.DB, sessionStore scs.Store, templateFS fs.FS, staticFS fs.FS, cfg Config) (*Server, error) {
|
||||
func New(db *sql.DB, sessionStore scs.Store, templateFS fs.FS, staticFS fs.FS, cfg Config) (*Server, error) {
|
||||
if cfg.Blob == nil {
|
||||
cfg.Blob = blob.Disabled{}
|
||||
}
|
||||
@@ -124,7 +125,7 @@ func New(st store.DB, sessionStore scs.Store, templateFS fs.FS, staticFS fs.FS,
|
||||
}
|
||||
|
||||
return &Server{
|
||||
store: st,
|
||||
db: db,
|
||||
sessions: sessions,
|
||||
tmpl: tmpl,
|
||||
cfg: cfg,
|
||||
@@ -180,7 +181,7 @@ func (s *Server) withUser(next http.Handler) http.Handler {
|
||||
}
|
||||
id := s.sessions.GetString(r.Context(), "user_id")
|
||||
if id != "" {
|
||||
u, err := s.store.UserByID(r.Context(), id)
|
||||
u, err := store.UserByID(r.Context(), s.db, id)
|
||||
if err == nil {
|
||||
r = r.WithContext(context.WithValue(r.Context(), userKey, u))
|
||||
}
|
||||
@@ -258,7 +259,7 @@ func (s *Server) renderHunt(w http.ResponseWriter, r *http.Request, date string)
|
||||
if u := currentUser(r); u != nil {
|
||||
viewer = u.ID
|
||||
}
|
||||
questions, err := s.store.ListHunt(r.Context(), date, viewer)
|
||||
questions, err := store.ListHunt(r.Context(), s.db, date, viewer)
|
||||
if err != nil {
|
||||
http.Error(w, "could not load questions", http.StatusInternalServerError)
|
||||
return
|
||||
@@ -318,8 +319,12 @@ func (s *Server) handleSubmit(w http.ResponseWriter, r *http.Request) {
|
||||
if len(city) > 80 {
|
||||
city = city[:80]
|
||||
}
|
||||
q, err := s.store.CreateQuestion(r.Context(), u.ID, title, body, city)
|
||||
if err != nil {
|
||||
q := store.NewQuestion(s.db)
|
||||
q.AuthorID = u.ID
|
||||
q.Title = title
|
||||
q.Body = body
|
||||
q.City = city
|
||||
if err := q.Create(r.Context()); err != nil {
|
||||
http.Error(w, "could not save question", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -332,14 +337,14 @@ func (s *Server) handleQuestion(w http.ResponseWriter, r *http.Request) {
|
||||
if u := currentUser(r); u != nil {
|
||||
viewer = u.ID
|
||||
}
|
||||
q, err := s.store.GetQuestion(r.Context(), id, viewer)
|
||||
q, err := store.GetQuestion(r.Context(), s.db, id, viewer)
|
||||
if err != nil || (q.Hidden && !currentUser(r).Admin()) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
var ans *store.Answer
|
||||
if q.Answered {
|
||||
ans, _ = s.store.GetAnswer(r.Context(), q.ID)
|
||||
ans, _ = store.GetAnswer(r.Context(), s.db, q.ID)
|
||||
}
|
||||
s.exec(w, "question", questionPage{
|
||||
page: s.basePage(r, q.Title),
|
||||
@@ -372,7 +377,7 @@ func (s *Server) handleVote(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "invalid vote", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if err := s.store.Vote(r.Context(), u.ID, id, value); err != nil {
|
||||
if err := store.Vote(r.Context(), s.db, u.ID, id, value); err != nil {
|
||||
http.Error(w, "could not vote", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -383,7 +388,7 @@ func (s *Server) handleVote(w http.ResponseWriter, r *http.Request) {
|
||||
s.renderLeaderboard(w, r, date)
|
||||
return
|
||||
}
|
||||
q, err := s.store.GetQuestion(r.Context(), id, u.ID)
|
||||
q, err := store.GetQuestion(r.Context(), s.db, id, u.ID)
|
||||
if err != nil {
|
||||
http.Error(w, "not found", http.StatusNotFound)
|
||||
return
|
||||
@@ -416,7 +421,7 @@ func (s *Server) renderLeaderboard(w http.ResponseWriter, r *http.Request, date
|
||||
if u := currentUser(r); u != nil {
|
||||
viewer = u.ID
|
||||
}
|
||||
questions, err := s.store.ListHunt(r.Context(), date, viewer)
|
||||
questions, err := store.ListHunt(r.Context(), s.db, date, viewer)
|
||||
if err != nil {
|
||||
http.Error(w, "could not load questions", http.StatusInternalServerError)
|
||||
return
|
||||
@@ -446,17 +451,21 @@ func (s *Server) handleAnswer(w http.ResponseWriter, r *http.Request) {
|
||||
if len(body) > 12000 {
|
||||
body = body[:12000]
|
||||
}
|
||||
if err := s.store.UpsertAnswer(r.Context(), id, u.ID, body); err != nil {
|
||||
ans := store.NewAnswer(s.db)
|
||||
ans.QuestionID = id
|
||||
ans.AuthorID = u.ID
|
||||
ans.Body = body
|
||||
if err := ans.Upsert(r.Context()); err != nil {
|
||||
http.Error(w, "could not save answer", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
ans, err := s.store.GetAnswer(r.Context(), id)
|
||||
saved, err := store.GetAnswer(r.Context(), s.db, id)
|
||||
if err != nil {
|
||||
http.Error(w, "could not load answer", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if isHTMX(r) {
|
||||
s.exec(w, "answer", questionPage{page: s.basePage(r, ""), Answer: ans})
|
||||
s.exec(w, "answer", questionPage{page: s.basePage(r, ""), Answer: saved})
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, "/questions/"+url.PathEscape(id), http.StatusSeeOther)
|
||||
@@ -472,12 +481,12 @@ func (s *Server) handleHide(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
id := chi.URLParam(r, "id")
|
||||
q, err := s.store.GetQuestion(r.Context(), id, u.ID)
|
||||
q, err := store.GetQuestion(r.Context(), s.db, id, u.ID)
|
||||
if err != nil {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
if err := s.store.HideQuestion(r.Context(), id); err != nil {
|
||||
if err := q.Hide(r.Context()); err != nil {
|
||||
http.Error(w, "could not hide", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user