chore: add /random to quotes app eb5ff3db
Steve Simkins · 2026-07-04 02:18 4 file(s) · +33 −0
apps/quotes/db.go +6 −0
92 92
	return scanQuote(db.QueryRow(`SELECT `+selectCols+` FROM quotes ORDER BY id LIMIT 1 OFFSET ?`, offset))
93 93
}
94 94
95 +
// randomQuote returns a uniformly random quote. Returns (nil, nil) when the
96 +
// table is empty.
97 +
func randomQuote(db *sql.DB) (*Quote, error) {
98 +
	return scanQuote(db.QueryRow(`SELECT ` + selectCols + ` FROM quotes ORDER BY RANDOM() LIMIT 1`))
99 +
}
100 +
95 101
func searchQuotes(db *sql.DB, q string) ([]Quote, error) {
96 102
	term := strings.TrimSpace(q)
97 103
	if term == "" {
apps/quotes/handlers_api.go +14 −0
40 40
	web.WriteJSON(w, http.StatusOK, q)
41 41
}
42 42
43 +
func (a *App) apiRandomQuote(w http.ResponseWriter, r *http.Request) {
44 +
	q, err := randomQuote(a.DB)
45 +
	if err != nil {
46 +
		a.Log.Error("random quote", "err", err)
47 +
		w.WriteHeader(http.StatusInternalServerError)
48 +
		return
49 +
	}
50 +
	if q == nil {
51 +
		web.WriteError(w, http.StatusNotFound, "no quotes")
52 +
		return
53 +
	}
54 +
	web.WriteJSON(w, http.StatusOK, q)
55 +
}
56 +
43 57
func (a *App) apiGetQuote(w http.ResponseWriter, r *http.Request) {
44 58
	q, err := getQuoteByShortID(a.DB, r.PathValue("short_id"))
45 59
	if err != nil {
apps/quotes/handlers_web.go +11 −0
35 35
	web.Render(a.Templates, w, "index.html", data, a.Log)
36 36
}
37 37
38 +
func (a *App) randomHandler(w http.ResponseWriter, r *http.Request) {
39 +
	data := indexPageData{BaseURL: a.BaseURL}
40 +
	if q, err := randomQuote(a.DB); err != nil {
41 +
		a.Log.Error("random quote", "err", err)
42 +
	} else if q != nil {
43 +
		v := quoteToView(*q)
44 +
		data.Quote = &v
45 +
	}
46 +
	web.Render(a.Templates, w, "index.html", data, a.Log)
47 +
}
48 +
38 49
func (a *App) loginGetHandler(w http.ResponseWriter, r *http.Request) {
39 50
	web.Render(a.Templates, w, "login.html", loginPageData{Error: r.URL.Query().Get("error")}, a.Log)
40 51
}
apps/quotes/routes.go +2 −0
15 15
	}
16 16
17 17
	mux.HandleFunc("GET /", a.indexHandler)
18 +
	mux.HandleFunc("GET /random", a.randomHandler)
18 19
	mux.HandleFunc("GET /static/", web.EmbeddedHandler(appFS, "static"))
19 20
	darkmatter.Mount(mux, "/assets")
20 21
27 28
28 29
	mux.HandleFunc("GET /api/quotes", a.apiListQuotes)
29 30
	mux.HandleFunc("GET /api/quotes/today", a.apiQuoteOfTheDay)
31 +
	mux.HandleFunc("GET /api/quotes/random", a.apiRandomQuote)
30 32
	mux.HandleFunc("GET /api/quotes/{short_id}", a.apiGetQuote)
31 33
32 34
	return mux