/
keyvalue.go
102 lines (89 loc) · 2.65 KB
/
keyvalue.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
// Copyright 2017 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.
package sqlstore
import (
"database/sql"
"time"
"golang.org/x/net/context"
errgo "gopkg.in/errgo.v1"
"github.com/CanonicalLtd/blues-identity/store"
)
// A providerDataStore implements store.ProviderDataStore.
type providerDataStore struct {
db *Database
}
func (s *providerDataStore) KeyValueStore(_ context.Context, idp string) (store.KeyValueStore, error) {
return &keyValueStore{
Database: s.db,
idp: idp,
}, nil
}
// A keyValueStore implements store.KeyValueStore.
type keyValueStore struct {
*Database
idp string
}
// Context implements idp.KeyValueStore.Context.
func (s *keyValueStore) Context(ctx context.Context) (context.Context, func()) {
return ctx, func() {}
}
type providerDataParams struct {
argBuilder
Provider string
Key string
Value []byte
Expire nullTime
Update bool
}
// Get implements store.KeyValueStore.Get by selecting the blob with the
// given key from the provider_data table.
func (s *keyValueStore) Get(_ context.Context, key string) ([]byte, error) {
params := &providerDataParams{
argBuilder: s.driver.argBuilderFunc(),
Provider: s.idp,
Key: key,
}
var value []byte
row, err := s.driver.queryRow(s.db, tmplGetProviderData, params)
if err != nil {
return nil, errgo.Mask(err)
}
if err := row.Scan(&value); err != nil {
if errgo.Cause(err) == sql.ErrNoRows {
return nil, store.KeyNotFoundError(key)
}
return nil, errgo.Mask(err)
}
return value, nil
}
// Set implements store.KeyValueStore.Set by upserting the blob with the
// given key, value and expire time into the provider_data table.
func (s *keyValueStore) Set(_ context.Context, key string, value []byte, expire time.Time) error {
params := &providerDataParams{
argBuilder: s.driver.argBuilderFunc(),
Provider: s.idp,
Key: key,
Value: value,
Expire: nullTime{expire, !expire.IsZero()},
Update: true,
}
_, err := s.driver.exec(s.db, tmplInsertProviderData, params)
return errgo.Mask(err)
}
// Add implements store.KeyValueStore.Add by inserting a blob with the
// given key, value and expire time into the provider_data table.
func (s *keyValueStore) Add(_ context.Context, key string, value []byte, expire time.Time) error {
params := &providerDataParams{
argBuilder: s.driver.argBuilderFunc(),
Provider: s.idp,
Key: key,
Value: value,
Expire: nullTime{expire, !expire.IsZero()},
Update: false,
}
_, err := s.driver.exec(s.db, tmplInsertProviderData, params)
if s.driver.isDuplicateFunc(errgo.Cause(err)) {
return store.DuplicateKeyError(key)
}
return errgo.Mask(err)
}