robotfs/engine/filesystem_delete.go

109 lines
2.6 KiB
Go

package engine
import (
"context"
"fmt"
"gosvc/logger"
"robotfs/utils"
)
func (f *FileSystemManager) DeleteDirectory(ctx context.Context, path utils.FullPath, isRecursive, ignoreRecursiveError bool) error {
f.Lock()
defer f.Unlock()
if string(path) == "/" {
return nil
}
entry, err := f.FindEntry(ctx, path)
if err != nil {
return err
}
if entry.IsDir {
err = f.doBatchDeleteFolderMetaAndData(ctx, entry, isRecursive, ignoreRecursiveError)
if err != nil {
return err
}
}
// Delete the directory entry itself
err = f.doDeleteEntryMetaAndData(ctx, entry)
if err != nil {
return err
}
if err := utils.Remove(f.root, string(path), isRecursive); err != nil {
return err
}
return nil
}
func (f *FileSystemManager) doBatchDeleteFolderMetaAndData(ctx context.Context, entry *utils.Entry, isRecursive, ignoreRecursiveError bool) error {
logger.Info("deleting folder => %s", entry.FullPath)
lastFileName := ""
includeLastFile := false
for {
lastFileName, err := f.doListDirectoryEntries(ctx, entry.FullPath, lastFileName, includeLastFile, 1000, func(sub *utils.Entry) bool {
if sub.IsDir {
// Recursively delete subdirectory
err := f.doBatchDeleteFolderMetaAndData(ctx, sub, isRecursive, ignoreRecursiveError)
if err == nil {
err = f.doDeleteEntryMetaAndData(ctx, sub)
}
if err != nil && !ignoreRecursiveError {
return false
}
} else {
// Delete file entry
err := f.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 := f.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 := f.meta.DeleteFolderChildren(ctx, entry.FullPath); storeDeletionErr != nil {
return fmt.Errorf("delete folder children metadata: %v", storeDeletionErr)
}
return nil
}
func (f *FileSystemManager) doDeleteEntryMetaAndData(ctx context.Context, entry *utils.Entry) error {
logger.Info("deleting entry => %s", entry.FullPath)
if storeDeletionErr := f.meta.DeleteEntry(ctx, entry.FullPath); storeDeletionErr != nil {
return fmt.Errorf("delete entry metadata: %v", storeDeletionErr)
}
return nil
}