github.com/ladydascalie/elvish@v0.0.0-20170703214355-2964dd3ece7f/store/dir.go (about) 1 package store 2 3 import ( 4 "database/sql" 5 6 "github.com/elves/elvish/store/storedefs" 7 ) 8 9 const ( 10 scoreDecay = 0.986 // roughly 0.5^(1/50) 11 scoreIncrement = 10 12 ) 13 14 func init() { 15 initDB["initialize directory history table"] = func(db *sql.DB) error { 16 _, err := db.Exec(`create table if not exists dir (path text unique primary key, score real default 0)`) 17 return err 18 } 19 } 20 21 // AddDir adds a directory to the directory history. 22 func (s *Store) AddDir(d string, incFactor float64) error { 23 return transaction(s.db, func(tx *sql.Tx) error { 24 // Insert when the path does not already exist 25 _, err := tx.Exec("insert or ignore into dir (path) values(?)", d) 26 if err != nil { 27 return err 28 } 29 30 // Decay scores 31 _, err = tx.Exec("update dir set score = score * ?", scoreDecay) 32 if err != nil { 33 return err 34 } 35 36 // Increment score 37 _, err = tx.Exec("update dir set score = score + ? where path = ?", scoreIncrement*incFactor, d) 38 return err 39 }) 40 } 41 42 // GetDirs lists all directories in the directory history whose names are not 43 // in the blacklist. The results are ordered by scores in descending order. 44 func (s *Store) GetDirs(blacklist map[string]struct{}) ([]storedefs.Dir, error) { 45 rows, err := s.db.Query( 46 "select path, score from dir order by score desc") 47 if err != nil { 48 return nil, err 49 } 50 return convertDirs(rows, blacklist) 51 } 52 53 func convertDirs(rows *sql.Rows, blacklist map[string]struct{}) ([]storedefs.Dir, error) { 54 var ( 55 dir storedefs.Dir 56 dirs []storedefs.Dir 57 ) 58 59 for rows.Next() { 60 rows.Scan(&dir.Path, &dir.Score) 61 if _, black := blacklist[dir.Path]; !black { 62 dirs = append(dirs, dir) 63 } 64 } 65 if err := rows.Err(); err != nil { 66 return nil, err 67 } 68 return dirs, nil 69 }