/
pp_pair.go
145 lines (130 loc) · 3.6 KB
/
pp_pair.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package types
import (
"errors"
"fmt"
"time"
"github.com/gbl08ma/sqalx"
sq "github.com/Masterminds/squirrel"
)
// PPPair is a PosPlay pair
type PPPair struct {
DiscordID uint64
Pair *APIPair
Paired time.Time
DeviceName string
}
// GetPPPairs returns a slice with all registered pairs
func GetPPPairs(node sqalx.Node) ([]*PPPair, error) {
return getPPPairsWithSelect(node, sdb.Select())
}
func getPPPairsWithSelect(node sqalx.Node, sbuilder sq.SelectBuilder) ([]*PPPair, error) {
pairs := []*PPPair{}
tx, err := node.Beginx()
if err != nil {
return pairs, err
}
defer tx.Commit() // read-only tx
rows, err := sbuilder.Columns("pp_pair.discord_id", "pp_pair.api_key",
"pp_pair.paired", "pp_pair.device_name").
From("pp_pair").
RunWith(tx).Query()
if err != nil {
return pairs, fmt.Errorf("getPPPairsWithSelect: %s", err)
}
apiPairs := []string{}
for rows.Next() {
var pair PPPair
var apiPair string
err := rows.Scan(
&pair.DiscordID,
&apiPair,
&pair.Paired,
&pair.DeviceName)
if err != nil {
rows.Close()
return pairs, fmt.Errorf("getPPPairsWithSelect: %s", err)
}
apiPairs = append(apiPairs, apiPair)
pairs = append(pairs, &pair)
}
if err := rows.Err(); err != nil {
rows.Close()
return pairs, fmt.Errorf("getPPPairsWithSelect: %s", err)
}
rows.Close()
for i := range pairs {
pairs[i].Pair, err = GetPair(tx, apiPairs[i])
if err != nil {
return pairs, fmt.Errorf("getPPPairsWithSelect: %s", err)
}
}
return pairs, nil
}
// GetPPPair returns the pair with the given Discord ID
func GetPPPair(node sqalx.Node, discordID uint64) (*PPPair, error) {
if value, present := node.Load(getCacheKey("pp_pair", fmt.Sprintf("%d", discordID))); present {
return value.(*PPPair), nil
}
s := sdb.Select().
Where(sq.Eq{"discord_id": discordID})
pairs, err := getPPPairsWithSelect(node, s)
if err != nil {
return nil, err
}
if len(pairs) == 0 {
return nil, errors.New("PPPair not found")
}
node.Store(getCacheKey("pp_pair", fmt.Sprintf("%d", discordID)), pairs[0])
return pairs[0], nil
}
// GetPPPairForKey returns the pair with the given Discord ID
func GetPPPairForKey(node sqalx.Node, apiKey string) (*PPPair, error) {
if value, present := node.Load(getCacheKey("pp_pair_key", apiKey)); present {
return value.(*PPPair), nil
}
s := sdb.Select().
Where(sq.Eq{"api_key": apiKey})
pairs, err := getPPPairsWithSelect(node, s)
if err != nil {
return nil, err
}
if len(pairs) == 0 {
return nil, errors.New("PPPair not found")
}
node.Store(getCacheKey("pp_pair_key", apiKey), pairs[0])
return pairs[0], nil
}
// Update adds or updates the PPPair
func (pair *PPPair) Update(node sqalx.Node) error {
tx, err := node.Beginx()
if err != nil {
return err
}
defer tx.Rollback()
_, err = sdb.Insert("pp_pair").
Columns("discord_id", "api_key", "paired", "device_name").
Values(pair.DiscordID, pair.Pair.Key, pair.Paired, pair.DeviceName).
Suffix("ON CONFLICT (discord_id) DO UPDATE SET api_key = ?, paired = ?, device_name = ?",
pair.Pair.Key, pair.Paired, pair.DeviceName).
RunWith(tx).Exec()
if err != nil {
return errors.New("AddPPair: " + err.Error())
}
return tx.Commit()
}
// Delete deletes the PPPair
func (pair *PPPair) Delete(node sqalx.Node) error {
tx, err := node.Beginx()
if err != nil {
return err
}
defer tx.Rollback()
_, err = sdb.Delete("pp_pair").
Where(sq.Eq{"discord_id": pair.DiscordID}).RunWith(tx).Exec()
if err != nil {
return fmt.Errorf("RemovePPPair: %s", err)
}
tx.Delete(getCacheKey("pp_pair", fmt.Sprintf("%d", pair.DiscordID)))
tx.Delete(getCacheKey("pp_pair_key", pair.Pair.Key))
return tx.Commit()
}