diff options
author | Quentin <quentin@deuxfleurs.fr> | 2021-08-23 20:40:03 +0200 |
---|---|---|
committer | Quentin <quentin@deuxfleurs.fr> | 2021-08-23 20:40:03 +0200 |
commit | 15e4d10fd4b35a2e70cc4fa6ad4117cd5c402cbc (patch) | |
tree | 0fe31ac79d5dbe480b1b386845b3dd8fcaa55bd4 /s3_stat.go | |
parent | 5d64be33e64eb75160b6fe37b01997de7e96237a (diff) | |
download | bagage-15e4d10fd4b35a2e70cc4fa6ad4117cd5c402cbc.tar.gz bagage-15e4d10fd4b35a2e70cc4fa6ad4117cd5c402cbc.zip |
Refactor the codebase
Diffstat (limited to 's3_stat.go')
-rw-r--r-- | s3_stat.go | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/s3_stat.go b/s3_stat.go new file mode 100644 index 0000000..65b6faa --- /dev/null +++ b/s3_stat.go @@ -0,0 +1,128 @@ +package main + +import ( + "errors" + "io/fs" + "path" + "time" + + "github.com/minio/minio-go/v7" +) + +type S3Stat struct { + fs *S3FS + obj minio.ObjectInfo + path S3Path +} + +/* + * Stat a path knowing its ObjectInfo + */ +func NewS3StatFromObjectInfo(fs *S3FS, bucket string, obj minio.ObjectInfo) (*S3Stat, error) { + s := new(S3Stat) + s.path = NewTrustedS3Path(bucket, obj) + s.obj = obj + s.fs = fs + + fs.cache[s.path.path] = s + return s, nil +} + +/* + * Stat a path without additional information + */ +func NewS3Stat(fs *S3FS, path string) (*S3Stat, error) { + cache := fs.cache + if entry, ok := cache[path]; ok { + return entry, nil + } + + s := new(S3Stat) + s.fs = fs + s.path = NewS3Path(path) + if err := s.Refresh(); err != nil { + return nil, err + } + + if s.path.class&OPAQUE_KEY != 0 { + return nil, errors.New("Failed to precisely determine the key type, this a logic error.") + } + + cache[path] = s + cache[s.path.path] = s + return s, nil +} + +func (s *S3Stat) Refresh() error { + if s.path.class == ROOT || s.path.class == BUCKET { + return nil + } + + mc := s.fs.mc + + // Compute the prefix to have the desired behaviour for our stat logic + prefix := s.path.key + if prefix[len(prefix)-1:] == "/" { + prefix = prefix[:len(prefix)-1] + } + + // Get info and check if the key exists + objs_info := mc.ListObjects(s.fs.ctx, s.path.bucket, minio.ListObjectsOptions{ + Prefix: prefix, + Recursive: false, + }) + + found := false + for object := range objs_info { + if object.Err != nil { + return object.Err + } + + if object.Key == prefix || object.Key == prefix+"/" { + s.obj = object + s.path = NewTrustedS3Path(s.path.bucket, object) + found = true + break + } + } + + if !found { + return fs.ErrNotExist + } + + return nil +} + +func (s *S3Stat) Name() string { + if s.path.class == ROOT { + return "/" + } else if s.path.class == BUCKET { + return s.path.bucket + } else { + return path.Base(s.path.key) + } +} + +func (s *S3Stat) Size() int64 { + return s.obj.Size +} + +func (s *S3Stat) Mode() fs.FileMode { + if s.path.class == OBJECT { + return fs.ModePerm + } else { + return fs.ModeDir | fs.ModePerm + } +} + +func (s *S3Stat) ModTime() time.Time { + return s.obj.LastModified +} + +func (s *S3Stat) IsDir() bool { + return s.path.class != OBJECT +} + +func (s *S3Stat) Sys() interface{} { + return nil +} |