package migration import ( "context" "fmt" "io/fs" "os" "path/filepath" "github.com/SecurityBrewery/catalyst/app/database" "github.com/SecurityBrewery/catalyst/app/database/sqlc" "github.com/SecurityBrewery/catalyst/app/upload" ) type filesMigration struct{} func newFilesMigration() func() (migration, error) { return func() (migration, error) { return filesMigration{}, nil } } func (filesMigration) name() string { return "005_pocketbase_files_to_tusd" } func (filesMigration) up(ctx context.Context, queries *sqlc.Queries, dir string, uploader *upload.Uploader) error { oldUploadDir := filepath.Join(dir, "storage") if _, err := os.Stat(oldUploadDir); os.IsNotExist(err) { // If the old upload directory does not exist, we assume no migration is needed. return nil } oldUploadRoot, err := os.OpenRoot(oldUploadDir) if err != nil { return fmt.Errorf("open old uploads root: %w", err) } files, err := database.PaginateItems(ctx, func(ctx context.Context, offset, limit int64) ([]sqlc.ListFilesRow, error) { return queries.ListFiles(ctx, sqlc.ListFilesParams{Limit: limit, Offset: offset}) }) if err != nil { return fmt.Errorf("list files: %w", err) } for _, file := range files { data, err := fs.ReadFile(oldUploadRoot.FS(), filepath.Join(file.ID, file.Blob)) if err != nil { return fmt.Errorf("read file %s: %w", file.Blob, err) } if _, err := uploader.CreateFile(file.ID, file.Name, data); err != nil { return err } } return nil }