fix: add ResolveRenameOp to handle directory renames

RenameNode was calling Resolve() which generated blob keys for
directories that don't have blobs, causing 'key not found' errors.

Added ResolveRenameOp to BlobKeyResolver interface:
- FlatKeyResolver returns nil (UUIDs don't change on rename)
- HierarchicalKeyResolver returns move op for files and directories

This allows directory renames to work correctly with flat storage,
and leverages os.Rename for atomic directory moves with hierarchical.

Co-authored-by: Ona <no-reply@ona.com>
This commit is contained in:
2026-01-04 23:58:43 +00:00
parent b8e1671248
commit d0c2a21ffd
5 changed files with 75 additions and 12 deletions

View File

@@ -77,3 +77,34 @@ func (r *HierarchicalKeyResolver) ResolveBulkMoveOps(ctx context.Context, db bun
return ops, nil
}
// ResolveRenameOp returns the blob move operation for renaming a node.
// For hierarchical storage, both files and directories need blob moves since
// the key is path-based. os.Rename handles directory moves atomically.
func (r *HierarchicalKeyResolver) ResolveRenameOp(ctx context.Context, db bun.IDB, node *Node, newName string) (*BlobMoveOp, error) {
oldPath, err := buildNodeAbsolutePathString(ctx, db, node)
if err != nil {
return nil, err
}
parentPath, err := buildPathFromNodeID(ctx, db, node.ParentID)
if err != nil {
return nil, err
}
var newPath string
if parentPath == "" {
newPath = newName
} else {
newPath = fmt.Sprintf("%s/%s", parentPath, newName)
}
oldKey := blob.Key(fmt.Sprintf("%s/%s", node.DriveID, oldPath))
newKey := blob.Key(fmt.Sprintf("%s/%s", node.DriveID, newPath))
return &BlobMoveOp{
Node: node,
OldKey: oldKey,
NewKey: newKey,
}, nil
}