github.com/Datadog/cnab-go@v0.3.3-beta1.0.20191007143216-bba4b7e723d0/utils/crud/filesystem.go (about) 1 package crud 2 3 import ( 4 "errors" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "strings" 10 ) 11 12 // ErrRecordDoesNotExist represents when file path is not found on file system 13 var ErrRecordDoesNotExist = errors.New("File does not exist") 14 15 // NewFileSystemStore creates a Store backed by a file system directory. 16 // Each key is represented by a file in that directory. 17 func NewFileSystemStore(baseDirectory string, fileExtension string) Store { 18 return fileSystemStore{ 19 baseDirectory: baseDirectory, 20 fileExtension: fileExtension, 21 } 22 } 23 24 type fileSystemStore struct { 25 baseDirectory string 26 fileExtension string 27 } 28 29 func (s fileSystemStore) List() ([]string, error) { 30 if err := s.ensure(); err != nil { 31 return nil, err 32 } 33 34 files, err := ioutil.ReadDir(s.baseDirectory) 35 if err != nil { 36 return []string{}, err 37 } 38 39 return names(s.storageFiles(files)), nil 40 } 41 42 func (s fileSystemStore) Store(name string, data []byte) error { 43 filename, err := s.fullyQualifiedName(name) 44 if err != nil { 45 return err 46 } 47 48 return ioutil.WriteFile(filename, data, os.ModePerm) 49 } 50 51 func (s fileSystemStore) Read(name string) ([]byte, error) { 52 filename, err := s.fullyQualifiedName(name) 53 if err != nil { 54 return nil, err 55 } 56 57 if _, err := os.Stat(filename); os.IsNotExist(err) { 58 return nil, ErrRecordDoesNotExist 59 } 60 61 return ioutil.ReadFile(filename) 62 } 63 64 func (s fileSystemStore) Delete(name string) error { 65 filename, err := s.fullyQualifiedName(name) 66 if err != nil { 67 return err 68 } 69 return os.Remove(filename) 70 } 71 72 func (s fileSystemStore) fileNameOf(name string) string { 73 return filepath.Join(s.baseDirectory, fmt.Sprintf("%s.%s", name, s.fileExtension)) 74 } 75 76 func (s fileSystemStore) fullyQualifiedName(name string) (string, error) { 77 if err := s.ensure(); err != nil { 78 return "", err 79 } 80 return s.fileNameOf(name), nil 81 } 82 83 func (s fileSystemStore) ensure() error { 84 fi, err := os.Stat(s.baseDirectory) 85 if err == nil { 86 if fi.IsDir() { 87 return nil 88 } 89 return errors.New("Storage directory name exists, but is not a directory") 90 } 91 return os.MkdirAll(s.baseDirectory, os.ModePerm) 92 } 93 94 func (s fileSystemStore) storageFiles(files []os.FileInfo) []os.FileInfo { 95 result := make([]os.FileInfo, 0) 96 ext := "." + s.fileExtension 97 for _, file := range files { 98 if !file.IsDir() && filepath.Ext(file.Name()) == ext { 99 result = append(result, file) 100 } 101 } 102 return result 103 } 104 105 func names(files []os.FileInfo) []string { 106 result := make([]string, 0) 107 for _, file := range files { 108 result = append(result, name(file.Name())) 109 } 110 return result 111 } 112 113 func name(filename string) string { 114 return strings.TrimSuffix(filepath.Base(filename), filepath.Ext(filename)) 115 }