internal/httpd/queries.go
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}