package swampfile import ( "caj-larsson/bog/dataswamp/swampfile" "github.com/spf13/afero" "io/fs" "os" "path" "time" ) type SwampFile struct { filename string file afero.File } func (f SwampFile) Path() string { return f.filename } func (f SwampFile) Size() int64 { stat, _ := f.file.Stat() return int64(stat.Size()) } func (f SwampFile) Read(p []byte) (int, error) { return f.file.Read(p) } func (f SwampFile) Write(p []byte) (int, error) { return f.file.Write(p) } func (f SwampFile) Close() error { return f.file.Close() } func (f SwampFile) Seek(offset int64, whence int) (int64, error) { return f.file.Seek(offset, whence) } func (f SwampFile) Modified() time.Time { stat, _ := f.file.Stat() return stat.ModTime() } func (f SwampFile) Truncate() { err := f.file.Truncate(0) if err != nil { panic(err) } } // The actual repository type Repository struct { Fs afero.Fs } func NewRepository() swampfile.Repository { return Repository{afero.NewMemMapFs()} } func (r Repository) Create(filename string, namespace_stub string) (swampfile.SwampInFile, error) { abs_path := path.Join(namespace_stub, filename) dir := path.Dir(abs_path) r.Fs.MkdirAll(dir, 0750) file, err := r.Fs.OpenFile(abs_path, os.O_RDWR|os.O_CREATE, 0644) if err != nil { panic(err) } bf := SwampFile{filename, file} return bf, nil } func (r Repository) Open(filename string, namespace_stub string) (swampfile.SwampOutFile, error) { abs_path := path.Join(namespace_stub, filename) dir := path.Dir(abs_path) r.Fs.MkdirAll(dir, 0750) file, err := r.Fs.OpenFile(abs_path, os.O_RDONLY, 0644) if err != nil { return nil, swampfile.ErrNotExists } bf := SwampFile{filename, file} return bf, nil } func (r Repository) Delete(filename string, namespace_stub string) { abs_path := path.Join(namespace_stub, filename) r.Fs.Remove(abs_path) } func (r Repository) DeleteOlderThan(namespace_stub string, ts time.Time) ([]swampfile.DeletedSwampFile, error) { df := []swampfile.DeletedSwampFile{} err := afero.Walk(r.Fs, namespace_stub, func(path string, info fs.FileInfo, err error) error { if err != nil { return err } if info.Mode().IsRegular() { if info.ModTime().Before(ts) { df = append(df, swampfile.DeletedSwampFile{path, info.Size()}) r.Fs.Remove(path) } return nil } if !info.Mode().IsDir() { return swampfile.ErrCorrupted } return nil }) return df, err }