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  }