-
Notifications
You must be signed in to change notification settings - Fork 4
/
session.go
129 lines (120 loc) · 3.38 KB
/
session.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package sql
import (
"context"
"fmt"
"time"
"github.com/jmoiron/sqlx"
"github.com/williamsjokvist/cfn-tracker/pkg/model"
)
type SessionStorage interface {
CreateSession(ctx context.Context, userId string) error
GetSessions(ctx context.Context, userId string, limit uint8, offset uint16) ([]*model.Session, error)
UpdateLatestSession(ctx context.Context, userId string) error
}
func (s *Storage) CreateSession(ctx context.Context, userId string) (*model.Session, error) {
sesh := model.Session{
UserId: userId,
CreatedAt: time.Now().Format(time.RFC3339),
}
query := `
INSERT OR IGNORE INTO sessions (user_id, created_at)
VALUES (:user_id, :created_at)
`
res, err := s.db.NamedExecContext(ctx, query, sesh)
if err != nil {
return nil, fmt.Errorf("create session: %w", err)
}
lastInsertId, err := res.LastInsertId()
if err != nil {
return nil, err
}
sesh.Id = uint16(lastInsertId)
return &sesh, nil
}
func (s *Storage) GetSessions(ctx context.Context, userId string, limit uint8, offset uint16) ([]*model.Session, error) {
pagination := ``
if limit != 0 || offset != 0 {
pagination = fmt.Sprintf(`LIMIT %d OFFSET %d`, limit, offset)
}
where := ``
var whereArgs []interface{}
if userId != "" {
where = `WHERE s.user_id = (?)`
whereArgs = append(whereArgs, userId)
}
query, args, err := sqlx.In(fmt.Sprintf(`
SELECT
s.id,
s.created_at,
u.display_name as user_name,
s.user_id,
COUNT(IIF(m.victory, 1, NULL)) as matches_won,
COUNT(IIF(m.victory = false, 1, NULL)) as matches_lost,
m.lp as starting_lp,
s.lp as ending_lp,
(s.lp - m.lp) as lp_gain,
m.mr as starting_mr,
s.mr as ending_mr,
(s.mr - m.mr) as mr_gain
FROM sessions as s
JOIN users u on u.code = s.user_id
JOIN matches m on s.id = m.session_id
%s
GROUP BY s.id
ORDER BY s.id DESC
%s
`, where, pagination), whereArgs...)
if err != nil {
return nil, fmt.Errorf("prepare get sessions query: %w", err)
}
var sessions []*model.Session
err = s.db.SelectContext(ctx, &sessions, query, args...)
if err != nil {
return nil, fmt.Errorf("excute get sessions query: %w", err)
}
return sessions, nil
}
func (s *Storage) updateLatestSession(ctx context.Context, lp, mr int, sessionId uint16) error {
query, args, err := sqlx.In(`
UPDATE sessions
SET
lp = ?,
mr = ?
WHERE id = (?)
`, lp, mr, sessionId)
if err != nil {
return fmt.Errorf("prepare update session query: %w", err)
}
_, err = s.db.ExecContext(ctx, s.db.Rebind(query), args...)
if err != nil {
return fmt.Errorf("excute update last session query: %w", err)
}
return nil
}
func (s *Storage) UpdateSession(ctx context.Context, sesh *model.Session, match model.Match, sessionId uint16) error {
err := s.updateLatestSession(ctx, sesh.LP, sesh.MR, sessionId)
if err != nil {
return fmt.Errorf("update session: %w", err)
}
err = s.SaveMatch(ctx, match)
if err != nil {
return fmt.Errorf("save match in storage: %w", err)
}
return nil
}
func (s *Storage) GetLatestSession(ctx context.Context, userId string) (*model.Session, error) {
sessions, err := s.GetSessions(ctx, userId, 1, 0)
if err != nil {
return nil, fmt.Errorf("get session: %w", err)
}
if len(sessions) == 0 {
return nil, nil
}
sesh := sessions[0]
matches, err := s.GetMatches(ctx, sesh.Id, userId, 0, 0)
if err != nil {
return nil, fmt.Errorf("failed to get matches by session: %w", err)
}
sesh.Matches = matches
return sesh, nil
}