github.com/soulteary/pocket-bookcase@v0.0.0-20240428065142-0b5a9a0fc98a/internal/domains/storage.go (about) 1 package domains 2 3 import ( 4 "fmt" 5 "io" 6 "io/fs" 7 "os" 8 "path/filepath" 9 10 "github.com/soulteary/pocket-bookcase/internal/dependencies" 11 "github.com/soulteary/pocket-bookcase/internal/model" 12 "github.com/spf13/afero" 13 ) 14 15 type StorageDomain struct { 16 deps *dependencies.Dependencies 17 fs afero.Fs 18 } 19 20 func NewStorageDomain(deps *dependencies.Dependencies, fs afero.Fs) *StorageDomain { 21 return &StorageDomain{ 22 deps: deps, 23 fs: fs, 24 } 25 } 26 27 // Stat returns the FileInfo structure describing file. 28 func (d *StorageDomain) Stat(name string) (fs.FileInfo, error) { 29 return d.fs.Stat(name) 30 } 31 32 // FS returns the filesystem used by this domain. 33 func (d *StorageDomain) FS() afero.Fs { 34 return d.fs 35 } 36 37 // FileExists checks if a file exists in storage. 38 func (d *StorageDomain) FileExists(name string) bool { 39 info, err := d.Stat(name) 40 return err == nil && !info.IsDir() 41 } 42 43 // DirExists checks if a directory exists in storage. 44 func (d *StorageDomain) DirExists(name string) bool { 45 info, err := d.Stat(name) 46 return err == nil && info.IsDir() 47 } 48 49 // WriteData writes bytes data to a file in storage. 50 // CAUTION: This function will overwrite existing file. 51 func (d *StorageDomain) WriteData(dst string, data []byte) error { 52 // Create directory if not exist 53 dir := filepath.Dir(dst) 54 if !d.DirExists(dir) { 55 err := d.fs.MkdirAll(dir, os.ModePerm) 56 if err != nil { 57 return err 58 } 59 } 60 61 // Create file 62 file, err := d.fs.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.ModePerm) 63 if err != nil { 64 return err 65 } 66 defer file.Close() 67 68 // Write data 69 _, err = file.Write(data) 70 return err 71 } 72 73 // WriteFile writes a file to storage. 74 func (d *StorageDomain) WriteFile(dst string, tmpFile *os.File) error { 75 if dst != "" && !d.DirExists(dst) { 76 err := d.fs.MkdirAll(filepath.Dir(dst), model.DataDirPerm) 77 if err != nil { 78 return fmt.Errorf("failed to create destination dir: %v", err) 79 } 80 } 81 82 dstFile, err := d.fs.Create(dst) 83 if err != nil { 84 return fmt.Errorf("failed to create destination file: %v", err) 85 } 86 defer dstFile.Close() 87 88 _, err = tmpFile.Seek(0, io.SeekStart) 89 if err != nil { 90 return fmt.Errorf("failed to rewind temporary file: %v", err) 91 } 92 93 _, err = io.Copy(dstFile, tmpFile) 94 if err != nil { 95 return fmt.Errorf("failed to copy file to the destination") 96 } 97 98 return nil 99 }