mirror of
https://github.com/octoleo/restic.git
synced 2025-02-04 12:58:27 +00:00
Add Load() for all existing backends
This commit is contained in:
parent
8b7bf8691d
commit
0a24261afb
@ -56,6 +56,10 @@ type Backend interface {
|
|||||||
Close() error
|
Close() error
|
||||||
|
|
||||||
Lister
|
Lister
|
||||||
|
|
||||||
|
// Load returns the data stored in the backend for h at the given offset
|
||||||
|
// and saves it in p. Load has the same semantics as io.ReaderAt.
|
||||||
|
Load(h Handle, p []byte, off int64) (int, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lister implements listing data items stored in a backend.
|
// Lister implements listing data items stored in a backend.
|
||||||
|
@ -223,6 +223,31 @@ func (b *Local) GetReader(t backend.Type, name string, offset, length uint) (io.
|
|||||||
return backend.LimitReadCloser(f, int64(length)), nil
|
return backend.LimitReadCloser(f, int64(length)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load returns the data stored in the backend for h at the given offset
|
||||||
|
// and saves it in p. Load has the same semantics as io.ReaderAt.
|
||||||
|
func (b *Local) Load(h backend.Handle, p []byte, off int64) (n int, err error) {
|
||||||
|
f, err := os.Open(filename(b.p, h.Type, h.Name))
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
e := f.Close()
|
||||||
|
if err == nil && e != nil {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if off > 0 {
|
||||||
|
_, err = f.Seek(off, 0)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return io.ReadFull(f, p)
|
||||||
|
}
|
||||||
|
|
||||||
// Test returns true if a blob of the given type and name exists in the backend.
|
// Test returns true if a blob of the given type and name exists in the backend.
|
||||||
func (b *Local) Test(t backend.Type, name string) (bool, error) {
|
func (b *Local) Test(t backend.Type, name string) (bool, error) {
|
||||||
_, err := os.Stat(filename(b.p, t, name))
|
_, err := os.Stat(filename(b.p, t, name))
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
type MockBackend struct {
|
type MockBackend struct {
|
||||||
CloseFn func() error
|
CloseFn func() error
|
||||||
CreateFn func() (Blob, error)
|
CreateFn func() (Blob, error)
|
||||||
|
LoadFn func(h Handle, p []byte, off int64) (int, error)
|
||||||
GetReaderFn func(Type, string, uint, uint) (io.ReadCloser, error)
|
GetReaderFn func(Type, string, uint, uint) (io.ReadCloser, error)
|
||||||
ListFn func(Type, <-chan struct{}) <-chan string
|
ListFn func(Type, <-chan struct{}) <-chan string
|
||||||
RemoveFn func(Type, string) error
|
RemoveFn func(Type, string) error
|
||||||
@ -42,6 +43,14 @@ func (m *MockBackend) Create() (Blob, error) {
|
|||||||
return m.CreateFn()
|
return m.CreateFn()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *MockBackend) Load(h Handle, p []byte, off int64) (int, error) {
|
||||||
|
if m.LoadFn == nil {
|
||||||
|
return 0, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.Load(h, p, off)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *MockBackend) GetReader(t Type, name string, offset, len uint) (io.ReadCloser, error) {
|
func (m *MockBackend) GetReader(t Type, name string, offset, len uint) (io.ReadCloser, error) {
|
||||||
if m.GetReaderFn == nil {
|
if m.GetReaderFn == nil {
|
||||||
return nil, errors.New("not implemented")
|
return nil, errors.New("not implemented")
|
||||||
|
@ -170,6 +170,27 @@ func (be *S3Backend) GetReader(t backend.Type, name string, offset, length uint)
|
|||||||
return backend.LimitReadCloser(obj, int64(length)), nil
|
return backend.LimitReadCloser(obj, int64(length)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load returns the data stored in the backend for h at the given offset
|
||||||
|
// and saves it in p. Load has the same semantics as io.ReaderAt.
|
||||||
|
func (be S3Backend) Load(h backend.Handle, p []byte, off int64) (int, error) {
|
||||||
|
debug.Log("s3.Load", "%v, offset %v, len %v", h, off, len(p))
|
||||||
|
path := s3path(h.Type, h.Name)
|
||||||
|
obj, err := be.client.GetObject(be.bucketname, path)
|
||||||
|
if err != nil {
|
||||||
|
debug.Log("s3.GetReader", " err %v", err)
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if off > 0 {
|
||||||
|
_, err = obj.Seek(off, 0)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return io.ReadFull(obj, p)
|
||||||
|
}
|
||||||
|
|
||||||
// Test returns true if a blob of the given type and name exists in the backend.
|
// Test returns true if a blob of the given type and name exists in the backend.
|
||||||
func (be *S3Backend) Test(t backend.Type, name string) (bool, error) {
|
func (be *S3Backend) Test(t backend.Type, name string) (bool, error) {
|
||||||
found := false
|
found := false
|
||||||
|
@ -366,6 +366,31 @@ func (r *SFTP) GetReader(t backend.Type, name string, offset, length uint) (io.R
|
|||||||
return backend.LimitReadCloser(f, int64(length)), nil
|
return backend.LimitReadCloser(f, int64(length)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load returns the data stored in the backend for h at the given offset
|
||||||
|
// and saves it in p. Load has the same semantics as io.ReaderAt.
|
||||||
|
func (r *SFTP) Load(h backend.Handle, p []byte, off int64) (n int, err error) {
|
||||||
|
f, err := r.c.Open(r.filename(h.Type, h.Name))
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
e := f.Close()
|
||||||
|
if err == nil && e != nil {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if off > 0 {
|
||||||
|
_, err = f.Seek(off, 0)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return io.ReadFull(f, p)
|
||||||
|
}
|
||||||
|
|
||||||
// Test returns true if a blob of the given type and name exists in the backend.
|
// Test returns true if a blob of the given type and name exists in the backend.
|
||||||
func (r *SFTP) Test(t backend.Type, name string) (bool, error) {
|
func (r *SFTP) Test(t backend.Type, name string) (bool, error) {
|
||||||
_, err := r.c.Lstat(r.filename(t, name))
|
_, err := r.c.Lstat(r.filename(t, name))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user