diff options
-rw-r--r-- | s3_fs.go | 46 |
1 files changed, 45 insertions, 1 deletions
@@ -95,7 +95,51 @@ func (s S3FS) RemoveAll(ctx context.Context, name string) error { func (s S3FS) Rename(ctx context.Context, oldName, newName string) error { s.ctx = ctx - return errors.New("Not implemented Rename") + + po := NewS3Path(oldName) + pn := NewS3Path(newName) + if po.class == ROOT || pn.class == ROOT { + return errors.New("Unable to rename root folder") + } else if po.class == BUCKET || pn.class == BUCKET { + log.Println("Moving a bucket is not implemented yet") + return nil + } + + //Check that newName is not inside oldName + if len(newName) > len(oldName) && newName[:len(oldName)] == oldName { + return errors.New("Cannot move an entity inside itself (eg. moving /data in /data/test is impossible)") + } + + //Gather all keys, copy the object, delete the original + objCh := s.mc.ListObjects(s.ctx, po.bucket, minio.ListObjectsOptions{Prefix: po.key, Recursive: true}) + for obj := range objCh { + log.Println("found object", obj) + src := minio.CopySrcOptions{ + Bucket: po.bucket, + Object: obj.Key, + } + + dst := minio.CopyDestOptions{ + Bucket: pn.bucket, + Object: path.Join(pn.key, obj.Key[len(po.key):]), + } + + _, err := s.mc.CopyObject(s.ctx, dst, src) + log.Println("copy", obj) + if err != nil { + log.Println("copy err", err) + return err + } + + log.Println("delete", obj) + err = s.mc.RemoveObject(s.ctx, po.bucket, obj.Key, minio.RemoveObjectOptions{}) + if err != nil /*&& err.Code != 200*/ /* @FIXME workaround for garage's bug #98 */ { + log.Println("delete err", err) + return err + } + } + + return nil } func (s S3FS) Stat(ctx context.Context, name string) (os.FileInfo, error) { |