/
sessions.go
88 lines (77 loc) · 2.3 KB
/
sessions.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
package database
import (
"database/sql"
"errors"
app "github.com/emilhauk/chitchat/internal"
"github.com/emilhauk/chitchat/internal/model"
"time"
)
type Sessions struct {
db *sql.DB
create *sql.Stmt
findById *sql.Stmt
updateLastSeenAt *sql.Stmt
delete *sql.Stmt
}
func NewSessionStore(db *sql.DB) Sessions {
create, err := db.Prepare("INSERT INTO sessions (id, user_uuid, created_at, last_seen_at) VALUE (?, ?, ?, ?)")
if err != nil {
log.Fatal().Err(err).Msgf("Failed to prepare statement for sessions.create")
}
findById, err := db.Prepare("SELECT id, user_uuid, created_at, last_seen_at FROM sessions WHERE id = ?")
if err != nil {
log.Fatal().Err(err).Msgf("Failed to prepare statement for sessions.findById")
}
updateLastSeenAt, err := db.Prepare("UPDATE sessions SET last_seen_at = ? WHERE id = ?")
if err != nil {
log.Fatal().Err(err).Msgf("Failed to prepare statement for sessions.updateLastSeenAt")
}
remove, err := db.Prepare("DELETE FROM sessions WHERE id = ?")
if err != nil {
log.Fatal().Err(err).Msgf("Failed to prepare statement for sessions.remove")
}
return Sessions{
db: db,
create: create,
findById: findById,
updateLastSeenAt: updateLastSeenAt,
delete: remove,
}
}
func (s Sessions) Create(m model.Session) error {
_, err := s.create.Exec(m.ID, m.UserUUID, m.CreatedAt, m.LastSeenAt)
return err
}
func (s Sessions) FindByID(id string) (model.Session, error) {
session, err := s.mapToSession(s.findById.QueryRow(id))
if err != nil && errors.Is(err, sql.ErrNoRows) {
return session, errors.Join(app.ErrSessionNotFound, err)
}
return session, err
}
func (s Sessions) SetLastSeenAt(id string, lastSeenAt time.Time) error {
_, err := s.updateLastSeenAt.Exec(lastSeenAt, id)
return err
}
func (s Sessions) Delete(id string) error {
_, err := s.delete.Exec(id)
return err
}
func (s Sessions) mapToSession(row interface{ Scan(...any) error }) (model.Session, error) {
var (
id string
userUUID string
createdAt time.Time
lastSeenAt sql.NullTime
)
err := row.Scan(&id, &userUUID, &createdAt, &lastSeenAt)
session := model.Session{
ID: id,
UserUUID: userUUID,
CreatedAt: createdAt,
}
if lastSeenAt.Valid {
session.LastSeenAt = &lastSeenAt.Time
}
return session, err
}