github.com/elves/elvish@v0.15.0/pkg/cli/histutil/db_store.go (about) 1 package histutil 2 3 import "github.com/elves/elvish/pkg/store" 4 5 // NewDBStore returns a Store backed by a database with the view of all 6 // commands frozen at creation. 7 func NewDBStore(db DB) (Store, error) { 8 upper, err := db.NextCmdSeq() 9 if err != nil { 10 return nil, err 11 } 12 return dbStore{db, upper}, nil 13 } 14 15 type dbStore struct { 16 db DB 17 upper int 18 } 19 20 func (s dbStore) AllCmds() ([]store.Cmd, error) { 21 return s.db.CmdsWithSeq(0, s.upper) 22 } 23 24 func (s dbStore) AddCmd(cmd store.Cmd) (int, error) { 25 return s.db.AddCmd(cmd.Text) 26 } 27 28 func (s dbStore) Cursor(prefix string) Cursor { 29 return &dbStoreCursor{ 30 s.db, prefix, s.upper, store.Cmd{Seq: s.upper}, ErrEndOfHistory} 31 } 32 33 type dbStoreCursor struct { 34 db DB 35 prefix string 36 upper int 37 cmd store.Cmd 38 err error 39 } 40 41 func (c *dbStoreCursor) Prev() { 42 if c.cmd.Seq < 0 { 43 return 44 } 45 cmd, err := c.db.PrevCmd(c.cmd.Seq, c.prefix) 46 c.set(cmd, err, -1) 47 } 48 49 func (c *dbStoreCursor) Next() { 50 if c.cmd.Seq >= c.upper { 51 return 52 } 53 cmd, err := c.db.NextCmd(c.cmd.Seq+1, c.prefix) 54 if cmd.Seq < c.upper { 55 c.set(cmd, err, c.upper) 56 } 57 if cmd.Seq >= c.upper { 58 c.cmd = store.Cmd{Seq: c.upper} 59 c.err = ErrEndOfHistory 60 } 61 } 62 63 func (c *dbStoreCursor) set(cmd store.Cmd, err error, endSeq int) { 64 if err == nil { 65 c.cmd = cmd 66 c.err = nil 67 } else if err.Error() == store.ErrNoMatchingCmd.Error() { 68 c.cmd = store.Cmd{Seq: endSeq} 69 c.err = ErrEndOfHistory 70 } else { 71 // Don't change c.cmd 72 c.err = err 73 } 74 } 75 76 func (c *dbStoreCursor) Get() (store.Cmd, error) { 77 return c.cmd, c.err 78 }