internal/httpd/queries.go

v1.41.0
gitbay/internal/httpd/queries.go history · blame · raw

78 lines · 2214 bytes

 1package httpd
 2
 3import (
 4	"net/http"
 5	"net/url"
 6	"strconv"
 7
 8	"gitbay.org/gitbay/internal/control"
 9	"gitbay.org/gitbay/internal/protocol"
10	"gitbay.org/gitbay/internal/store"
11)
12
13// queryPerPage is how many rows a saved query's page shows before
14// offering the next, through query run's own cursor.
15const queryPerPage = 50
16
17// queriesPage lists the viewer's saved queries (/{owner}/-/queries), or
18// runs one (/{owner}/-/queries/{name}) through query show and query run,
19// the reads the CLI makes. Saved queries are private: under anyone else's
20// name the page is not found.
21func (s *Server) queriesPage(w http.ResponseWriter, r *http.Request, viewer store.User) {
22	if r.PathValue("owner") != viewer.Username {
23		s.notFound(w, r)
24		return
25	}
26	name := r.PathValue("name")
27	data := struct {
28		basePage
29		Tab   string
30		Saved []control.SavedQueryOut
31		Query control.SavedQueryOut
32		Count int
33		Items []control.QueryItem
34		Next  string
35	}{basePage: s.baseFor(viewer), Tab: "dashboard"}
36	if name == "" {
37		if msg, ok := s.runControlInto(viewer, []string{"query", "list"}, &data.Saved); !ok {
38			http.Error(w, msg, http.StatusInternalServerError)
39			return
40		}
41		s.render(w, "queries.html", data)
42		return
43	}
44	switch code, msg := s.runControlIntoCode(viewer, []string{"query", "show", name}, &data.Query); code {
45	case protocol.ExitOK:
46	case protocol.ExitNotFound:
47		s.notFound(w, r)
48		return
49	default:
50		http.Error(w, msg, http.StatusInternalServerError)
51		return
52	}
53	if data.Query.Count != nil {
54		data.Count = *data.Query.Count
55	}
56	argv := []string{"query", "run", name, "--limit", strconv.Itoa(queryPerPage)}
57	if cursor := r.URL.Query().Get("cursor"); cursor != "" {
58		argv = append(argv, "--cursor", cursor)
59	}
60	var page struct {
61		Items []control.QueryItem `json:"items"`
62		Next  string              `json:"next"`
63	}
64	switch code, msg := s.runControlIntoCode(viewer, argv, &page); code {
65	case protocol.ExitOK:
66	case protocol.ExitUsage:
67		http.Error(w, msg, http.StatusBadRequest)
68		return
69	default:
70		http.Error(w, msg, http.StatusInternalServerError)
71		return
72	}
73	data.Items = page.Items
74	if page.Next != "" {
75		data.Next = "?" + url.Values{"cursor": {page.Next}}.Encode()
76	}
77	s.render(w, "queries.html", data)
78}