robotfs/pkg/fs/filesystem_delete.go

109 lines
2.6 KiB
Go

package fs
import (
"context"
"fmt"
"gosvc/logger"
"robotfs/utils"
)
func (fs *FileSystem) DeleteDirectory(ctx context.Context, path utils.FullPath, isRecursive, ignoreRecursiveError bool) error {
locker := fs.locker.AcquireLock(string(path))
defer fs.locker.ReleaseLock(locker)
if string(path) == "/" {
return nil
}
entry, err := fs.FindEntry(ctx, path)
if err != nil {
return err
}
if entry.IsDir {
err = fs.doBatchDeleteFolderMetaAndData(ctx, entry, isRecursive, ignoreRecursiveError)
if err != nil {
return err
}
}
// Delete the directory entry itself
err = fs.doDeleteEntryMetaAndData(ctx, entry)
if err != nil {
return err
}
if err := utils.Remove(fs.root, string(path), isRecursive); err != nil {
return err
}
return nil
}
func (fs *FileSystem) doBatchDeleteFolderMetaAndData(ctx context.Context, entry *utils.Entry, isRecursive, ignoreRecursiveError bool) error {
logger.Info("deleting folder => %s", entry.FullPath)
lastFileName := ""
includeLastFile := false
for {
lastFileName, err := fs.doListDirectoryEntries(ctx, entry.FullPath, lastFileName, includeLastFile, 1000, func(sub *utils.Entry) bool {
if sub.IsDir {
// Recursively delete subdirectory
err := fs.doBatchDeleteFolderMetaAndData(ctx, sub, isRecursive, ignoreRecursiveError)
if err == nil {
err = fs.doDeleteEntryMetaAndData(ctx, sub)
}
if err != nil && !ignoreRecursiveError {
return false
}
} else {
// Delete file entry
err := fs.doDeleteEntryMetaAndData(ctx, sub)
if err != nil && !ignoreRecursiveError {
return false
}
}
return true
})
if err != nil {
return fmt.Errorf("list folder %s: %v", entry.FullPath, err)
}
if lastFileName == "" && !isRecursive {
// Check if there are any entries
hasEntries := false
_, err := fs.doListDirectoryEntries(ctx, entry.FullPath, "", false, 1, func(_ *utils.Entry) bool {
hasEntries = true
return false
})
if err != nil {
return fmt.Errorf("check directory empty: %v", err)
}
if hasEntries {
return fmt.Errorf("directory not empty: %s", entry.FullPath)
}
}
if lastFileName == "" {
break
}
}
if storeDeletionErr := fs.meta.DeleteFolderChildren(ctx, entry.FullPath); storeDeletionErr != nil {
return fmt.Errorf("delete folder children metadata: %v", storeDeletionErr)
}
return nil
}
func (fs *FileSystem) doDeleteEntryMetaAndData(ctx context.Context, entry *utils.Entry) error {
logger.Info("deleting entry => %s", entry.FullPath)
if storeDeletionErr := fs.meta.DeleteEntry(ctx, entry.FullPath); storeDeletionErr != nil {
return fmt.Errorf("delete entry metadata: %v", storeDeletionErr)
}
return nil
}