Files
drive/apps/backend/internal/blob/fs_store.go

96 lines
1.7 KiB
Go

package blob
import (
"context"
"io"
"os"
"path/filepath"
)
var _ Store = &FSStore{}
type FSStore struct {
config FSStoreConfig
}
type FSStoreConfig struct {
Root string
}
func NewFSStore(config FSStoreConfig) *FSStore {
return &FSStore{config: config}
}
func (s *FSStore) Put(ctx context.Context, key Key, reader io.Reader) error {
path := filepath.Join(s.config.Root, string(key))
err := os.MkdirAll(filepath.Dir(path), 0755)
if err != nil {
return err
}
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0644)
if err != nil {
if os.IsExist(err) {
return ErrConflict
}
return err
}
defer f.Close()
_, err = io.Copy(f, reader)
if err != nil {
_ = os.Remove(path)
return err
}
return nil
}
func (s *FSStore) Retrieve(ctx context.Context, key Key) (io.ReadCloser, error) {
path := filepath.Join(s.config.Root, string(key))
f, err := os.Open(path)
if err != nil {
if os.IsNotExist(err) {
return nil, ErrNotFound
}
return nil, err
}
return f, nil
}
func (s *FSStore) Delete(ctx context.Context, key Key) error {
err := os.Remove(filepath.Join(s.config.Root, string(key)))
// no op if file does not exist
// swallow error if file does not exist
if err != nil && !os.IsNotExist(err) {
return err
}
return nil
}
func (s *FSStore) Move(ctx context.Context, srcKey, dstKey Key) error {
oldPath := filepath.Join(s.config.Root, string(srcKey))
newPath := filepath.Join(s.config.Root, string(dstKey))
_, err := os.Stat(newPath)
if err == nil {
return ErrConflict
}
err = os.MkdirAll(filepath.Dir(newPath), 0755)
if err != nil {
return err
}
err = os.Rename(oldPath, newPath)
if err != nil {
if os.IsNotExist(err) {
return ErrNotFound
}
return err
}
return nil
}