-
Notifications
You must be signed in to change notification settings - Fork 0
/
hybrid_store.go
80 lines (70 loc) · 1.65 KB
/
hybrid_store.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
package histutil
import "github.com/markusbkk/elvish/pkg/store/storedefs"
// NewHybridStore returns a store that provides a view of all the commands that
// exists in the database, plus a in-memory session history.
func NewHybridStore(db DB) (Store, error) {
if db == nil {
return NewMemStore(), nil
}
dbStore, err := NewDBStore(db)
if err != nil {
return NewMemStore(), err
}
return hybridStore{dbStore, NewMemStore()}, nil
}
type hybridStore struct {
shared, session Store
}
func (s hybridStore) AddCmd(cmd storedefs.Cmd) (int, error) {
seq, err := s.shared.AddCmd(cmd)
s.session.AddCmd(storedefs.Cmd{Text: cmd.Text, Seq: seq})
return seq, err
}
func (s hybridStore) AllCmds() ([]storedefs.Cmd, error) {
shared, err := s.shared.AllCmds()
session, err2 := s.session.AllCmds()
if err == nil {
err = err2
}
if len(shared) == 0 {
return session, err
}
return append(shared, session...), err
}
func (s hybridStore) Cursor(prefix string) Cursor {
return &hybridStoreCursor{
s.shared.Cursor(prefix), s.session.Cursor(prefix), false}
}
type hybridStoreCursor struct {
shared Cursor
session Cursor
useShared bool
}
func (c *hybridStoreCursor) Prev() {
if c.useShared {
c.shared.Prev()
return
}
c.session.Prev()
if _, err := c.session.Get(); err == ErrEndOfHistory {
c.useShared = true
c.shared.Prev()
}
}
func (c *hybridStoreCursor) Next() {
if !c.useShared {
c.session.Next()
return
}
c.shared.Next()
if _, err := c.shared.Get(); err == ErrEndOfHistory {
c.useShared = false
c.session.Next()
}
}
func (c *hybridStoreCursor) Get() (storedefs.Cmd, error) {
if c.useShared {
return c.shared.Get()
}
return c.session.Get()
}