mirror of
https://github.com/usememos/memos.git
synced 2025-04-17 19:07:26 +02:00
chore: improve resource internal_path migrator (#2698)
* chore: improve internal path migrator - handle mixed path styles - handle Windows paths - add tests * chore: fix goimports error
This commit is contained in:
parent
914c0620c4
commit
369b8af109
@ -59,11 +59,14 @@ var (
|
|||||||
}
|
}
|
||||||
|
|
||||||
store := store.New(dbDriver, profile)
|
store := store.New(dbDriver, profile)
|
||||||
if err := store.MigrateResourceInternalPath(ctx); err != nil {
|
|
||||||
cancel()
|
go func() {
|
||||||
log.Error("failed to migrate resource internal path", zap.Error(err))
|
if err := store.MigrateResourceInternalPath(ctx); err != nil {
|
||||||
return
|
cancel()
|
||||||
}
|
log.Error("failed to migrate resource internal path", zap.Error(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
s, err := server.NewServer(ctx, profile, store)
|
s, err := server.NewServer(ctx, profile, store)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2,10 +2,15 @@ package store
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"path/filepath"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/usememos/memos/internal/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MigrateResourceInternalPath migrates resource internal path from absolute path to relative path.
|
// MigrateResourceInternalPath migrates resource internal path from absolute path to relative path.
|
||||||
@ -15,30 +20,37 @@ func (s *Store) MigrateResourceInternalPath(ctx context.Context) error {
|
|||||||
return errors.Wrap(err, "failed to list resources")
|
return errors.Wrap(err, "failed to list resources")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dataPath := strings.ReplaceAll(s.Profile.Data, `\`, "/")
|
||||||
|
migrateStartTime := time.Now()
|
||||||
|
migratedCount := 0
|
||||||
for _, resource := range resources {
|
for _, resource := range resources {
|
||||||
if resource.InternalPath == "" {
|
if resource.InternalPath == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
internalPath := resource.InternalPath
|
internalPath := strings.ReplaceAll(resource.InternalPath, `\`, "/")
|
||||||
if filepath.IsAbs(internalPath) {
|
if !strings.HasPrefix(internalPath, dataPath) {
|
||||||
if !strings.HasPrefix(internalPath, s.Profile.Data) {
|
continue
|
||||||
// Invalid internal path, skip.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
internalPath = strings.TrimPrefix(internalPath, s.Profile.Data)
|
|
||||||
for strings.HasPrefix(internalPath, "/") {
|
|
||||||
internalPath = strings.TrimPrefix(internalPath, "/")
|
|
||||||
}
|
|
||||||
_, err := s.UpdateResource(ctx, &UpdateResource{
|
|
||||||
ID: resource.ID,
|
|
||||||
InternalPath: &internalPath,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "failed to update resource")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internalPath = strings.TrimPrefix(internalPath, dataPath)
|
||||||
|
|
||||||
|
for os.IsPathSeparator(internalPath[0]) {
|
||||||
|
internalPath = internalPath[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := s.UpdateResource(ctx, &UpdateResource{
|
||||||
|
ID: resource.ID,
|
||||||
|
InternalPath: &internalPath,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to update local resource path")
|
||||||
|
}
|
||||||
|
migratedCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if migratedCount > 0 {
|
||||||
|
log.Info(fmt.Sprintf("migrated %d local resource paths in %s", migratedCount, time.Since(migrateStartTime)))
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
56
test/store/migrator_test.go
Normal file
56
test/store/migrator_test.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package teststore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/usememos/memos/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMigrateResourceInternalPath(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
ts := NewTestingStore(ctx, t)
|
||||||
|
user, err := createTestingHostUser(ctx, ts)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
testCases := []map[string]string{
|
||||||
|
{
|
||||||
|
ts.Profile.Data + "/assets/test.jpg": "assets/test.jpg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ts.Profile.Data + `\assets\test.jpg`: "assets/test.jpg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"/unhandled/path/test.jpg": "/unhandled/path/test.jpg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`C:\unhandled\path\assets\test.jpg`: `C:\unhandled\path\assets\test.jpg`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
for input, expectedOutput := range testCase {
|
||||||
|
resourceCreate := &store.Resource{
|
||||||
|
CreatorID: user.ID,
|
||||||
|
InternalPath: input,
|
||||||
|
}
|
||||||
|
createdResource, err := ts.CreateResource(ctx, resourceCreate)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = ts.MigrateResourceInternalPath(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
findResource := &store.FindResource{
|
||||||
|
ID: &createdResource.ID,
|
||||||
|
}
|
||||||
|
resource, err := ts.GetResource(ctx, findResource)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, expectedOutput, resource.InternalPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ts.Close()
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user