github.com/mg98/scriptup@v0.1.0/pkg/scriptup/storage/file_storage.go (about) 1 package storage 2 3 import ( 4 "bufio" 5 "errors" 6 "os" 7 "strings" 8 ) 9 10 type FileStorage struct { 11 Path string 12 file *os.File 13 } 14 15 func NewFileStorage(path string) *FileStorage { 16 return &FileStorage{Path: path} 17 } 18 19 // Open the file. 20 func (s *FileStorage) Open() error { 21 var err error 22 s.file, err = os.OpenFile(s.Path, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0777) 23 return err 24 } 25 26 // Close the file. 27 func (s *FileStorage) Close() error { 28 return s.file.Close() 29 } 30 31 // Append the entry as a new line at the end of the file. 32 func (s *FileStorage) Append(entry string) error { 33 if err := s.Open(); err != nil { 34 return err 35 } 36 defer s.Close() 37 _, err := s.file.WriteString(entry + "\n") 38 return err 39 } 40 41 // Pop removes the last line from the file. 42 func (s *FileStorage) Pop() error { 43 if err := s.Open(); err != nil { 44 return err 45 } 46 defer s.Close() 47 var lines []string 48 scanner := bufio.NewScanner(s.file) 49 scanner.Split(bufio.ScanLines) 50 for scanner.Scan() { 51 lines = append(lines, scanner.Text()) 52 } 53 if err := scanner.Err(); err != nil { 54 return err 55 } 56 if len(lines) == 0 { 57 return errors.New("no migrations left") 58 } 59 if err := s.file.Truncate(0); err != nil { 60 return err 61 } 62 if _, err := s.file.Seek(0, 0); err != nil { 63 return err 64 } 65 for _, line := range lines[:len(lines)-1] { 66 if _, err := s.file.WriteString(line + "\n"); err != nil { 67 return err 68 } 69 } 70 return nil 71 } 72 73 // All returns all entries from the file. 74 func (s *FileStorage) All(o Order) ([]string, error) { 75 if err := s.Open(); err != nil { 76 return nil, err 77 } 78 defer s.Close() 79 var entries []string 80 scanner := bufio.NewScanner(s.file) 81 for scanner.Scan() { 82 entries = append(entries, strings.Trim(scanner.Text(), " \n")) 83 } 84 if err := scanner.Err(); err != nil { 85 return nil, err 86 } 87 if o == OrderAsc { 88 return entries, nil 89 } 90 91 // reverse for descending order 92 var reverseEntries []string 93 for i := len(entries) - 1; i >= 0; i-- { 94 reverseEntries = append(reverseEntries, entries[i]) 95 } 96 return reverseEntries, nil 97 } 98 99 // Latest returns the most recently added entry. 100 func (s *FileStorage) Latest() (*string, error) { 101 if err := s.Open(); err != nil { 102 return nil, err 103 } 104 defer s.Close() 105 scanner := bufio.NewScanner(s.file) 106 var lastLine string 107 for scanner.Scan() { 108 lastLine = scanner.Text() 109 } 110 if err := scanner.Err(); err != nil { 111 return nil, err 112 } 113 if lastLine == "" { 114 return nil, nil 115 } 116 return &lastLine, nil 117 }