-
Notifications
You must be signed in to change notification settings - Fork 0
/
group.go
90 lines (80 loc) · 1.69 KB
/
group.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
package store
import (
"database/sql"
"fmt"
)
//go:generate counterfeiter -o fakes/group_repo.go --fake-name GroupRepo . GroupRepo
type GroupRepo interface {
Create(Transaction, string) (int, error)
Delete(Transaction, int) error
GetID(Transaction, string) (int, error)
}
type GroupTable struct {
}
func (g *GroupTable) Create(tx Transaction, guid string) (int, error) {
id, err := g.findRowByGUID(tx, guid)
if err != nil {
if err == sql.ErrNoRows {
id, err = g.firstBlankRow(tx)
if err != nil {
return -1, fmt.Errorf("failed to find available tag: %s", err.Error())
} else {
err = g.updateRow(tx, id, guid)
if err != nil {
return -1, err
}
return id, nil
}
}
return -1, err
}
return id, nil
}
func (g *GroupTable) findRowByGUID(tx Transaction, guid string) (int, error) {
var id int
err := tx.QueryRow(
tx.Rebind(`
SELECT id FROM groups
WHERE guid = ?
`),
guid,
).Scan(&id)
return id, err
}
func (g *GroupTable) firstBlankRow(tx Transaction) (int, error) {
var id int
err := tx.QueryRow(
`SELECT id FROM groups
WHERE guid is NULL
ORDER BY id
LIMIT 1
FOR UPDATE
`).Scan(&id)
return id, err
}
func (g *GroupTable) updateRow(tx Transaction, id int, guid string) error {
_, err := tx.Exec(
tx.Rebind(`
UPDATE groups SET guid = ?
WHERE id = ?
`),
guid,
id,
)
return err
}
func (g *GroupTable) Delete(tx Transaction, id int) error {
_, err := tx.Exec(
tx.Rebind(`UPDATE groups SET guid = NULL WHERE id = ?`),
id,
)
return err
}
func (g *GroupTable) GetID(tx Transaction, guid string) (int, error) {
var id int
err := tx.QueryRow(
tx.Rebind(`SELECT id FROM groups WHERE guid = ?`),
guid,
).Scan(&id)
return id, err
}