Signed-off-by: Seongmin Lee git@boltless.me
+61
appview/db/pulls.go
+61
appview/db/pulls.go
···
281
281
return GetPullsWithLimit(e, 0, filters...)
282
282
}
283
283
284
+
func GetPullIDs(e Execer, opts models.PullSearchOptions) ([]int64, error) {
285
+
var ids []int64
286
+
287
+
var filters []filter
288
+
filters = append(filters, FilterEq("state", opts.State))
289
+
if opts.RepoAt != "" {
290
+
filters = append(filters, FilterEq("repo_at", opts.RepoAt))
291
+
}
292
+
293
+
var conditions []string
294
+
var args []any
295
+
296
+
for _, filter := range filters {
297
+
conditions = append(conditions, filter.Condition())
298
+
args = append(args, filter.Arg()...)
299
+
}
300
+
301
+
whereClause := ""
302
+
if conditions != nil {
303
+
whereClause = " where " + strings.Join(conditions, " and ")
304
+
}
305
+
pageClause := ""
306
+
if opts.Page.Limit != 0 {
307
+
pageClause = fmt.Sprintf(
308
+
" limit %d offset %d ",
309
+
opts.Page.Limit,
310
+
opts.Page.Offset,
311
+
)
312
+
}
313
+
314
+
query := fmt.Sprintf(
315
+
`
316
+
select
317
+
id
318
+
from
319
+
pulls
320
+
%s
321
+
%s`,
322
+
whereClause,
323
+
pageClause,
324
+
)
325
+
args = append(args, opts.Page.Limit, opts.Page.Offset)
326
+
rows, err := e.Query(query, args...)
327
+
if err != nil {
328
+
return nil, err
329
+
}
330
+
defer rows.Close()
331
+
332
+
for rows.Next() {
333
+
var id int64
334
+
err := rows.Scan(&id)
335
+
if err != nil {
336
+
return nil, err
337
+
}
338
+
339
+
ids = append(ids, id)
340
+
}
341
+
342
+
return ids, nil
343
+
}
344
+
284
345
func GetPull(e Execer, repoAt syntax.ATURI, pullId int) (*models.Pull, error) {
285
346
pulls, err := GetPullsWithLimit(e, 1, FilterEq("repo_at", repoAt), FilterEq("pull_id", pullId))
286
347
if err != nil {
+1
appview/pages/pages.go
+1
appview/pages/pages.go
+7
appview/pages/templates/repo/pulls/pulls.html
+7
appview/pages/templates/repo/pulls/pulls.html
···
31
31
{{ i "ban" "w-4 h-4" }}
32
32
<span>{{ .RepoInfo.Stats.PullCount.Closed }} closed</span>
33
33
</a>
34
+
<form class="flex gap-4" method="GET">
35
+
<input type="hidden" name="state" value="{{ .FilteringBy.String }}">
36
+
<input class="" type="text" name="q" value="{{ .FilterQuery }}">
37
+
<button class="btn" type="submit">
38
+
search
39
+
</button>
40
+
</form>
34
41
</div>
35
42
<a
36
43
href="/{{ .RepoInfo.FullName }}/pulls/new"
+35
-2
appview/pulls/pulls.go
+35
-2
appview/pulls/pulls.go
···
17
17
"tangled.org/core/api/tangled"
18
18
"tangled.org/core/appview/config"
19
19
"tangled.org/core/appview/db"
20
+
pulls_indexer "tangled.org/core/appview/indexer/pulls"
20
21
"tangled.org/core/appview/models"
21
22
"tangled.org/core/appview/notify"
22
23
"tangled.org/core/appview/oauth"
···
49
50
enforcer *rbac.Enforcer
50
51
logger *slog.Logger
51
52
validator *validator.Validator
53
+
indexer *pulls_indexer.Indexer
52
54
}
53
55
54
56
func New(
···
61
63
notifier notify.Notifier,
62
64
enforcer *rbac.Enforcer,
63
65
validator *validator.Validator,
66
+
indexer *pulls_indexer.Indexer,
64
67
logger *slog.Logger,
65
68
) *Pulls {
66
69
return &Pulls{
···
74
77
enforcer: enforcer,
75
78
logger: logger,
76
79
validator: validator,
80
+
indexer: indexer,
77
81
}
78
82
}
79
83
···
544
548
}
545
549
546
550
func (s *Pulls) RepoPulls(w http.ResponseWriter, r *http.Request) {
551
+
l := s.logger.With("handler", "RepoPulls")
552
+
547
553
user := s.oauth.GetUser(r)
548
554
params := r.URL.Query()
549
555
···
561
567
return
562
568
}
563
569
570
+
keyword := params.Get("q")
571
+
572
+
var ids []int64
573
+
searchOpts := models.PullSearchOptions{
574
+
Keyword: keyword,
575
+
RepoAt: f.RepoAt().String(),
576
+
State: state,
577
+
// Page: page,
578
+
}
579
+
l.Debug("searching with", "searchOpts", searchOpts)
580
+
if keyword != "" {
581
+
res, err := s.indexer.Search(r.Context(), searchOpts)
582
+
if err != nil {
583
+
l.Error("failed to search for pulls", "err", err)
584
+
return
585
+
}
586
+
l.Debug("searched pulls with indexer", "res.Hits", res.Hits)
587
+
ids = res.Hits
588
+
} else {
589
+
ids, err = db.GetPullIDs(s.db, searchOpts)
590
+
if err != nil {
591
+
l.Error("failed to get all pull ids", "err", err)
592
+
return
593
+
}
594
+
l.Debug("indexed all pulls from the db", "ids", ids)
595
+
}
596
+
564
597
pulls, err := db.GetPulls(
565
598
s.db,
566
-
db.FilterEq("repo_at", f.RepoAt()),
567
-
db.FilterEq("state", state),
599
+
db.FilterIn("id", ids),
568
600
)
569
601
if err != nil {
570
602
log.Println("failed to get pulls", err)
···
651
683
Pulls: pulls,
652
684
LabelDefs: defs,
653
685
FilteringBy: state,
686
+
FilterQuery: keyword,
654
687
Stacks: stacks,
655
688
Pipelines: m,
656
689
})