fix(dbfs): file modified_at should not be updated by ent

This commit is contained in:
Aaron Liu
2025-08-05 15:11:32 +08:00
parent e31a6cbcb3
commit 80b25e88ee
18 changed files with 110 additions and 350 deletions

View File

@@ -3,6 +3,7 @@ package dbfs
import (
"context"
"fmt"
"time"
"github.com/cloudreve/Cloudreve/v4/inventory"
"github.com/cloudreve/Cloudreve/v4/inventory/types"
@@ -100,6 +101,7 @@ func (f *DBFS) PatchMetadata(ctx context.Context, path []*fs.URI, metas ...fs.Me
metadataMap := make(map[string]string)
privateMap := make(map[string]bool)
deleted := make([]string, 0)
updateModifiedAt := false
for _, meta := range metas {
if meta.Remove {
deleted = append(deleted, meta.Key)
@@ -109,6 +111,9 @@ func (f *DBFS) PatchMetadata(ctx context.Context, path []*fs.URI, metas ...fs.Me
if meta.Private {
privateMap[meta.Key] = meta.Private
}
if meta.UpdateModifiedAt {
updateModifiedAt = true
}
}
fc, tx, ctx, err := inventory.WithTx(ctx, f.fileClient)
@@ -128,6 +133,13 @@ func (f *DBFS) PatchMetadata(ctx context.Context, path []*fs.URI, metas ...fs.Me
return fmt.Errorf("failed to remove metadata: %w", err)
}
}
if updateModifiedAt {
if err := fc.UpdateModifiedAt(ctx, target.Model, time.Now()); err != nil {
_ = inventory.Rollback(tx)
return fmt.Errorf("failed to update file modified at: %w", err)
}
}
}
if err := inventory.Commit(tx); err != nil {

View File

@@ -203,10 +203,11 @@ type (
}
MetadataPatch struct {
Key string `json:"key" binding:"required"`
Value string `json:"value"`
Private bool `json:"private" binding:"ne=true"`
Remove bool `json:"remove"`
Key string `json:"key" binding:"required"`
Value string `json:"value"`
Private bool `json:"private" binding:"ne=true"`
Remove bool `json:"remove"`
UpdateModifiedAt bool `json:"-"`
}
// ListFileResult result of listing files.

View File

@@ -43,6 +43,8 @@ var (
// validateColor validates a color value
validateColor = func(optional bool) metadataValidator {
return func(ctx context.Context, m *manager, patch *fs.MetadataPatch) error {
patch.UpdateModifiedAt = true
if patch.Remove {
return nil
}
@@ -67,6 +69,8 @@ var (
return fmt.Errorf("cannot remove system metadata")
}
patch.UpdateModifiedAt = true
dep := dependency.FromContext(ctx)
// Validate share owner is valid hashid
if patch.Key == shareOwnerMetadataKey {
@@ -96,6 +100,8 @@ var (
customizeMetadataSuffix: {
iconColorMetadataKey: validateColor(false),
emojiIconMetadataKey: func(ctx context.Context, m *manager, patch *fs.MetadataPatch) error {
patch.UpdateModifiedAt = true
if patch.Remove {
return nil
}
@@ -125,6 +131,8 @@ var (
},
tagMetadataSuffix: {
wildcardMetadataKey: func(ctx context.Context, m *manager, patch *fs.MetadataPatch) error {
patch.UpdateModifiedAt = true
if err := validateColor(true)(ctx, m, patch); err != nil {
return err
}
@@ -138,6 +146,8 @@ var (
},
customPropsMetadataSuffix: {
wildcardMetadataKey: func(ctx context.Context, m *manager, patch *fs.MetadataPatch) error {
patch.UpdateModifiedAt = true
if patch.Remove {
return nil
}
@@ -260,40 +270,44 @@ var (
)
func (m *manager) PatchMedata(ctx context.Context, path []*fs.URI, data ...fs.MetadataPatch) error {
if err := m.validateMetadata(ctx, data...); err != nil {
data, err := m.validateMetadata(ctx, data...)
if err != nil {
return err
}
return m.fs.PatchMetadata(ctx, path, data...)
}
func (m *manager) validateMetadata(ctx context.Context, data ...fs.MetadataPatch) error {
func (m *manager) validateMetadata(ctx context.Context, data ...fs.MetadataPatch) ([]fs.MetadataPatch, error) {
validated := make([]fs.MetadataPatch, 0, len(data))
for _, patch := range data {
category := strings.Split(patch.Key, ":")
if len(category) < 2 {
return serializer.NewError(serializer.CodeParamErr, "Invalid metadata key", nil)
return validated, serializer.NewError(serializer.CodeParamErr, "Invalid metadata key", nil)
}
categoryValidators, ok := validators[category[0]]
if !ok {
return serializer.NewError(serializer.CodeParamErr, "Invalid metadata key",
return validated, serializer.NewError(serializer.CodeParamErr, "Invalid metadata key",
fmt.Errorf("unknown category: %s", category[0]))
}
// Explicit validators
if v, ok := categoryValidators[patch.Key]; ok {
if err := v(ctx, m, &patch); err != nil {
return serializer.NewError(serializer.CodeParamErr, "Invalid metadata patch", err)
return validated, serializer.NewError(serializer.CodeParamErr, "Invalid metadata patch", err)
}
}
// Wildcard validators
if v, ok := categoryValidators[wildcardMetadataKey]; ok {
if err := v(ctx, m, &patch); err != nil {
return serializer.NewError(serializer.CodeParamErr, "Invalid metadata patch", err)
return validated, serializer.NewError(serializer.CodeParamErr, "Invalid metadata patch", err)
}
}
validated = append(validated, patch)
}
return nil
return validated, nil
}

View File

@@ -115,7 +115,7 @@ func (m *manager) Create(ctx context.Context, path *fs.URI, fileType types.FileT
isSymbolic := false
if o.Metadata != nil {
if err := m.validateMetadata(ctx, lo.MapToSlice(o.Metadata, func(key string, value string) fs.MetadataPatch {
_, err := m.validateMetadata(ctx, lo.MapToSlice(o.Metadata, func(key string, value string) fs.MetadataPatch {
if key == shareRedirectMetadataKey {
isSymbolic = true
}
@@ -124,7 +124,8 @@ func (m *manager) Create(ctx context.Context, path *fs.URI, fileType types.FileT
Key: key,
Value: value,
}
})...); err != nil {
})...)
if err != nil {
return nil, err
}
}

View File

@@ -55,7 +55,7 @@ func (m *manager) CreateUploadSession(ctx context.Context, req *fs.UploadRequest
// Validate metadata
if req.Props.Metadata != nil {
if err := m.validateMetadata(ctx, lo.MapToSlice(req.Props.Metadata, func(key string, value string) fs.MetadataPatch {
if _, err := m.validateMetadata(ctx, lo.MapToSlice(req.Props.Metadata, func(key string, value string) fs.MetadataPatch {
return fs.MetadataPatch{
Key: key,
Value: value,