-
Notifications
You must be signed in to change notification settings - Fork 394
/
partners_staticdb.go
95 lines (80 loc) · 2.58 KB
/
partners_staticdb.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
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package rewards
import (
"context"
"sort"
"strings"
"github.com/zeebo/errs"
)
// PartnersStaticDB implements partner lookup based on a static definition.
//
// architecture: Database Implementation
type PartnersStaticDB struct {
list *PartnerList
byName map[string]PartnerInfo
byID map[string]PartnerInfo
byUserAgent map[string]PartnerInfo
}
var _ PartnersDB = (*PartnersStaticDB)(nil)
// NewPartnersStaticDB creates a new PartnersStaticDB.
func NewPartnersStaticDB(list *PartnerList) (*PartnersStaticDB, error) {
db := &PartnersStaticDB{
list: list,
byName: map[string]PartnerInfo{},
byID: map[string]PartnerInfo{},
byUserAgent: map[string]PartnerInfo{},
}
sort.Slice(list.Partners, func(i, k int) bool {
return list.Partners[i].Name < list.Partners[k].Name
})
var errg errs.Group
for _, p := range list.Partners {
name := strings.ToLower(p.Name)
if _, exists := db.byName[name]; exists {
errg.Add(ErrPartners.New("name %q already exists", p.Name))
} else {
db.byName[name] = p
}
if _, exists := db.byID[p.ID]; exists {
errg.Add(ErrPartners.New("id %q already exists", p.ID))
} else {
db.byID[p.ID] = p
}
useragent := CanonicalUserAgentProduct(p.UserAgent())
if _, exists := db.byUserAgent[useragent]; exists {
errg.Add(ErrPartners.New("user agent %q already exists", useragent))
} else {
db.byUserAgent[useragent] = p
}
}
return db, errg.Err()
}
// All returns all partners.
func (db *PartnersStaticDB) All(ctx context.Context) ([]PartnerInfo, error) {
return append([]PartnerInfo{}, db.list.Partners...), nil
}
// ByName returns partner definitions for a given name. Name is case insensitive.
func (db *PartnersStaticDB) ByName(ctx context.Context, name string) (PartnerInfo, error) {
partner, ok := db.byName[strings.ToLower(name)]
if !ok {
return PartnerInfo{}, ErrPartnerNotExist.New("%q", name)
}
return partner, nil
}
// ByID returns partner definition corresponding to an id.
func (db *PartnersStaticDB) ByID(ctx context.Context, id string) (PartnerInfo, error) {
partner, ok := db.byID[id]
if !ok {
return PartnerInfo{}, ErrPartnerNotExist.New("%q", id)
}
return partner, nil
}
// ByUserAgent returns partner definition corresponding to an user agent product string.
func (db *PartnersStaticDB) ByUserAgent(ctx context.Context, agent string) (PartnerInfo, error) {
partner, ok := db.byUserAgent[CanonicalUserAgentProduct(agent)]
if !ok {
return PartnerInfo{}, ErrPartnerNotExist.New("%q", agent)
}
return partner, nil
}