mirror of
https://github.com/get-drexa/drive.git
synced 2025-12-01 05:51:39 +00:00
feat: impl upload service
This commit is contained in:
@@ -3,6 +3,7 @@ package blob
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrConflict = errors.New("key already used for a different blob")
|
||||
ErrNotFound = errors.New("key not found")
|
||||
ErrConflict = errors.New("key already used for a different blob")
|
||||
ErrNotFound = errors.New("key not found")
|
||||
ErrInvalidFileContent = errors.New("invalid file content. must provide either a reader or a blob key")
|
||||
)
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/get-drexa/drexa/internal/ioext"
|
||||
)
|
||||
|
||||
var _ Store = &FSStore{}
|
||||
@@ -14,13 +16,18 @@ type FSStore struct {
|
||||
}
|
||||
|
||||
type FSStoreConfig struct {
|
||||
Root string
|
||||
Root string
|
||||
UploadURL string
|
||||
}
|
||||
|
||||
func NewFSStore(config FSStoreConfig) *FSStore {
|
||||
return &FSStore{config: config}
|
||||
}
|
||||
|
||||
func (s *FSStore) GenerateUploadURL(ctx context.Context, key Key, opts UploadURLOptions) (string, error) {
|
||||
return s.config.UploadURL, nil
|
||||
}
|
||||
|
||||
func (s *FSStore) Put(ctx context.Context, key Key, reader io.Reader) error {
|
||||
path := filepath.Join(s.config.Root, string(key))
|
||||
|
||||
@@ -47,7 +54,7 @@ func (s *FSStore) Put(ctx context.Context, key Key, reader io.Reader) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *FSStore) Retrieve(ctx context.Context, key Key) (io.ReadCloser, error) {
|
||||
func (s *FSStore) Read(ctx context.Context, key Key) (io.ReadCloser, error) {
|
||||
path := filepath.Join(s.config.Root, string(key))
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
@@ -59,6 +66,37 @@ func (s *FSStore) Retrieve(ctx context.Context, key Key) (io.ReadCloser, error)
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (s *FSStore) ReadRange(ctx context.Context, key Key, offset, length int64) (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
|
||||
}
|
||||
|
||||
_, err = f.Seek(offset, io.SeekStart)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ioext.NewLimitReadCloser(f, length), nil
|
||||
}
|
||||
|
||||
func (s *FSStore) ReadSize(ctx context.Context, key Key) (int64, error) {
|
||||
path := filepath.Join(s.config.Root, string(key))
|
||||
fi, err := os.Stat(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return 0, ErrNotFound
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
return fi.Size(), 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
|
||||
@@ -69,6 +107,11 @@ func (s *FSStore) Delete(ctx context.Context, key Key) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *FSStore) Update(ctx context.Context, key Key, opts UpdateOptions) error {
|
||||
// Update is a no-op for FSStore
|
||||
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))
|
||||
|
||||
@@ -2,6 +2,13 @@ package blob
|
||||
|
||||
type Key string
|
||||
|
||||
type KeyMode int
|
||||
|
||||
const (
|
||||
KeyModeStable KeyMode = iota
|
||||
KeyModeDerived
|
||||
)
|
||||
|
||||
func (k Key) IsNil() bool {
|
||||
return k == ""
|
||||
}
|
||||
|
||||
@@ -3,11 +3,24 @@ package blob
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UploadURLOptions struct {
|
||||
Duration time.Duration
|
||||
}
|
||||
|
||||
type UpdateOptions struct {
|
||||
ContentType string
|
||||
}
|
||||
|
||||
type Store interface {
|
||||
GenerateUploadURL(ctx context.Context, key Key, opts UploadURLOptions) (string, error)
|
||||
Put(ctx context.Context, key Key, reader io.Reader) error
|
||||
Retrieve(ctx context.Context, key Key) (io.ReadCloser, error)
|
||||
Update(ctx context.Context, key Key, opts UpdateOptions) error
|
||||
Delete(ctx context.Context, key Key) error
|
||||
Move(ctx context.Context, srcKey, dstKey Key) error
|
||||
Read(ctx context.Context, key Key) (io.ReadCloser, error)
|
||||
ReadRange(ctx context.Context, key Key, offset, length int64) (io.ReadCloser, error)
|
||||
ReadSize(ctx context.Context, key Key) (int64, error)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user