mirror of https://github.com/cloudreve/Cloudreve
103 lines
2.5 KiB
Go
103 lines
2.5 KiB
Go
package migrator
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/cloudreve/Cloudreve/v4/application/migrator/model"
|
|
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
|
"github.com/cloudreve/Cloudreve/v4/pkg/conf"
|
|
)
|
|
|
|
func (m *Migrator) migrateShare() error {
|
|
m.l.Info("Migrating shares...")
|
|
batchSize := 1000
|
|
offset := m.state.ShareOffset
|
|
ctx := context.Background()
|
|
|
|
if offset > 0 {
|
|
m.l.Info("Resuming share migration from offset %d", offset)
|
|
}
|
|
|
|
for {
|
|
m.l.Info("Migrating shares with offset %d", offset)
|
|
var shares []model.Share
|
|
if err := model.DB.Limit(batchSize).Offset(offset).Find(&shares).Error; err != nil {
|
|
return fmt.Errorf("failed to list v3 shares: %w", err)
|
|
}
|
|
|
|
if len(shares) == 0 {
|
|
if m.dep.ConfigProvider().Database().Type == conf.PostgresDB {
|
|
m.l.Info("Resetting share ID sequence for postgres...")
|
|
m.v4client.Share.ExecContext(ctx, "SELECT SETVAL('shares_id_seq', (SELECT MAX(id) FROM shares))")
|
|
}
|
|
break
|
|
}
|
|
|
|
tx, err := m.v4client.Tx(ctx)
|
|
if err != nil {
|
|
_ = tx.Rollback()
|
|
return fmt.Errorf("failed to start transaction: %w", err)
|
|
}
|
|
|
|
for _, s := range shares {
|
|
sourceId := int(s.SourceID)
|
|
if !s.IsDir {
|
|
sourceId += m.state.LastFolderID
|
|
}
|
|
|
|
// check if file exists
|
|
_, err = tx.File.Query().Where(file.ID(sourceId)).First(ctx)
|
|
if err != nil {
|
|
m.l.Warning("File %d not found, skipping share %d", sourceId, s.ID)
|
|
continue
|
|
}
|
|
|
|
// check if user exist
|
|
if _, ok := m.state.UserIDs[int(s.UserID)]; !ok {
|
|
m.l.Warning("User %d not found, skipping share %d", s.UserID, s.ID)
|
|
continue
|
|
}
|
|
|
|
stm := tx.Share.Create().
|
|
SetCreatedAt(formatTime(s.CreatedAt)).
|
|
SetUpdatedAt(formatTime(s.UpdatedAt)).
|
|
SetViews(s.Views).
|
|
SetRawID(int(s.ID)).
|
|
SetDownloads(s.Downloads).
|
|
SetFileID(sourceId).
|
|
SetUserID(int(s.UserID))
|
|
|
|
if s.Password != "" {
|
|
stm.SetPassword(s.Password)
|
|
}
|
|
|
|
if s.Expires != nil {
|
|
stm.SetNillableExpires(s.Expires)
|
|
}
|
|
|
|
if s.RemainDownloads >= 0 {
|
|
stm.SetRemainDownloads(s.RemainDownloads)
|
|
}
|
|
|
|
if _, err := stm.Save(ctx); err != nil {
|
|
_ = tx.Rollback()
|
|
return fmt.Errorf("failed to create share %d: %w", s.ID, err)
|
|
}
|
|
}
|
|
|
|
if err := tx.Commit(); err != nil {
|
|
return fmt.Errorf("failed to commit transaction: %w", err)
|
|
}
|
|
|
|
offset += batchSize
|
|
m.state.ShareOffset = offset
|
|
if err := m.saveState(); err != nil {
|
|
m.l.Warning("Failed to save state after share batch: %s", err)
|
|
} else {
|
|
m.l.Info("Saved migration state after processing this batch")
|
|
}
|
|
}
|
|
return nil
|
|
}
|