Signed-off-by: dusk y.bera003.06@protonmail.com
+2
-2
appview/db/artifact.go
+2
-2
appview/db/artifact.go
···
57
return err
58
}
59
60
-
func GetArtifact(e Execer, filters ...filter) ([]Artifact, error) {
61
var artifacts []Artifact
62
63
var conditions []string
···
130
return artifacts, nil
131
}
132
133
-
func DeleteArtifact(e Execer, filters ...filter) error {
134
var conditions []string
135
var args []any
136
for _, filter := range filters {
···
57
return err
58
}
59
60
+
func GetArtifact(e Execer, filters ...Filter) ([]Artifact, error) {
61
var artifacts []Artifact
62
63
var conditions []string
···
130
return artifacts, nil
131
}
132
133
+
func DeleteArtifact(e Execer, filters ...Filter) error {
134
var conditions []string
135
var args []any
136
for _, filter := range filters {
+1
-1
appview/db/collaborators.go
+1
-1
appview/db/collaborators.go
+13
-13
appview/db/db.go
+13
-13
appview/db/db.go
···
918
return d.DB.Close()
919
}
920
921
-
type filter struct {
922
key string
923
arg any
924
cmp string
925
}
926
927
-
func newFilter(key, cmp string, arg any) filter {
928
-
return filter{
929
key: key,
930
arg: arg,
931
cmp: cmp,
932
}
933
}
934
935
-
func FilterEq(key string, arg any) filter { return newFilter(key, "=", arg) }
936
-
func FilterNotEq(key string, arg any) filter { return newFilter(key, "<>", arg) }
937
-
func FilterGte(key string, arg any) filter { return newFilter(key, ">=", arg) }
938
-
func FilterLte(key string, arg any) filter { return newFilter(key, "<=", arg) }
939
-
func FilterIs(key string, arg any) filter { return newFilter(key, "is", arg) }
940
-
func FilterIsNot(key string, arg any) filter { return newFilter(key, "is not", arg) }
941
-
func FilterIn(key string, arg any) filter { return newFilter(key, "in", arg) }
942
-
func FilterBetween(key string, arg1, arg2 any) filter {
943
return newFilter(key, "between", []any{arg1, arg2})
944
}
945
946
-
func (f filter) Condition() string {
947
rv := reflect.ValueOf(f.arg)
948
kind := rv.Kind()
949
···
969
return fmt.Sprintf("%s %s ?", f.key, f.cmp)
970
}
971
972
-
func (f filter) Arg() []any {
973
rv := reflect.ValueOf(f.arg)
974
kind := rv.Kind()
975
if (kind == reflect.Slice && rv.Type().Elem().Kind() != reflect.Uint8) || kind == reflect.Array {
···
918
return d.DB.Close()
919
}
920
921
+
type Filter struct {
922
key string
923
arg any
924
cmp string
925
}
926
927
+
func newFilter(key, cmp string, arg any) Filter {
928
+
return Filter{
929
key: key,
930
arg: arg,
931
cmp: cmp,
932
}
933
}
934
935
+
func FilterEq(key string, arg any) Filter { return newFilter(key, "=", arg) }
936
+
func FilterNotEq(key string, arg any) Filter { return newFilter(key, "<>", arg) }
937
+
func FilterGte(key string, arg any) Filter { return newFilter(key, ">=", arg) }
938
+
func FilterLte(key string, arg any) Filter { return newFilter(key, "<=", arg) }
939
+
func FilterIs(key string, arg any) Filter { return newFilter(key, "is", arg) }
940
+
func FilterIsNot(key string, arg any) Filter { return newFilter(key, "is not", arg) }
941
+
func FilterIn(key string, arg any) Filter { return newFilter(key, "in", arg) }
942
+
func FilterBetween(key string, arg1, arg2 any) Filter {
943
return newFilter(key, "between", []any{arg1, arg2})
944
}
945
946
+
func (f Filter) Condition() string {
947
rv := reflect.ValueOf(f.arg)
948
kind := rv.Kind()
949
···
969
return fmt.Sprintf("%s %s ?", f.key, f.cmp)
970
}
971
972
+
func (f Filter) Arg() []any {
973
rv := reflect.ValueOf(f.arg)
974
kind := rv.Kind()
975
if (kind == reflect.Slice && rv.Type().Elem().Kind() != reflect.Uint8) || kind == reflect.Array {
+1
-1
appview/db/follow.go
+1
-1
appview/db/follow.go
+7
-7
appview/db/issues.go
+7
-7
appview/db/issues.go
···
245
return err
246
}
247
248
-
func GetIssuesPaginated(e Execer, page pagination.Page, filters ...filter) ([]Issue, error) {
249
issueMap := make(map[string]*Issue) // at-uri -> issue
250
251
var conditions []string
···
395
return issues, nil
396
}
397
398
-
func GetIssues(e Execer, filters ...filter) ([]Issue, error) {
399
return GetIssuesPaginated(e, pagination.Page{No: 0, Count: 10}, filters...)
400
}
401
···
462
return id, nil
463
}
464
465
-
func DeleteIssueComments(e Execer, filters ...filter) error {
466
var conditions []string
467
var args []any
468
for _, filter := range filters {
···
481
return err
482
}
483
484
-
func GetIssueComments(e Execer, filters ...filter) ([]IssueComment, error) {
485
var comments []IssueComment
486
487
var conditions []string
···
571
return comments, nil
572
}
573
574
-
func DeleteIssues(e Execer, filters ...filter) error {
575
var conditions []string
576
var args []any
577
for _, filter := range filters {
···
589
return err
590
}
591
592
-
func CloseIssues(e Execer, filters ...filter) error {
593
var conditions []string
594
var args []any
595
for _, filter := range filters {
···
607
return err
608
}
609
610
-
func ReopenIssues(e Execer, filters ...filter) error {
611
var conditions []string
612
var args []any
613
for _, filter := range filters {
···
245
return err
246
}
247
248
+
func GetIssuesPaginated(e Execer, page pagination.Page, filters ...Filter) ([]Issue, error) {
249
issueMap := make(map[string]*Issue) // at-uri -> issue
250
251
var conditions []string
···
395
return issues, nil
396
}
397
398
+
func GetIssues(e Execer, filters ...Filter) ([]Issue, error) {
399
return GetIssuesPaginated(e, pagination.Page{No: 0, Count: 10}, filters...)
400
}
401
···
462
return id, nil
463
}
464
465
+
func DeleteIssueComments(e Execer, filters ...Filter) error {
466
var conditions []string
467
var args []any
468
for _, filter := range filters {
···
481
return err
482
}
483
484
+
func GetIssueComments(e Execer, filters ...Filter) ([]IssueComment, error) {
485
var comments []IssueComment
486
487
var conditions []string
···
571
return comments, nil
572
}
573
574
+
func DeleteIssues(e Execer, filters ...Filter) error {
575
var conditions []string
576
var args []any
577
for _, filter := range filters {
···
589
return err
590
}
591
592
+
func CloseIssues(e Execer, filters ...Filter) error {
593
var conditions []string
594
var args []any
595
for _, filter := range filters {
···
607
return err
608
}
609
610
+
func ReopenIssues(e Execer, filters ...Filter) error {
611
var conditions []string
612
var args []any
613
for _, filter := range filters {
+1
-1
appview/db/language.go
+1
-1
appview/db/language.go
+62
-14
appview/db/pipeline.go
+62
-14
appview/db/pipeline.go
···
131
ExitCode int
132
}
133
134
-
func GetPipelines(e Execer, filters ...filter) ([]Pipeline, error) {
135
var pipelines []Pipeline
136
137
var conditions []string
···
290
291
// this is a mega query, but the most useful one:
292
// get N pipelines, for each one get the latest status of its N workflows
293
-
func GetPipelineStatuses(e Execer, filters ...filter) ([]Pipeline, error) {
294
var conditions []string
295
var args []any
296
for _, filter := range filters {
···
305
}
306
307
query := fmt.Sprintf(`
308
select
309
p.id,
310
p.knot,
···
313
p.repo_name,
314
p.sha,
315
p.created,
316
-
t.id,
317
-
t.kind,
318
-
t.push_ref,
319
-
t.push_new_sha,
320
-
t.push_old_sha,
321
-
t.pr_source_branch,
322
-
t.pr_target_branch,
323
-
t.pr_source_sha,
324
-
t.pr_action
325
from
326
-
pipelines p
327
-
join
328
-
triggers t ON p.trigger_id = t.id
329
%s
330
`, whereClause)
331
···
485
486
return all, nil
487
}
···
131
ExitCode int
132
}
133
134
+
func GetPipelines(e Execer, filters ...Filter) ([]Pipeline, error) {
135
var pipelines []Pipeline
136
137
var conditions []string
···
290
291
// this is a mega query, but the most useful one:
292
// get N pipelines, for each one get the latest status of its N workflows
293
+
func GetPipelineStatuses(e Execer, filters ...Filter) ([]Pipeline, error) {
294
var conditions []string
295
var args []any
296
for _, filter := range filters {
···
305
}
306
307
query := fmt.Sprintf(`
308
+
with ranked_pipelines as (
309
+
select
310
+
p.id,
311
+
p.knot,
312
+
p.rkey,
313
+
p.repo_owner,
314
+
p.repo_name,
315
+
p.sha,
316
+
p.created,
317
+
t.id,
318
+
t.kind,
319
+
t.push_ref,
320
+
t.push_new_sha,
321
+
t.push_old_sha,
322
+
t.pr_source_branch,
323
+
t.pr_target_branch,
324
+
t.pr_source_sha,
325
+
t.pr_action,
326
+
row_number() over (order by p.created desc) as row_num
327
+
from
328
+
pipelines p
329
+
join
330
+
triggers t ON p.trigger_id = t.id
331
+
)
332
select
333
p.id,
334
p.knot,
···
337
p.repo_name,
338
p.sha,
339
p.created,
340
+
p.id,
341
+
p.kind,
342
+
p.push_ref,
343
+
p.push_new_sha,
344
+
p.push_old_sha,
345
+
p.pr_source_branch,
346
+
p.pr_target_branch,
347
+
p.pr_source_sha,
348
+
p.pr_action
349
from
350
+
ranked_pipelines p
351
%s
352
`, whereClause)
353
···
507
508
return all, nil
509
}
510
+
511
+
// get pipeline counts, implement with filters
512
+
func GetPipelineCount(e Execer, filters ...Filter) (int, error) {
513
+
var conditions []string
514
+
var args []any
515
+
for _, filter := range filters {
516
+
conditions = append(conditions, filter.Condition())
517
+
args = append(args, filter.Arg()...)
518
+
}
519
+
520
+
whereClause := ""
521
+
if conditions != nil {
522
+
whereClause = " where " + strings.Join(conditions, " and ")
523
+
}
524
+
525
+
query := fmt.Sprintf(`select count(*) as count from pipelines %s`, whereClause)
526
+
527
+
row := e.QueryRow(query, args...)
528
+
529
+
var count int
530
+
if err := row.Scan(&count); err != nil {
531
+
return 0, err
532
+
}
533
+
534
+
return count, nil
535
+
}
+1
-1
appview/db/profile.go
+1
-1
appview/db/profile.go
+4
-4
appview/db/pulls.go
+4
-4
appview/db/pulls.go
···
311
return pullId - 1, err
312
}
313
314
-
func GetPullsWithLimit(e Execer, limit int, filters ...filter) ([]*Pull, error) {
315
pulls := make(map[int]*Pull)
316
317
var conditions []string
···
529
return orderedByPullId, nil
530
}
531
532
-
func GetPulls(e Execer, filters ...filter) ([]*Pull, error) {
533
return GetPullsWithLimit(e, 0, filters...)
534
}
535
···
884
return err
885
}
886
887
-
func SetPullParentChangeId(e Execer, parentChangeId string, filters ...filter) error {
888
var conditions []string
889
var args []any
890
···
908
909
// Only used when stacking to update contents in the event of a rebase (the interdiff should be empty).
910
// otherwise submissions are immutable
911
-
func UpdatePull(e Execer, newPatch, sourceRev string, filters ...filter) error {
912
var conditions []string
913
var args []any
914
···
311
return pullId - 1, err
312
}
313
314
+
func GetPullsWithLimit(e Execer, limit int, filters ...Filter) ([]*Pull, error) {
315
pulls := make(map[int]*Pull)
316
317
var conditions []string
···
529
return orderedByPullId, nil
530
}
531
532
+
func GetPulls(e Execer, filters ...Filter) ([]*Pull, error) {
533
return GetPullsWithLimit(e, 0, filters...)
534
}
535
···
884
return err
885
}
886
887
+
func SetPullParentChangeId(e Execer, parentChangeId string, filters ...Filter) error {
888
var conditions []string
889
var args []any
890
···
908
909
// Only used when stacking to update contents in the event of a rebase (the interdiff should be empty).
910
// otherwise submissions are immutable
911
+
func UpdatePull(e Execer, newPatch, sourceRev string, filters ...Filter) error {
912
var conditions []string
913
var args []any
914
+1
-1
appview/db/punchcard.go
+1
-1
appview/db/punchcard.go
+3
-3
appview/db/registration.go
+3
-3
appview/db/registration.go
···
48
NeedsUpgrade
49
)
50
51
-
func GetRegistrations(e Execer, filters ...filter) ([]Registration, error) {
52
var registrations []Registration
53
54
var conditions []string
···
108
return registrations, nil
109
}
110
111
-
func MarkRegistered(e Execer, filters ...filter) error {
112
var conditions []string
113
var args []any
114
for _, filter := range filters {
···
133
return err
134
}
135
136
-
func DeleteKnot(e Execer, filters ...filter) error {
137
var conditions []string
138
var args []any
139
for _, filter := range filters {
···
48
NeedsUpgrade
49
)
50
51
+
func GetRegistrations(e Execer, filters ...Filter) ([]Registration, error) {
52
var registrations []Registration
53
54
var conditions []string
···
108
return registrations, nil
109
}
110
111
+
func MarkRegistered(e Execer, filters ...Filter) error {
112
var conditions []string
113
var args []any
114
for _, filter := range filters {
···
133
return err
134
}
135
136
+
func DeleteKnot(e Execer, filters ...Filter) error {
137
var conditions []string
138
var args []any
139
for _, filter := range filters {
+2
-2
appview/db/repos.go
+2
-2
appview/db/repos.go
···
39
return p
40
}
41
42
-
func GetRepos(e Execer, limit int, filters ...filter) ([]Repo, error) {
43
repoMap := make(map[syntax.ATURI]*Repo)
44
45
var conditions []string
···
285
return repos, nil
286
}
287
288
-
func CountRepos(e Execer, filters ...filter) (int64, error) {
289
var conditions []string
290
var args []any
291
for _, filter := range filters {
···
39
return p
40
}
41
42
+
func GetRepos(e Execer, limit int, filters ...Filter) ([]Repo, error) {
43
repoMap := make(map[syntax.ATURI]*Repo)
44
45
var conditions []string
···
285
return repos, nil
286
}
287
288
+
func CountRepos(e Execer, filters ...Filter) (int64, error) {
289
var conditions []string
290
var args []any
291
for _, filter := range filters {
+5
-5
appview/db/spindle.go
+5
-5
appview/db/spindle.go
···
27
Created time.Time
28
}
29
30
-
func GetSpindles(e Execer, filters ...filter) ([]Spindle, error) {
31
var spindles []Spindle
32
33
var conditions []string
···
109
return err
110
}
111
112
-
func VerifySpindle(e Execer, filters ...filter) (int64, error) {
113
var conditions []string
114
var args []any
115
for _, filter := range filters {
···
132
return res.RowsAffected()
133
}
134
135
-
func DeleteSpindle(e Execer, filters ...filter) error {
136
var conditions []string
137
var args []any
138
for _, filter := range filters {
···
162
return err
163
}
164
165
-
func RemoveSpindleMember(e Execer, filters ...filter) error {
166
var conditions []string
167
var args []any
168
for _, filter := range filters {
···
181
return err
182
}
183
184
-
func GetSpindleMembers(e Execer, filters ...filter) ([]SpindleMember, error) {
185
var members []SpindleMember
186
187
var conditions []string
···
27
Created time.Time
28
}
29
30
+
func GetSpindles(e Execer, filters ...Filter) ([]Spindle, error) {
31
var spindles []Spindle
32
33
var conditions []string
···
109
return err
110
}
111
112
+
func VerifySpindle(e Execer, filters ...Filter) (int64, error) {
113
var conditions []string
114
var args []any
115
for _, filter := range filters {
···
132
return res.RowsAffected()
133
}
134
135
+
func DeleteSpindle(e Execer, filters ...Filter) error {
136
var conditions []string
137
var args []any
138
for _, filter := range filters {
···
162
return err
163
}
164
165
+
func RemoveSpindleMember(e Execer, filters ...Filter) error {
166
var conditions []string
167
var args []any
168
for _, filter := range filters {
···
181
return err
182
}
183
184
+
func GetSpindleMembers(e Execer, filters ...Filter) ([]SpindleMember, error) {
185
var members []SpindleMember
186
187
var conditions []string
+2
-2
appview/db/star.go
+2
-2
appview/db/star.go
···
102
}
103
}
104
105
-
func GetStars(e Execer, limit int, filters ...filter) ([]Star, error) {
106
var conditions []string
107
var args []any
108
for _, filter := range filters {
···
185
return stars, nil
186
}
187
188
-
func CountStars(e Execer, filters ...filter) (int64, error) {
189
var conditions []string
190
var args []any
191
for _, filter := range filters {
···
102
}
103
}
104
105
+
func GetStars(e Execer, limit int, filters ...Filter) ([]Star, error) {
106
var conditions []string
107
var args []any
108
for _, filter := range filters {
···
185
return stars, nil
186
}
187
188
+
func CountStars(e Execer, filters ...Filter) (int64, error) {
189
var conditions []string
190
var args []any
191
for _, filter := range filters {
+3
-3
appview/db/strings.go
+3
-3
appview/db/strings.go
···
123
return err
124
}
125
126
-
func GetStrings(e Execer, limit int, filters ...filter) ([]String, error) {
127
var all []String
128
129
var conditions []string
···
206
return all, nil
207
}
208
209
-
func CountStrings(e Execer, filters ...filter) (int64, error) {
210
var conditions []string
211
var args []any
212
for _, filter := range filters {
···
230
return count, nil
231
}
232
233
-
func DeleteString(e Execer, filters ...filter) error {
234
var conditions []string
235
var args []any
236
for _, filter := range filters {
···
123
return err
124
}
125
126
+
func GetStrings(e Execer, limit int, filters ...Filter) ([]String, error) {
127
var all []String
128
129
var conditions []string
···
206
return all, nil
207
}
208
209
+
func CountStrings(e Execer, filters ...Filter) (int64, error) {
210
var conditions []string
211
var args []any
212
for _, filter := range filters {
···
230
return count, nil
231
}
232
233
+
func DeleteString(e Execer, filters ...Filter) error {
234
var conditions []string
235
var args []any
236
for _, filter := range filters {
+1
appview/pages/pages.go
+1
appview/pages/pages.go
+33
-1
appview/pages/templates/repo/pipelines/pipelines.html
+33
-1
appview/pages/templates/repo/pipelines/pipelines.html
···
7
{{ end }}
8
9
{{ define "repoContent" }}
10
-
<div class="flex justify-between items-center gap-4">
11
<div class="w-full flex flex-col gap-2">
12
{{ range .Pipelines }}
13
{{ block "pipeline" (list $ .) }} {{ end }}
···
17
</p>
18
{{ end }}
19
</div>
20
</div>
21
{{ end }}
22
···
100
</div>
101
{{ end }}
102
{{ end }}
···
7
{{ end }}
8
9
{{ define "repoContent" }}
10
+
<div class="flex flex-col justify-between items-center gap-4">
11
<div class="w-full flex flex-col gap-2">
12
{{ range .Pipelines }}
13
{{ block "pipeline" (list $ .) }} {{ end }}
···
17
</p>
18
{{ end }}
19
</div>
20
+
{{ block "pagination" . }} {{ end }}
21
</div>
22
{{ end }}
23
···
101
</div>
102
{{ end }}
103
{{ end }}
104
+
105
+
{{ define "pagination" }}
106
+
{{ $currentPage := .Pagination.CurrentPage }}
107
+
<div class="flex place-self-end mt-4 gap-2">
108
+
{{ if gt $currentPage.No 0 }}
109
+
{{ $prev := .Pagination.PreviousPage }}
110
+
<a
111
+
class="btn flex items-center gap-2 no-underline hover:no-underline dark:text-white dark:hover:bg-gray-700"
112
+
hx-boost="true"
113
+
href = "/{{ $.RepoInfo.FullName }}/pipelines?page={{ add $prev.No 1 }}&count={{ $prev.Count }}"
114
+
>
115
+
{{ i "chevron-left" "w-4 h-4" }}
116
+
previous
117
+
</a>
118
+
{{ else }}
119
+
<div></div>
120
+
{{ end }}
121
+
122
+
{{ if lt (add $currentPage.No 1) .Pagination.TotalPageCount }}
123
+
{{ $next := .Pagination.NextPage }}
124
+
<a
125
+
class="btn flex items-center gap-2 no-underline hover:no-underline dark:text-white dark:hover:bg-gray-700"
126
+
hx-boost="true"
127
+
href = "/{{ $.RepoInfo.FullName }}/pipelines?page={{ add $next.No 1 }}&count={{ $next.Count }}"
128
+
>
129
+
next
130
+
{{ i "chevron-right" "w-4 h-4" }}
131
+
</a>
132
+
{{ end }}
133
+
</div>
134
+
{{ end }}
+29
-3
appview/pipelines/pipelines.go
+29
-3
appview/pipelines/pipelines.go
···
13
"tangled.sh/tangled.sh/core/appview/db"
14
"tangled.sh/tangled.sh/core/appview/oauth"
15
"tangled.sh/tangled.sh/core/appview/pages"
16
"tangled.sh/tangled.sh/core/appview/reporesolver"
17
"tangled.sh/tangled.sh/core/eventconsumer"
18
"tangled.sh/tangled.sh/core/idresolver"
···
71
}
72
73
repoInfo := f.RepoInfo(user)
74
-
75
-
ps, err := db.GetPipelineStatuses(
76
-
p.db,
77
db.FilterEq("repo_owner", repoInfo.OwnerDid),
78
db.FilterEq("repo_name", repoInfo.Name),
79
db.FilterEq("knot", repoInfo.Knot),
80
)
81
if err != nil {
82
l.Error("failed to query db", "err", err)
83
return
84
}
85
86
p.pages.Pipelines(w, pages.PipelinesParams{
87
LoggedInUser: user,
88
RepoInfo: repoInfo,
89
Pipelines: ps,
90
})
91
}
···
13
"tangled.sh/tangled.sh/core/appview/db"
14
"tangled.sh/tangled.sh/core/appview/oauth"
15
"tangled.sh/tangled.sh/core/appview/pages"
16
+
"tangled.sh/tangled.sh/core/appview/pagination"
17
"tangled.sh/tangled.sh/core/appview/reporesolver"
18
"tangled.sh/tangled.sh/core/eventconsumer"
19
"tangled.sh/tangled.sh/core/idresolver"
···
72
}
73
74
repoInfo := f.RepoInfo(user)
75
+
filters := []db.Filter{
76
db.FilterEq("repo_owner", repoInfo.OwnerDid),
77
db.FilterEq("repo_name", repoInfo.Name),
78
db.FilterEq("knot", repoInfo.Knot),
79
+
}
80
+
81
+
page, ok := r.Context().Value("page").(pagination.Page)
82
+
if !ok {
83
+
l.Error("failed to get page")
84
+
page = pagination.Page{No: 0, Count: 16}
85
+
}
86
+
pipelinesCount, err := db.GetPipelineCount(p.db, filters...)
87
+
if err != nil {
88
+
l.Error("failed to get pipeline count", "err", err)
89
+
p.pages.Notice(w, "pipelines", "Failed to load pipelines. Try again later.")
90
+
return
91
+
}
92
+
paginate := pagination.NewFromPage(page, pipelinesCount)
93
+
94
+
currentPage := paginate.CurrentPage()
95
+
filters = append(filters, db.FilterBetween(
96
+
"row_num",
97
+
currentPage.Count*currentPage.No+1,
98
+
currentPage.Count*(currentPage.No+1),
99
+
))
100
+
101
+
ps, err := db.GetPipelineStatuses(
102
+
p.db,
103
+
filters...,
104
)
105
if err != nil {
106
l.Error("failed to query db", "err", err)
107
+
p.pages.Notice(w, "pipelines", "Failed to load pipelines. Try again later.")
108
return
109
}
110
111
p.pages.Pipelines(w, pages.PipelinesParams{
112
LoggedInUser: user,
113
RepoInfo: repoInfo,
114
+
Pagination: paginate,
115
Pipelines: ps,
116
})
117
}
+1
-1
appview/pipelines/router.go
+1
-1
appview/pipelines/router.go