github.com/markusbkk/elvish@v0.0.0-20231204143114-91dc52438621/pkg/cli/histutil/hybrid_store.go (about) 1 package histutil 2 3 import "github.com/markusbkk/elvish/pkg/store/storedefs" 4 5 // NewHybridStore returns a store that provides a view of all the commands that 6 // exists in the database, plus a in-memory session history. 7 func NewHybridStore(db DB) (Store, error) { 8 if db == nil { 9 return NewMemStore(), nil 10 } 11 dbStore, err := NewDBStore(db) 12 if err != nil { 13 return NewMemStore(), err 14 } 15 return hybridStore{dbStore, NewMemStore()}, nil 16 } 17 18 type hybridStore struct { 19 shared, session Store 20 } 21 22 func (s hybridStore) AddCmd(cmd storedefs.Cmd) (int, error) { 23 seq, err := s.shared.AddCmd(cmd) 24 s.session.AddCmd(storedefs.Cmd{Text: cmd.Text, Seq: seq}) 25 return seq, err 26 } 27 28 func (s hybridStore) AllCmds() ([]storedefs.Cmd, error) { 29 shared, err := s.shared.AllCmds() 30 session, err2 := s.session.AllCmds() 31 if err == nil { 32 err = err2 33 } 34 if len(shared) == 0 { 35 return session, err 36 } 37 return append(shared, session...), err 38 } 39 40 func (s hybridStore) Cursor(prefix string) Cursor { 41 return &hybridStoreCursor{ 42 s.shared.Cursor(prefix), s.session.Cursor(prefix), false} 43 } 44 45 type hybridStoreCursor struct { 46 shared Cursor 47 session Cursor 48 useShared bool 49 } 50 51 func (c *hybridStoreCursor) Prev() { 52 if c.useShared { 53 c.shared.Prev() 54 return 55 } 56 c.session.Prev() 57 if _, err := c.session.Get(); err == ErrEndOfHistory { 58 c.useShared = true 59 c.shared.Prev() 60 } 61 } 62 63 func (c *hybridStoreCursor) Next() { 64 if !c.useShared { 65 c.session.Next() 66 return 67 } 68 c.shared.Next() 69 if _, err := c.shared.Get(); err == ErrEndOfHistory { 70 c.useShared = false 71 c.session.Next() 72 } 73 } 74 75 func (c *hybridStoreCursor) Get() (storedefs.Cmd, error) { 76 if c.useShared { 77 return c.shared.Get() 78 } 79 return c.session.Get() 80 }