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

@@ -598,7 +598,8 @@ func (vfs *VirtualFS) RenameNode(ctx context.Context, db bun.IDB, node *Node, na
return ErrAccessDenied
}
oldKey, err := vfs.keyResolver.Resolve(ctx, db, node)
// Resolve rename operation before updating DB (needs old path)
renameOp, err := vfs.keyResolver.ResolveRenameOp(ctx, db, node, name)
if err != nil {
return err
}
@@ -617,22 +618,18 @@ func (vfs *VirtualFS) RenameNode(ctx context.Context, db bun.IDB, node *Node, na
return err
}
newKey, err := vfs.keyResolver.Resolve(ctx, db, node)
if err != nil {
return err
}
if oldKey != newKey {
err = vfs.blobStore.Move(ctx, oldKey, newKey)
// Execute blob move if needed
if renameOp != nil {
err = vfs.blobStore.Move(ctx, renameOp.OldKey, renameOp.NewKey)
if err != nil {
return err
}
if vfs.keyResolver.ShouldPersistKey() {
node.BlobKey = newKey
node.BlobKey = renameOp.NewKey
_, err = db.NewUpdate().Model(node).
WherePK().
Set("blob_key = ?", newKey).
Set("blob_key = ?", renameOp.NewKey).
Exec(ctx)
if err != nil {
return err