feat: Add basic STFS-backed Read implementation
This commit is contained in:
@@ -1,18 +1,25 @@
|
||||
package fs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/fs"
|
||||
"log"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
models "github.com/pojntfx/stfs/internal/db/sqlite/models/metadata"
|
||||
"github.com/pojntfx/stfs/pkg/config"
|
||||
"github.com/pojntfx/stfs/pkg/inventory"
|
||||
"github.com/pojntfx/stfs/pkg/operations"
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
type File struct {
|
||||
afero.File
|
||||
|
||||
ops *operations.Operations
|
||||
|
||||
metadata config.MetadataConfig
|
||||
|
||||
path string
|
||||
@@ -20,10 +27,15 @@ type File struct {
|
||||
name string
|
||||
info os.FileInfo
|
||||
|
||||
reader *io.PipeReader
|
||||
readerLock sync.Mutex
|
||||
|
||||
onHeader func(hdr *models.Header)
|
||||
}
|
||||
|
||||
func NewFile(
|
||||
ops *operations.Operations,
|
||||
|
||||
metadata config.MetadataConfig,
|
||||
|
||||
path string,
|
||||
@@ -34,6 +46,8 @@ func NewFile(
|
||||
onHeader func(hdr *models.Header),
|
||||
) *File {
|
||||
return &File{
|
||||
ops: ops,
|
||||
|
||||
metadata: metadata,
|
||||
|
||||
path: path,
|
||||
@@ -45,19 +59,19 @@ func NewFile(
|
||||
}
|
||||
}
|
||||
|
||||
func (f File) Name() string {
|
||||
func (f *File) Name() string {
|
||||
log.Println("File.Name", f.name)
|
||||
|
||||
return f.name
|
||||
}
|
||||
|
||||
func (f File) Stat() (os.FileInfo, error) {
|
||||
func (f *File) Stat() (os.FileInfo, error) {
|
||||
log.Println("File.Stat", f.name)
|
||||
|
||||
return f.info, nil
|
||||
}
|
||||
|
||||
func (f File) Readdir(count int) ([]os.FileInfo, error) {
|
||||
func (f *File) Readdir(count int) ([]os.FileInfo, error) {
|
||||
log.Println("File.Readdir", f.name, count)
|
||||
|
||||
hdrs, err := inventory.List(
|
||||
@@ -80,61 +94,94 @@ func (f File) Readdir(count int) ([]os.FileInfo, error) {
|
||||
return fileInfos, nil
|
||||
}
|
||||
|
||||
func (f File) Readdirnames(n int) ([]string, error) {
|
||||
func (f *File) Readdirnames(n int) ([]string, error) {
|
||||
log.Println("File.Readdirnames", f.name, n)
|
||||
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (f File) Sync() error {
|
||||
func (f *File) Sync() error {
|
||||
log.Println("File.Sync", f.name)
|
||||
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (f File) Truncate(size int64) error {
|
||||
func (f *File) Truncate(size int64) error {
|
||||
log.Println("File.Truncate", f.name, size)
|
||||
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (f File) WriteString(s string) (ret int, err error) {
|
||||
func (f *File) WriteString(s string) (ret int, err error) {
|
||||
log.Println("File.WriteString", f.name, s)
|
||||
|
||||
return -1, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (f File) Close() error {
|
||||
func (f *File) Close() error {
|
||||
log.Println("File.Close", f.name)
|
||||
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (f File) Read(p []byte) (n int, err error) {
|
||||
log.Println("File.Read", f.name, p)
|
||||
func (f *File) Read(p []byte) (n int, err error) {
|
||||
log.Println("File.Read", f.name, len(p))
|
||||
|
||||
return -1, ErrNotImplemented
|
||||
f.readerLock.Lock()
|
||||
defer f.readerLock.Unlock()
|
||||
|
||||
if f.reader == nil {
|
||||
reader, writer := io.Pipe()
|
||||
|
||||
go func() {
|
||||
if err := f.ops.Restore(
|
||||
func(path string, mode fs.FileMode) (io.WriteCloser, error) {
|
||||
return writer, nil
|
||||
},
|
||||
func(path string, mode fs.FileMode) error {
|
||||
// Not necessary; can't read on a directory
|
||||
return nil
|
||||
},
|
||||
|
||||
f.path,
|
||||
"",
|
||||
true,
|
||||
); err != nil {
|
||||
// TODO: Handle error
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
f.reader = reader
|
||||
}
|
||||
|
||||
w := &bytes.Buffer{}
|
||||
if _, err := io.CopyN(w, f.reader, int64(len(p))); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
return copy(p, w.Bytes()), nil
|
||||
}
|
||||
|
||||
func (f File) ReadAt(p []byte, off int64) (n int, err error) {
|
||||
func (f *File) ReadAt(p []byte, off int64) (n int, err error) {
|
||||
log.Println("File.ReadAt", f.name, p, off)
|
||||
|
||||
return -1, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (f File) Seek(offset int64, whence int) (int64, error) {
|
||||
func (f *File) Seek(offset int64, whence int) (int64, error) {
|
||||
log.Println("File.Seek", f.name, offset, whence)
|
||||
|
||||
return -1, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (f File) Write(p []byte) (n int, err error) {
|
||||
func (f *File) Write(p []byte) (n int, err error) {
|
||||
log.Println("File.Write", f.name, p)
|
||||
|
||||
return -1, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (f File) WriteAt(p []byte, off int64) (n int, err error) {
|
||||
func (f *File) WriteAt(p []byte, off int64) (n int, err error) {
|
||||
log.Println("File.WriteAt", f.name, p, off)
|
||||
|
||||
return -1, ErrNotImplemented
|
||||
|
||||
@@ -28,37 +28,37 @@ func NewFileInfo(hdr *tar.Header) *FileInfo {
|
||||
}
|
||||
}
|
||||
|
||||
func (f FileInfo) Name() string {
|
||||
func (f *FileInfo) Name() string {
|
||||
log.Println("FileInfo.Name", f.name)
|
||||
|
||||
return f.name
|
||||
}
|
||||
|
||||
func (f FileInfo) Size() int64 {
|
||||
func (f *FileInfo) Size() int64 {
|
||||
log.Println("FileInfo.Size", f.name)
|
||||
|
||||
return f.size
|
||||
}
|
||||
|
||||
func (f FileInfo) Mode() os.FileMode {
|
||||
func (f *FileInfo) Mode() os.FileMode {
|
||||
log.Println("FileInfo.Mode", f.name)
|
||||
|
||||
return os.FileMode(f.mode)
|
||||
}
|
||||
|
||||
func (f FileInfo) ModTime() time.Time {
|
||||
func (f *FileInfo) ModTime() time.Time {
|
||||
log.Println("FileInfo.ModTime", f.name)
|
||||
|
||||
return f.modTime
|
||||
}
|
||||
|
||||
func (f FileInfo) IsDir() bool {
|
||||
func (f *FileInfo) IsDir() bool {
|
||||
log.Println("FileInfo.IsDir", f.name)
|
||||
|
||||
return f.isDir
|
||||
}
|
||||
|
||||
func (f FileInfo) Sys() interface{} {
|
||||
func (f *FileInfo) Sys() interface{} {
|
||||
log.Println("FileInfo.Sys", f.name)
|
||||
|
||||
return nil
|
||||
|
||||
@@ -86,6 +86,8 @@ func (f *FileSystem) Open(name string) (afero.File, error) {
|
||||
}
|
||||
|
||||
return NewFile(
|
||||
f.ops,
|
||||
|
||||
f.metadata,
|
||||
|
||||
hdr.Name,
|
||||
|
||||
Reference in New Issue
Block a user