Initial QSfera import
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
package metadata
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"sync"
|
||||
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/utils/metadata"
|
||||
|
||||
"github.com/qsfera/server/pkg/storage"
|
||||
)
|
||||
|
||||
// Lazy is a lazy storage implementation that initializes the underlying storage only when needed.
|
||||
type Lazy struct {
|
||||
next func() (metadata.Storage, error)
|
||||
|
||||
initName string `validate:"required"`
|
||||
initCTX context.Context `validate:"required"`
|
||||
}
|
||||
|
||||
func NewLazyStorage(next metadata.Storage) (*Lazy, error) {
|
||||
s := &Lazy{}
|
||||
s.next = sync.OnceValues[metadata.Storage, error](func() (metadata.Storage, error) {
|
||||
if err := validator.New(validator.WithPrivateFieldValidation()).Struct(s); err != nil {
|
||||
return nil, errors.Join(storage.ErrStorageInitialization, storage.ErrStorageValidation, err)
|
||||
}
|
||||
|
||||
if err := next.Init(s.initCTX, s.initName); err != nil {
|
||||
return nil, errors.Join(storage.ErrStorageInitialization, err)
|
||||
}
|
||||
|
||||
return next, nil
|
||||
})
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// Backend wraps the backend of the next storage
|
||||
func (s *Lazy) Backend() string {
|
||||
next, err := s.next()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return next.Backend()
|
||||
}
|
||||
|
||||
// Init prepares the required data for the underlying lazy storage initialization
|
||||
func (s *Lazy) Init(ctx context.Context, name string) (err error) {
|
||||
s.initCTX = ctx
|
||||
s.initName = name
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Upload wraps the upload method of the next storage
|
||||
func (s *Lazy) Upload(ctx context.Context, req metadata.UploadRequest) (*metadata.UploadResponse, error) {
|
||||
next, err := s.next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return next.Upload(ctx, req)
|
||||
}
|
||||
|
||||
// Download wraps the download method of the next storage
|
||||
func (s *Lazy) Download(ctx context.Context, req metadata.DownloadRequest) (*metadata.DownloadResponse, error) {
|
||||
next, err := s.next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return next.Download(ctx, req)
|
||||
}
|
||||
|
||||
// SimpleUpload wraps the simple upload method of the next storage
|
||||
func (s *Lazy) SimpleUpload(ctx context.Context, uploadpath string, content []byte) error {
|
||||
next, err := s.next()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return next.SimpleUpload(ctx, uploadpath, content)
|
||||
}
|
||||
|
||||
// SimpleDownload wraps the simple download method of the next storage
|
||||
func (s *Lazy) SimpleDownload(ctx context.Context, path string) ([]byte, error) {
|
||||
next, err := s.next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return next.SimpleDownload(ctx, path)
|
||||
}
|
||||
|
||||
// Delete wraps the delete method of the next storage
|
||||
func (s *Lazy) Delete(ctx context.Context, path string) error {
|
||||
next, err := s.next()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return next.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// Stat wraps the stat method of the next storage
|
||||
func (s *Lazy) Stat(ctx context.Context, path string) (*provider.ResourceInfo, error) {
|
||||
next, err := s.next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return next.Stat(ctx, path)
|
||||
}
|
||||
|
||||
// ReadDir wraps the read directory method of the next storage
|
||||
func (s *Lazy) ReadDir(ctx context.Context, path string) ([]string, error) {
|
||||
next, err := s.next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return next.ReadDir(ctx, path)
|
||||
}
|
||||
|
||||
// ListDir wraps the list directory method of the next storage
|
||||
func (s *Lazy) ListDir(ctx context.Context, path string) ([]*provider.ResourceInfo, error) {
|
||||
next, err := s.next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return next.ListDir(ctx, path)
|
||||
}
|
||||
|
||||
// CreateSymlink wraps the create symlink method of the next storage
|
||||
func (s *Lazy) CreateSymlink(ctx context.Context, oldname, newname string) error {
|
||||
next, err := s.next()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return next.CreateSymlink(ctx, oldname, newname)
|
||||
}
|
||||
|
||||
// ResolveSymlink wraps the resolve symlink method of the next storage
|
||||
func (s *Lazy) ResolveSymlink(ctx context.Context, name string) (string, error) {
|
||||
next, err := s.next()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return next.ResolveSymlink(ctx, name)
|
||||
}
|
||||
|
||||
// MakeDirIfNotExist wraps the make directory if not exist method of the next storage
|
||||
func (s *Lazy) MakeDirIfNotExist(ctx context.Context, name string) error {
|
||||
next, err := s.next()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return next.MakeDirIfNotExist(ctx, name)
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrStorageInitialization is returned when the storage initialization fails
|
||||
ErrStorageInitialization = errors.New("failed to initialize storage")
|
||||
|
||||
// ErrStorageValidation is returned when the storage configuration is invalid
|
||||
ErrStorageValidation = errors.New("failed to validate storage configuration")
|
||||
)
|
||||
Reference in New Issue
Block a user