-
Notifications
You must be signed in to change notification settings - Fork 0
/
db.go
105 lines (92 loc) · 2.42 KB
/
db.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
103
104
105
package histutil
import (
"strings"
"github.com/markusbkk/elvish/pkg/store/storedefs"
)
// DB is the interface of the storage database.
type DB interface {
NextCmdSeq() (int, error)
AddCmd(cmd string) (int, error)
CmdsWithSeq(from, upto int) ([]storedefs.Cmd, error)
PrevCmd(upto int, prefix string) (storedefs.Cmd, error)
NextCmd(from int, prefix string) (storedefs.Cmd, error)
}
// FaultyInMemoryDB is an in-memory DB implementation that can be injected
// one-off errors. It is useful in tests.
type FaultyInMemoryDB interface {
DB
// SetOneOffError causes the next operation on the database to return the
// given error.
SetOneOffError(err error)
}
// NewFaultyInMemoryDB creates a new FaultyInMemoryDB with the given commands.
func NewFaultyInMemoryDB(cmds ...string) FaultyInMemoryDB {
return &testDB{cmds: cmds}
}
// Implementation of FaultyInMemoryDB.
type testDB struct {
cmds []string
oneOffError error
}
func (s *testDB) SetOneOffError(err error) {
s.oneOffError = err
}
func (s *testDB) error() error {
err := s.oneOffError
s.oneOffError = nil
return err
}
func (s *testDB) NextCmdSeq() (int, error) {
return len(s.cmds), s.error()
}
func (s *testDB) AddCmd(cmd string) (int, error) {
if s.oneOffError != nil {
return -1, s.error()
}
s.cmds = append(s.cmds, cmd)
return len(s.cmds) - 1, nil
}
func (s *testDB) CmdsWithSeq(from, upto int) ([]storedefs.Cmd, error) {
if err := s.error(); err != nil {
return nil, err
}
if from < 0 {
from = 0
}
if upto < 0 || upto > len(s.cmds) {
upto = len(s.cmds)
}
var cmds []storedefs.Cmd
for i := from; i < upto; i++ {
cmds = append(cmds, storedefs.Cmd{Text: s.cmds[i], Seq: i})
}
return cmds, nil
}
func (s *testDB) PrevCmd(upto int, prefix string) (storedefs.Cmd, error) {
if s.oneOffError != nil {
return storedefs.Cmd{}, s.error()
}
if upto < 0 || upto > len(s.cmds) {
upto = len(s.cmds)
}
for i := upto - 1; i >= 0; i-- {
if strings.HasPrefix(s.cmds[i], prefix) {
return storedefs.Cmd{Text: s.cmds[i], Seq: i}, nil
}
}
return storedefs.Cmd{}, storedefs.ErrNoMatchingCmd
}
func (s *testDB) NextCmd(from int, prefix string) (storedefs.Cmd, error) {
if s.oneOffError != nil {
return storedefs.Cmd{}, s.error()
}
if from < 0 {
from = 0
}
for i := from; i < len(s.cmds); i++ {
if strings.HasPrefix(s.cmds[i], prefix) {
return storedefs.Cmd{Text: s.cmds[i], Seq: i}, nil
}
}
return storedefs.Cmd{}, storedefs.ErrNoMatchingCmd
}