109 lines
2.7 KiB
Go
109 lines
2.7 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 {
|
|
locker := f.locker.AcquireLock(string(path))
|
|
defer f.locker.ReleaseLock(locker)
|
|
|
|
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
|
|
}
|