Skip to content

Commit 27e97e9

Browse files
committed
Implement dbfake
1 parent e207782 commit 27e97e9

File tree

1 file changed

+128
-1
lines changed

1 file changed

+128
-1
lines changed

coderd/database/dbfake/dbfake.go

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2822,7 +2822,134 @@ func (q *FakeQuerier) GetUserActivityInsights(ctx context.Context, arg database.
28222822
return nil, err
28232823
}
28242824

2825-
panic("not implemented")
2825+
q.mutex.RLock()
2826+
defer q.mutex.RUnlock()
2827+
2828+
type uniqueKey struct {
2829+
TemplateID uuid.UUID
2830+
UserID uuid.UUID
2831+
}
2832+
2833+
combinedStats := make(map[uniqueKey]map[time.Time]int64)
2834+
2835+
// Get application stats
2836+
for _, s := range q.workspaceAppStats {
2837+
if !(((s.SessionStartedAt.After(arg.StartTime) || s.SessionStartedAt.Equal(arg.StartTime)) && s.SessionStartedAt.Before(arg.EndTime)) ||
2838+
(s.SessionEndedAt.After(arg.StartTime) && s.SessionEndedAt.Before(arg.EndTime)) ||
2839+
(s.SessionStartedAt.Before(arg.StartTime) && (s.SessionEndedAt.After(arg.EndTime) || s.SessionEndedAt.Equal(arg.EndTime)))) {
2840+
continue
2841+
}
2842+
2843+
w, err := q.getWorkspaceByIDNoLock(ctx, s.WorkspaceID)
2844+
if err != nil {
2845+
return nil, err
2846+
}
2847+
2848+
if len(arg.TemplateIDs) > 0 && !slices.Contains(arg.TemplateIDs, w.TemplateID) {
2849+
continue
2850+
}
2851+
2852+
key := uniqueKey{
2853+
TemplateID: w.TemplateID,
2854+
UserID: s.UserID,
2855+
}
2856+
if combinedStats[key] == nil {
2857+
combinedStats[key] = make(map[time.Time]int64)
2858+
}
2859+
2860+
t := s.SessionStartedAt.Truncate(5 * time.Minute)
2861+
if t.Before(arg.StartTime) {
2862+
t = arg.StartTime
2863+
}
2864+
for t.Before(s.SessionEndedAt) && t.Before(arg.EndTime) {
2865+
combinedStats[key][t] = 60
2866+
t = t.Add(1 * time.Minute)
2867+
}
2868+
}
2869+
2870+
// Get session stats
2871+
for _, s := range q.workspaceAgentStats {
2872+
if s.CreatedAt.Before(arg.StartTime) || s.CreatedAt.Equal(arg.EndTime) || s.CreatedAt.After(arg.EndTime) {
2873+
continue
2874+
}
2875+
if len(arg.TemplateIDs) > 0 && !slices.Contains(arg.TemplateIDs, s.TemplateID) {
2876+
continue
2877+
}
2878+
if s.ConnectionCount == 0 {
2879+
continue
2880+
}
2881+
2882+
key := uniqueKey{
2883+
TemplateID: s.TemplateID,
2884+
UserID: s.UserID,
2885+
}
2886+
2887+
if combinedStats[key] == nil {
2888+
combinedStats[key] = make(map[time.Time]int64)
2889+
}
2890+
2891+
if s.SessionCountJetBrains > 0 || s.SessionCountVSCode > 0 || s.SessionCountReconnectingPTY > 0 || s.SessionCountSSH > 0 {
2892+
t := s.CreatedAt.Truncate(time.Minute)
2893+
combinedStats[key][t] = 60
2894+
}
2895+
}
2896+
2897+
// Use temporary maps for aggregation purposes
2898+
mUserIDTemplateIDs := map[uuid.UUID]map[uuid.UUID]struct{}{}
2899+
mUserIDUsageSeconds := map[uuid.UUID]int64{}
2900+
2901+
for key, times := range combinedStats {
2902+
if mUserIDTemplateIDs[key.UserID] == nil {
2903+
mUserIDTemplateIDs[key.UserID] = make(map[uuid.UUID]struct{})
2904+
mUserIDUsageSeconds[key.UserID] = 0
2905+
}
2906+
2907+
if _, ok := mUserIDTemplateIDs[key.UserID][key.TemplateID]; !ok {
2908+
mUserIDTemplateIDs[key.UserID][key.TemplateID] = struct{}{}
2909+
}
2910+
2911+
for _, t := range times {
2912+
mUserIDUsageSeconds[key.UserID] += t
2913+
}
2914+
}
2915+
2916+
userIDs := make([]uuid.UUID, 0, len(mUserIDUsageSeconds))
2917+
for userID := range mUserIDUsageSeconds {
2918+
userIDs = append(userIDs, userID)
2919+
}
2920+
sort.Slice(userIDs, func(i, j int) bool {
2921+
return userIDs[i].String() < userIDs[j].String()
2922+
})
2923+
2924+
// Finally, select stats
2925+
var rows []database.GetUserActivityInsightsRow
2926+
2927+
for _, userID := range userIDs {
2928+
user, err := q.getUserByIDNoLock(userID)
2929+
if err != nil {
2930+
return nil, err
2931+
}
2932+
2933+
tids := mUserIDTemplateIDs[userID]
2934+
templateIDs := make([]uuid.UUID, 0, len(tids))
2935+
for key := range tids {
2936+
templateIDs = append(templateIDs, key)
2937+
}
2938+
sort.Slice(templateIDs, func(i, j int) bool {
2939+
return templateIDs[i].String() < templateIDs[j].String()
2940+
})
2941+
2942+
row := database.GetUserActivityInsightsRow{
2943+
UserID: user.ID,
2944+
Username: user.Username,
2945+
AvatarURL: user.AvatarURL,
2946+
TemplateIDs: templateIDs,
2947+
UsageSeconds: mUserIDUsageSeconds[userID],
2948+
}
2949+
2950+
rows = append(rows, row)
2951+
}
2952+
return rows, nil
28262953
}
28272954

28282955
func (q *FakeQuerier) GetUserByEmailOrUsername(_ context.Context, arg database.GetUserByEmailOrUsernameParams) (database.User, error) {

0 commit comments

Comments
 (0)