@@ -4,12 +4,14 @@ import (
4
4
"context"
5
5
"database/sql"
6
6
"fmt"
7
+ "strconv"
7
8
"strings"
8
9
"time"
9
10
10
11
"github.com/go-redis/redis"
11
12
"github.com/pkg/errors"
12
13
"github.com/volatiletech/sqlboiler/boil"
14
+ "github.com/volatiletech/sqlboiler/queries/qm"
13
15
14
16
"github.com/ProgrammingLab/prolab-accounts/infra/record"
15
17
"github.com/ProgrammingLab/prolab-accounts/infra/store"
@@ -33,15 +35,15 @@ func NewGitHubStore(ctx context.Context, db *sqlutil.DB, cli *redis.Client) stor
33
35
}
34
36
35
37
const (
36
- contributionTotalCount = "contributions-total-count"
38
+ contributionTotalCountKey = "contributions-total-count"
37
39
)
38
40
39
41
func (s * githubStoreImpl ) UpdateContributionDays (c * model.GitHubContributionCollection ) ([]* record.GithubContributionDay , error ) {
40
42
z := redis.Z {
41
43
Score : float64 (c .TotalCount ),
42
44
Member : int64 (c .UserID ),
43
45
}
44
- err := s .cli .ZAdd (contributionTotalCount , z ).Err ()
46
+ err := s .cli .ZAdd (contributionTotalCountKey , z ).Err ()
45
47
if err != nil {
46
48
return nil , errors .WithStack (err )
47
49
}
@@ -64,6 +66,77 @@ func (s *githubStoreImpl) UpdateContributionDays(c *model.GitHubContributionColl
64
66
return days , nil
65
67
}
66
68
69
+ func (s * githubStoreImpl ) ListContributionCollections (usersLimit int ) ([]* model.GitHubContributionCollection , error ) {
70
+ cols , err := s .getTopUsers (usersLimit )
71
+ if err != nil {
72
+ return nil , err
73
+ }
74
+
75
+ err = s .loadDays (cols )
76
+ if err != nil {
77
+ return nil , err
78
+ }
79
+
80
+ return cols , nil
81
+ }
82
+
83
+ func (s * githubStoreImpl ) getTopUsers (usersLimit int ) ([]* model.GitHubContributionCollection , error ) {
84
+ values , err := s .cli .ZRevRangeWithScores (contributionTotalCountKey , 0 , int64 (usersLimit )- 1 ).Result ()
85
+ if err != nil {
86
+ return nil , errors .WithStack (err )
87
+ }
88
+
89
+ cols := make ([]* model.GitHubContributionCollection , 0 , len (values ))
90
+ for _ , v := range values {
91
+ id , err := strconv .ParseInt (v .Member .(string ), 10 , 64 )
92
+ if err != nil {
93
+ return nil , errors .WithStack (err )
94
+ }
95
+ col := & model.GitHubContributionCollection {
96
+ UserID : model .UserID (id ),
97
+ TotalCount : int (v .Score ),
98
+ }
99
+ cols = append (cols , col )
100
+ }
101
+
102
+ return cols , nil
103
+ }
104
+
105
+ func (s * githubStoreImpl ) loadDays (cols []* model.GitHubContributionCollection ) error {
106
+ userIDs := make ([]int64 , 0 , len (cols ))
107
+ for _ , c := range cols {
108
+ userIDs = append (userIDs , int64 (c .UserID ))
109
+ }
110
+
111
+ mods := []qm.QueryMod {
112
+ qm .Load ("User.Profile.Department" ),
113
+ qm .Load ("User.Profile.Role" ),
114
+ qm .From ("github_contribution_days as days" ),
115
+ qm .InnerJoin ("users on users.id = days.user_id" ),
116
+ qm .InnerJoin ("profiles on profiles.id = users.profile_id" ),
117
+ qm .Where ("profiles.profile_scope = ?" , model .Public ),
118
+ qm .WhereIn ("users.id in ?" , sqlutil .Int64SliceToAbstractSlice (userIDs )... ),
119
+ qm .OrderBy ("days.date" ),
120
+ }
121
+ var days []* record.GithubContributionDay
122
+ err := record .NewQuery (mods ... ).Bind (s .ctx , s .db , & days )
123
+ if err != nil {
124
+ return errors .WithStack (err )
125
+ }
126
+
127
+ daysMap := make (map [model.UserID ][]* record.GithubContributionDay , len (cols ))
128
+ for _ , d := range days {
129
+ id := model .UserID (d .UserID )
130
+ daysMap [id ] = append (daysMap [id ], d )
131
+ }
132
+
133
+ for _ , c := range cols {
134
+ c .Days = daysMap [c .UserID ]
135
+ }
136
+
137
+ return nil
138
+ }
139
+
67
140
func bulkInsert (ctx context.Context , tx * sql.Tx , days []* record.GithubContributionDay ) error {
68
141
if len (days ) == 0 {
69
142
return nil
0 commit comments