• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

go-pkgz / auth / 7255079117

18 Dec 2023 11:27PM UTC coverage: 82.941%. Remained the same
7255079117

Pull #189

github

web-flow
Bump golang.org/x/crypto from 0.14.0 to 0.17.0 in /_example

Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.14.0 to 0.17.0.
- [Commits](https://github.com/golang/crypto/compare/v0.14.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #189: Bump golang.org/x/crypto from 0.14.0 to 0.17.0 in /_example

2572 of 3101 relevant lines covered (82.94%)

6.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.71
/avatar/bolt.go
1
package avatar
2

3
import (
4
        "bytes"
5
        "fmt"
6
        "io"
7
        "log"
8

9
        bolt "go.etcd.io/bbolt"
10
)
11

12
// BoltDB implements avatar store with bolt
13
// using separate db (file) with "avatars" bucket to keep image bin and "metas" bucket
14
// to keep sha1 of picture. avatarID (base file name) used as a key for both.
15
type BoltDB struct {
16
        fileName string // full path to boltdb
17
        db       *bolt.DB
18
}
19

20
const avatarsBktName = "avatars"
21
const metasBktName = "metas"
22

23
// NewBoltDB makes bolt avatar store
24
func NewBoltDB(fileName string, options bolt.Options) (*BoltDB, error) {
5✔
25
        db, err := bolt.Open(fileName, 0600, &options) //nolint
5✔
26
        if err != nil {
5✔
27
                return nil, fmt.Errorf("failed to make boltdb for %s: %w", fileName, err)
×
28
        }
×
29
        err = db.Update(func(tx *bolt.Tx) error {
10✔
30
                if _, e := tx.CreateBucketIfNotExists([]byte(avatarsBktName)); e != nil {
5✔
31
                        return fmt.Errorf("failed to create top level bucket %s: %w", avatarsBktName, e)
×
32
                }
×
33
                if _, e := tx.CreateBucketIfNotExists([]byte(metasBktName)); e != nil {
5✔
34
                        return fmt.Errorf("failed to create top metas bucket %s: %w", metasBktName, e)
×
35
                }
×
36
                return nil
5✔
37
        })
38
        if err != nil {
5✔
39
                return nil, fmt.Errorf("failed to initialize boltdb db %q buckets: %w", fileName, err)
×
40
        }
×
41
        return &BoltDB{db: db, fileName: fileName}, nil
5✔
42
}
43

44
// Put avatar to bolt, key by avatarID. Trying to resize image and lso calculates sha1 of the file for ID func
45
func (b *BoltDB) Put(userID string, reader io.Reader) (avatar string, err error) {
5✔
46
        id := encodeID(userID)
5✔
47

5✔
48
        avatarID := id + imgSfx
5✔
49
        err = b.db.Update(func(tx *bolt.Tx) error {
10✔
50
                buf := &bytes.Buffer{}
5✔
51
                if _, err = io.Copy(buf, reader); err != nil {
5✔
52
                        return fmt.Errorf("can't read avatar %s: %w", avatarID, err)
×
53
                }
×
54

55
                if err = tx.Bucket([]byte(avatarsBktName)).Put([]byte(avatarID), buf.Bytes()); err != nil {
5✔
56
                        return fmt.Errorf("can't put to bucket with %s: %w", avatarID, err)
×
57
                }
×
58
                // store sha1 of the image
59
                return tx.Bucket([]byte(metasBktName)).Put([]byte(avatarID), []byte(hash(buf.Bytes(), avatarID)))
5✔
60
        })
61
        return avatarID, err
5✔
62
}
63

64
// Get avatar reader for avatar id.image, avatarID used as the direct key
65
func (b *BoltDB) Get(avatarID string) (reader io.ReadCloser, size int, err error) {
3✔
66
        buf := &bytes.Buffer{}
3✔
67
        err = b.db.View(func(tx *bolt.Tx) error {
6✔
68
                data := tx.Bucket([]byte(avatarsBktName)).Get([]byte(avatarID))
3✔
69
                if data == nil {
4✔
70
                        return fmt.Errorf("can't load avatar %s", avatarID)
1✔
71
                }
1✔
72
                size, err = buf.Write(data)
2✔
73
                if err != nil {
2✔
74
                        return fmt.Errorf("failed to write for %s: %w", avatarID, err)
×
75
                }
×
76
                return nil
2✔
77
        })
78
        return io.NopCloser(buf), size, err
3✔
79
}
80

81
// ID returns a fingerprint of the avatar content.
82
func (b *BoltDB) ID(avatarID string) (id string) {
2✔
83
        data := []byte{}
2✔
84
        err := b.db.View(func(tx *bolt.Tx) error {
4✔
85
                if data = tx.Bucket([]byte(metasBktName)).Get([]byte(avatarID)); data == nil {
3✔
86
                        return fmt.Errorf("can't load avatar's id for %s", avatarID)
1✔
87
                }
1✔
88
                return nil
1✔
89
        })
90

91
        if err != nil { // failed to get ID, use encoded avatarID
3✔
92
                log.Printf("[DEBUG] can't get avatar info '%s', %s", avatarID, err)
1✔
93
                return encodeID(avatarID)
1✔
94
        }
1✔
95

96
        return string(data)
1✔
97
}
98

99
// Remove avatar from bolt
100
func (b *BoltDB) Remove(avatarID string) (err error) {
3✔
101
        return b.db.Update(func(tx *bolt.Tx) error {
6✔
102
                bkt := tx.Bucket([]byte(avatarsBktName))
3✔
103
                if bkt.Get([]byte(avatarID)) == nil {
5✔
104
                        return fmt.Errorf("avatar key not found, %s", avatarID)
2✔
105
                }
2✔
106
                if err = tx.Bucket([]byte(avatarsBktName)).Delete([]byte(avatarID)); err != nil {
1✔
107
                        return fmt.Errorf("can't delete avatar object %s: %w", avatarID, err)
×
108
                }
×
109
                if err = tx.Bucket([]byte(metasBktName)).Delete([]byte(avatarID)); err != nil {
1✔
110
                        return fmt.Errorf("can't delete meta object %s: %w", avatarID, err)
×
111
                }
×
112
                return nil
1✔
113
        })
114
}
115

116
// List all avatars (ids) from metas bucket
117
// note: id includes .image suffix
118
func (b *BoltDB) List() (ids []string, err error) {
2✔
119
        err = b.db.View(func(tx *bolt.Tx) error {
4✔
120
                return tx.Bucket([]byte(metasBktName)).ForEach(func(k, _ []byte) error {
6✔
121
                        ids = append(ids, string(k))
4✔
122
                        return nil
4✔
123
                })
4✔
124
        })
125
        if err != nil {
2✔
126
                return nil, fmt.Errorf("failed to list: %w", err)
×
127
        }
×
128
        return ids, nil
2✔
129
}
130

131
// Close bolt store
132
func (b *BoltDB) Close() error {
5✔
133
        if err := b.db.Close(); err != nil {
5✔
134
                return fmt.Errorf("failed to close %s: %w", b.fileName, err)
×
135
        }
×
136
        return nil
5✔
137
}
138

139
func (b *BoltDB) String() string {
1✔
140
        return fmt.Sprintf("boltdb, path=%s", b.fileName)
1✔
141
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc