-
Notifications
You must be signed in to change notification settings - Fork 3
/
bucket.go
91 lines (78 loc) · 2.08 KB
/
bucket.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
package boltdb
import (
"bytes"
"errors"
"github.com/boltdb/bolt"
)
var ErrWrongType = errors.New("WRONGTYPE Operation against a key holding the wrong kind of value")
type Bucket struct {
db *bolt.DB
bucketName []byte
}
func (b *Bucket) Hash(key []byte) (*Hash, error) {
if err := b.ensureType(key, HASH); err != nil {
return nil, err
}
return &Hash{bucket: b, key: key}, nil
}
func (b *Bucket) List(key []byte) (*List, error) {
if err := b.ensureType(key, LIST); err != nil {
return nil, err
}
return &List{bucket: b, key: key}, nil
}
func (b *Bucket) SortedSet(key []byte) (*SortedSet, error) {
if err := b.ensureType(key, SORTEDSET); err != nil {
return nil, err
}
return &SortedSet{bucket: b, key: key}, nil
}
func (b *Bucket) ensureType(key []byte, elemType ElemType) error {
if t, err := b.TypeOf(key); err != nil {
return err
} else if t != NONE && t != elemType {
return ErrWrongType
}
return nil
}
func (b *Bucket) TypeOf(key []byte) (ElemType, error) {
elemType := NONE
err := b.View(func(bucket *bolt.Bucket) error {
c := bucket.Cursor()
prefix := bytes.Join([][]byte{KEY, key, SEP}, nil)
if k, _ := c.Seek(prefix); bytes.HasPrefix(k, prefix) {
t := bytes.TrimPrefix(k, prefix)
elemType = ElemType(t[0])
}
return nil
})
return elemType, err
}
func (b *Bucket) Get(key []byte) ([]byte, error) {
var val []byte
err := b.View(func(bucket *bolt.Bucket) error {
val = bucket.Get(rawKey(key, STRING))
return nil
})
return val, err
}
func (b *Bucket) Set(key, value []byte) error {
if err := b.ensureType(key, STRING); err != nil {
return err
}
return b.Update(func(bucket *bolt.Bucket) error {
return bucket.Put(rawKey(key, STRING), value)
})
}
// View make bolt.DB.View(Tx){tx.Bucket(...)} to View(bolt.Bucket)
func (b *Bucket) View(fn func(*bolt.Bucket) error) error {
return b.db.View(func(tx *bolt.Tx) error {
return fn(tx.Bucket(b.bucketName))
})
}
// Update make db.View easy to use
func (b *Bucket) Update(fn func(*bolt.Bucket) error) error {
return b.db.Update(func(tx *bolt.Tx) error {
return fn(tx.Bucket(b.bucketName))
})
}