diff --git a/local_test.go b/local_test.go index 365af65..64d76ff 100644 --- a/local_test.go +++ b/local_test.go @@ -54,6 +54,20 @@ func TestStorageLocal(t *testing.T) { assert.Equal(t, "test2.txt", copyFileInfo.Name) assert.Equal(t, int64(len("hi")), copyFileInfo.Size) + t.Log("== CopyDir ==") + + err = stor.CopyDir("testing", "testing2") + assert.NoError(t, err) + + copyFiles, err := stor.ReadDir("testing2") + assert.NoError(t, err) + assert.Equal(t, 3, len(copyFiles)) + + t.Log("== DeleteDir ==") + + err = stor.DeleteDir("testing2") + assert.NoError(t, err) + t.Log("== Move ==") err = stor.Move("test2.txt", "test3.txt") assert.NoError(t, err) diff --git a/s3_test.go b/s3_test.go index 2d79279..2ff95b8 100644 --- a/s3_test.go +++ b/s3_test.go @@ -65,6 +65,20 @@ func TestStorageS3(t *testing.T) { assert.Equal(t, "test2.txt", copyFileInfo.Name) assert.Equal(t, int64(len("hi")), copyFileInfo.Size) + t.Log("== CopyDir ==") + + err = stor.CopyDir("testing", "testing2") + assert.NoError(t, err) + + copyFiles, err := stor.ReadDir("testing2") + assert.NoError(t, err) + assert.Equal(t, 3, len(copyFiles)) + + t.Log("== DeleteDir ==") + + err = stor.DeleteDir("testing2") + assert.NoError(t, err) + t.Log("== Move ==") err = stor.Move("test2.txt", "test3.txt") diff --git a/storage.go b/storage.go index f9b783a..1dbb3f7 100644 --- a/storage.go +++ b/storage.go @@ -368,3 +368,71 @@ func (s *Storage) ReadDir(name string) ([]FileInfo, error) { } return fileInfo, nil } + +// CopyDir copies a directory from one place to another. +// It takes a folder nae, and the destination folder name as its parameter. +// The function returns an error, if any. +func (s *Storage) CopyDir(name string, dst string) error { + if s.s3Client != nil { + var fileInfo []FileInfo + for object := range s.s3Client.ListObjects(s.ctx, s.config.S3BucketName, minio.ListObjectsOptions{ + Prefix: name + "/", + Recursive: true, + }) { + if object.Err != nil { + minioErr := minio.ToErrorResponse(object.Err) + if minioErr.Code == "NoSuchKey" { + return ErrFolderNotFound + } + return object.Err + } + fileInfo = append(fileInfo, FileInfo{ + Name: object.Key, + Size: object.Size, + ModTime: object.LastModified, + Mode: fs.FileMode(0777), + IsDir: object.Size == 0, + }) + } + + for _, object := range fileInfo { + cutStr, _ := strings.CutPrefix(object.Name, name+"/") + if _, err := s.s3Client.CopyObject(s.ctx, minio.CopyDestOptions{ + Bucket: s.config.S3BucketName, + Object: dst + "/" + cutStr, + }, minio.CopySrcOptions{ + Bucket: s.config.S3BucketName, + Object: object.Name, + }); err != nil { + return err + } + } + + return nil + } else { + return os.Rename(filepath.Join(s.config.Path, name), filepath.Join(s.config.Path, dst)) + } +} + +// DeleteDir deletes all files within a certain directory. +// It takes a folder name as its parameter. +// The function returns an error, if any. +func (s *Storage) DeleteDir(name string) error { + if s.s3Client != nil { + objChan := s.s3Client.ListObjects(s.ctx, s.config.S3BucketName, minio.ListObjectsOptions{Prefix: name + "/", Recursive: true}) + + for remObjErr := range s.s3Client.RemoveObjects(s.ctx, s.config.S3BucketName, objChan, minio.RemoveObjectsOptions{}) { + if remObjErr.Err != nil { + minioErr := minio.ToErrorResponse(remObjErr.Err) + if minioErr.Code == "NoSuchKey" { + return ErrFolderNotFound + } else { + return remObjErr.Err + } + } + } + return nil + } else { + return os.RemoveAll(filepath.Join(s.config.Path, name)) + } +}