mirror of
https://github.com/photoprism/photoprism.git
synced 2025-10-06 09:19:33 +08:00
972 lines
27 KiB
Go
972 lines
27 KiB
Go
package commands
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/urfave/cli/v2"
|
|
|
|
"github.com/photoprism/photoprism/internal/config"
|
|
"github.com/photoprism/photoprism/internal/entity"
|
|
"github.com/photoprism/photoprism/internal/entity/migrate"
|
|
"github.com/photoprism/photoprism/pkg/txt/report"
|
|
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/clause"
|
|
)
|
|
|
|
var MigrationsStatusCommand = &cli.Command{
|
|
Name: "ls",
|
|
Aliases: []string{"status", "show"},
|
|
Usage: "Displays the status of schema migrations",
|
|
ArgsUsage: "[migrations...]",
|
|
Flags: report.CliFlags,
|
|
Action: migrationsStatusAction,
|
|
}
|
|
|
|
var MigrationsRunCommand = &cli.Command{
|
|
Name: "run",
|
|
Aliases: []string{"execute", "migrate"},
|
|
Usage: "Executes database schema migrations",
|
|
ArgsUsage: "[migrations...]",
|
|
Flags: []cli.Flag{
|
|
&cli.BoolFlag{
|
|
Name: "failed",
|
|
Aliases: []string{"f"},
|
|
Usage: "run previously failed migrations",
|
|
},
|
|
&cli.BoolFlag{
|
|
Name: "trace",
|
|
Aliases: []string{"t"},
|
|
Usage: "show trace logs for debugging",
|
|
},
|
|
},
|
|
Action: migrationsRunAction,
|
|
}
|
|
|
|
var MigrationsTransferCommand = &cli.Command{
|
|
Name: "transfer",
|
|
Aliases: []string{"copy"},
|
|
Usage: "Executes database data transfers",
|
|
ArgsUsage: "[migrations...]",
|
|
Flags: []cli.Flag{
|
|
&cli.BoolFlag{
|
|
Name: "force",
|
|
Aliases: []string{"f"},
|
|
Usage: "truncate target tables if populated",
|
|
},
|
|
&cli.BoolFlag{
|
|
Name: "trace",
|
|
Aliases: []string{"t"},
|
|
Usage: "show trace logs for debugging",
|
|
},
|
|
},
|
|
Action: migrationsTransferAction,
|
|
}
|
|
|
|
// MigrationsCommands registers the "migrations" CLI command.
|
|
var MigrationsCommands = &cli.Command{
|
|
Name: "migrations",
|
|
Usage: "Database schema migration subcommands",
|
|
Subcommands: []*cli.Command{
|
|
MigrationsStatusCommand,
|
|
MigrationsRunCommand,
|
|
MigrationsTransferCommand,
|
|
},
|
|
}
|
|
|
|
// migrationsStatusAction lists the status of schema migration.
|
|
func migrationsStatusAction(ctx *cli.Context) error {
|
|
conf, err := InitConfig(ctx)
|
|
|
|
_, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer conf.Shutdown()
|
|
|
|
var ids []string
|
|
|
|
// Check argument for specific migrations to be run.
|
|
if migrations := strings.TrimSpace(ctx.Args().First()); migrations != "" {
|
|
ids = strings.Fields(migrations)
|
|
}
|
|
|
|
db := conf.Db()
|
|
|
|
status, err := migrate.Status(db, ids)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Report columns.
|
|
cols := []string{"ID", "Dialect", "Stage", "Started At", "Finished At", "Status"}
|
|
|
|
// Report rows.
|
|
rows := make([][]string, 0, len(status))
|
|
|
|
for _, m := range status {
|
|
var stage, started, finished, info string
|
|
|
|
if m.Stage == "" {
|
|
stage = "main"
|
|
} else {
|
|
stage = m.Stage
|
|
}
|
|
|
|
if m.StartedAt.IsZero() {
|
|
started = "-"
|
|
} else {
|
|
started = m.StartedAt.Format("2006-01-02 15:04:05")
|
|
}
|
|
|
|
if m.Finished() {
|
|
finished = m.FinishedAt.Format("2006-01-02 15:04:05")
|
|
} else {
|
|
finished = "-"
|
|
}
|
|
|
|
if m.Error != "" {
|
|
info = m.Error
|
|
} else if m.Finished() {
|
|
info = "OK"
|
|
} else if m.StartedAt.IsZero() {
|
|
info = "-"
|
|
} else if m.Repeat(false) {
|
|
info = "Repeat"
|
|
} else {
|
|
info = "Running?"
|
|
}
|
|
|
|
rows = append(rows, []string{m.ID, m.Dialect, stage, started, finished, info})
|
|
}
|
|
|
|
// Display report.
|
|
info, err := report.RenderFormat(rows, cols, report.CliFormat(ctx))
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Println(info)
|
|
|
|
return nil
|
|
}
|
|
|
|
// migrationsRunAction executes database schema migrations.
|
|
func migrationsRunAction(ctx *cli.Context) error {
|
|
if ctx.Args().First() == "ls" {
|
|
return fmt.Errorf("run '%s migrations ls' to display the status of schema migrations", filepath.Base(os.Args[0]))
|
|
}
|
|
|
|
start := time.Now()
|
|
|
|
conf := config.NewConfig(ctx)
|
|
|
|
_, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
if err := conf.Init(); err != nil {
|
|
return err
|
|
}
|
|
|
|
defer conf.Shutdown()
|
|
|
|
if ctx.Bool("trace") {
|
|
log.SetLevel(logrus.TraceLevel)
|
|
log.Infoln("migrate: enabled trace mode")
|
|
}
|
|
|
|
runFailed := ctx.Bool("failed")
|
|
|
|
if runFailed {
|
|
log.Infoln("migrate: running previously failed migrations")
|
|
}
|
|
|
|
var ids []string
|
|
|
|
// Check argument for specific migrations to be run.
|
|
if migrations := strings.TrimSpace(ctx.Args().First()); migrations != "" {
|
|
ids = strings.Fields(migrations)
|
|
}
|
|
|
|
log.Infoln("migrating database schema...")
|
|
|
|
// Run migrations.
|
|
conf.MigrateDb(runFailed, ids)
|
|
|
|
elapsed := time.Since(start)
|
|
|
|
log.Infof("completed in %s", elapsed)
|
|
|
|
return nil
|
|
}
|
|
|
|
// migrationsTransferAction executes database data migrations.
|
|
func migrationsTransferAction(ctx *cli.Context) error {
|
|
if ctx.Args().First() == "ls" {
|
|
return fmt.Errorf("run '%s migrations ls' to display the status of schema migrations", filepath.Base(os.Args[0]))
|
|
}
|
|
|
|
batchSize := 5
|
|
|
|
start := time.Now()
|
|
|
|
conf := config.NewConfig(ctx)
|
|
tfrConf := config.NewConfig(ctx)
|
|
|
|
//log = event.Log
|
|
|
|
if err := tfrConf.SwapDBAndTransfer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
_, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
if err := conf.Init(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := tfrConf.Init(); err != nil {
|
|
return err
|
|
}
|
|
|
|
defer conf.Shutdown()
|
|
defer tfrConf.Shutdown()
|
|
|
|
if ctx.Bool("trace") {
|
|
log.SetLevel(logrus.TraceLevel)
|
|
log.Infoln("migrate: enabled trace mode")
|
|
}
|
|
|
|
var ids []string
|
|
|
|
runForced := ctx.Bool("force")
|
|
log.Infoln("migrate: ensure target is empty...")
|
|
if tfrConf.Db().Unscoped().Migrator().HasTable(&entity.Photo{}) {
|
|
var photoCount int64
|
|
if err := tfrConf.Db().Unscoped().Model(&entity.Photo{}).Count(&photoCount).Error; err != nil {
|
|
log.Errorf("migrate: count of photos has failed with %s", err.Error())
|
|
return err
|
|
}
|
|
if photoCount > 0 {
|
|
if !runForced {
|
|
errmsg := fmt.Sprintf("migrate: transfer target database is not empty, %d photos found", photoCount)
|
|
log.Error(errmsg)
|
|
return fmt.Errorf(errmsg)
|
|
} else {
|
|
entity.SetDbProvider(tfrConf)
|
|
entity.Entities.Truncate(tfrConf.Db())
|
|
}
|
|
} else {
|
|
runForced = false
|
|
}
|
|
}
|
|
|
|
log.Infoln("migrate: migrating database schema...")
|
|
|
|
// Run migrations.
|
|
log.Infof("migrate: migrating against %s", tfrConf.DatabaseDsn())
|
|
entity.SetDbProvider(tfrConf)
|
|
tfrConf.MigrateDb(false, ids)
|
|
if runForced {
|
|
entity.CreateDefaultFixtures()
|
|
}
|
|
log.Infof("migrate: migrating against %s", conf.DatabaseDsn())
|
|
entity.SetDbProvider(conf)
|
|
conf.MigrateDb(false, ids)
|
|
|
|
// Copy tables
|
|
|
|
// Replace the admin user with the source one.
|
|
var userRecord entity.User
|
|
if err := tfrConf.Db().Unscoped().
|
|
Where("id = 1").
|
|
Find(&userRecord).Error; err != nil {
|
|
log.Errorf("migrate: error in admin user preselect %s", err.Error())
|
|
return err
|
|
} else {
|
|
if err = tfrConf.Db().Unscoped().Delete(&entity.UserDetails{UserUID: userRecord.UserUID}).Error; err != nil {
|
|
log.Errorf("migrate: error in admin user cleanup user details %s", err.Error())
|
|
return err
|
|
}
|
|
if err = tfrConf.Db().Unscoped().Delete(&entity.UserSettings{UserUID: userRecord.UserUID}).Error; err != nil {
|
|
log.Errorf("migrate: error in admin user cleanup user settings %s", err.Error())
|
|
return err
|
|
}
|
|
if err = tfrConf.Db().Unscoped().Delete(&entity.UserShare{UserUID: userRecord.UserUID}).Error; err != nil {
|
|
log.Errorf("migrate: error in admin user cleanup user share %s", err.Error())
|
|
return err
|
|
}
|
|
if err := conf.Db().Unscoped().
|
|
Where("id = 1").
|
|
Find(&userRecord).Error; err != nil {
|
|
log.Errorf("migrate: error in admin user preselect %s", err.Error())
|
|
return err
|
|
} else {
|
|
if err = tfrConf.Db().Save(&userRecord).Error; err != nil {
|
|
log.Errorf("migrate: error in admin user update %s", err.Error())
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
// Bring the rest of the users across
|
|
var users entity.Users
|
|
result := conf.Db().Unscoped().
|
|
//Clauses(clause.OnConflict{UpdateAll: true}). // <-- This is not working against sqlite. Not generating the ON CONFLICT statements.
|
|
Where("id > 1").
|
|
FindInBatches(&users, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newUsers []*entity.User
|
|
for _, user := range users {
|
|
newUsers = append(newUsers, &user)
|
|
}
|
|
if result := tfrConf.Db().Create(newUsers); result.Error != nil {
|
|
log.Errorf("migrate: error in batch user create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of users transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var albums entity.Albums
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&albums, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newAlbums []*entity.Album
|
|
for _, album := range albums {
|
|
newAlbums = append(newAlbums, &album)
|
|
}
|
|
if result := tfrConf.Db().Create(newAlbums); result.Error != nil {
|
|
log.Errorf("migrate: error in batch album create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of albums transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var cameras []entity.Camera
|
|
result = conf.Db().Unscoped().
|
|
Where("id > 1").
|
|
FindInBatches(&cameras, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newCameras []*entity.Camera
|
|
for _, camera := range cameras {
|
|
newCameras = append(newCameras, &camera)
|
|
}
|
|
if result := tfrConf.Db().Create(newCameras); result.Error != nil {
|
|
log.Errorf("migrate: error in batch camera create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of cameras transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var lenses entity.Lenses
|
|
result = conf.Db().Unscoped().
|
|
Where("id > 1").
|
|
FindInBatches(&lenses, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newLenses []*entity.Lens
|
|
for _, lens := range lenses {
|
|
newLenses = append(newLenses, &lens)
|
|
}
|
|
if result := tfrConf.Db().Create(newLenses); result.Error != nil {
|
|
log.Errorf("migrate: error in batch lens create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of lenses transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var places []entity.Place
|
|
result = conf.Db().Unscoped().
|
|
Where("id <> 'zz'").
|
|
FindInBatches(&places, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newPlaces []*entity.Place
|
|
for _, place := range places {
|
|
newPlaces = append(newPlaces, &place)
|
|
}
|
|
if result := tfrConf.Db().Create(newPlaces); result.Error != nil {
|
|
log.Errorf("migrate: error in batch place create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of places transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var cells []entity.Cell
|
|
result = conf.Db().Unscoped().
|
|
Where("id <> 'zz'").
|
|
FindInBatches(&cells, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newCells []*entity.Cell
|
|
for _, cell := range cells {
|
|
newCells = append(newCells, &cell)
|
|
}
|
|
if result := tfrConf.Db().Create(newCells); result.Error != nil {
|
|
log.Errorf("migrate: error in batch cell create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of cells transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var countries entity.Countries
|
|
result = conf.Db().Unscoped().
|
|
Where("id <> 'zz'").
|
|
FindInBatches(&countries, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newCountries []*entity.Country
|
|
for _, country := range countries {
|
|
newCountries = append(newCountries, &country)
|
|
}
|
|
if result := tfrConf.Db().Create(newCountries); result.Error != nil {
|
|
log.Errorf("migrate: error in batch country create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of countries transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var keywords []entity.Keyword
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&keywords, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newKeywords []*entity.Keyword
|
|
for _, keyword := range keywords {
|
|
newKeywords = append(newKeywords, &keyword)
|
|
}
|
|
if result := tfrConf.Db().Create(newKeywords); result.Error != nil {
|
|
log.Errorf("migrate: error in batch keyword create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of keywords transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var labels []entity.Label
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&labels, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newLabels []*entity.Label
|
|
for _, label := range labels {
|
|
newLabels = append(newLabels, &label)
|
|
}
|
|
if result := tfrConf.Db().Create(newLabels); result.Error != nil {
|
|
log.Errorf("migrate: error in batch label create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of labels transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var photos []entity.Photo
|
|
result = conf.Db().Unscoped().
|
|
Preload("Labels", func(db *gorm.DB) *gorm.DB {
|
|
return db.Order("photos_labels.uncertainty ASC, photos_labels.label_id DESC")
|
|
}).
|
|
Preload("Labels.Label").
|
|
Preload("Camera").
|
|
Preload("Lens").
|
|
Preload("Details").
|
|
Preload("Place").
|
|
Preload("Cell").
|
|
Preload("Cell.Place").
|
|
Preload("Albums").
|
|
Preload("Keywords").
|
|
Preload("Labels").
|
|
FindInBatches(&photos, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newPhotos []*entity.Photo
|
|
for _, photo := range photos {
|
|
newPhotos = append(newPhotos, &photo)
|
|
}
|
|
if result := tfrConf.Db().Create(newPhotos); result.Error != nil {
|
|
log.Errorf("migrate: error in batch photo create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of photos transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var files entity.Files
|
|
result = conf.Db().Unscoped().FindInBatches(&files, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newFiles []*entity.File
|
|
for _, file := range files {
|
|
newFiles = append(newFiles, &file)
|
|
}
|
|
if result := tfrConf.Db().Create(newFiles); result.Error != nil {
|
|
log.Errorf("migrate: error in batch file create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of files transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var albumUsers []entity.AlbumUser
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&albumUsers, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newAlbumUsers []*entity.AlbumUser
|
|
for _, albumUser := range albumUsers {
|
|
newAlbumUsers = append(newAlbumUsers, &albumUser)
|
|
}
|
|
if result := tfrConf.Db().Create(newAlbumUsers); result.Error != nil {
|
|
log.Errorf("migrate: error in batch albumuser create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of albumusers transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var clients entity.Clients
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&clients, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newClients []*entity.Client
|
|
for _, client := range clients {
|
|
newClients = append(newClients, &client)
|
|
}
|
|
if result := tfrConf.Db().Create(newClients); result.Error != nil {
|
|
log.Errorf("migrate: error in batch client create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of clients transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var sessions entity.Sessions
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&sessions, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newSessions []*entity.Session
|
|
for _, session := range sessions {
|
|
newSessions = append(newSessions, &session)
|
|
}
|
|
if result := tfrConf.Db().Create(newSessions); result.Error != nil {
|
|
log.Errorf("migrate: error in batch session create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of sessions transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var userdetails []entity.UserDetails
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&userdetails, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newUserDetails []*entity.UserDetails
|
|
for _, userdetail := range userdetails {
|
|
newUserDetails = append(newUserDetails, &userdetail)
|
|
}
|
|
if result := tfrConf.Db().
|
|
Clauses(clause.OnConflict{
|
|
Columns: []clause.Column{{Name: "user_uid"}},
|
|
UpdateAll: true,
|
|
}).Create(newUserDetails); result.Error != nil {
|
|
log.Errorf("migrate: error in batch userdetail create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of userdetails transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var usersettings []entity.UserSettings
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&usersettings, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newUserSettings []*entity.UserSettings
|
|
for _, usersetting := range usersettings {
|
|
newUserSettings = append(newUserSettings, &usersetting)
|
|
}
|
|
if result := tfrConf.Db().
|
|
Clauses(clause.OnConflict{
|
|
Columns: []clause.Column{{Name: "user_uid"}},
|
|
UpdateAll: true,
|
|
}).
|
|
Create(newUserSettings); result.Error != nil {
|
|
log.Errorf("migrate: error in batch usersetting create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of usersettings transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var usershares entity.UserShares
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&usershares, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newUserShares []*entity.UserShare
|
|
for _, usershare := range usershares {
|
|
newUserShares = append(newUserShares, &usershare)
|
|
}
|
|
if result := tfrConf.Db().Create(newUserShares); result.Error != nil {
|
|
log.Errorf("migrate: error in batch usershare create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of usershares transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var categorys []entity.Category
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&categorys, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newCategorys []*entity.Category
|
|
for _, category := range categorys {
|
|
newCategorys = append(newCategorys, &category)
|
|
}
|
|
if result := tfrConf.Db().Create(newCategorys); result.Error != nil {
|
|
log.Errorf("migrate: error in batch category create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of categories transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var duplicates entity.Duplicates
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&duplicates, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newDuplicates []*entity.Duplicate
|
|
for _, duplicate := range duplicates {
|
|
newDuplicates = append(newDuplicates, &duplicate)
|
|
}
|
|
if result := tfrConf.Db().Create(newDuplicates); result.Error != nil {
|
|
log.Errorf("migrate: error in batch duplicate create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of duplicates transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var errors entity.Errors
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&errors, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newErrors []*entity.Error
|
|
for _, error := range errors {
|
|
newErrors = append(newErrors, &error)
|
|
}
|
|
if result := tfrConf.Db().
|
|
Clauses(clause.OnConflict{
|
|
Columns: []clause.Column{{Name: "id"}},
|
|
UpdateAll: true,
|
|
}).
|
|
Create(newErrors); result.Error != nil {
|
|
log.Errorf("migrate: error in batch error create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of errors transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var faces entity.Faces
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&faces, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newFaces []*entity.Face
|
|
for _, face := range faces {
|
|
newFaces = append(newFaces, &face)
|
|
}
|
|
if result := tfrConf.Db().Create(newFaces); result.Error != nil {
|
|
log.Errorf("migrate: error in batch face create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of faces transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var services entity.Services
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&services, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newServices []*entity.Service
|
|
for _, service := range services {
|
|
newServices = append(newServices, &service)
|
|
}
|
|
if result := tfrConf.Db().Create(newServices); result.Error != nil {
|
|
log.Errorf("migrate: error in batch service create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of services transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var fileshares []entity.FileShare
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&fileshares, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newFileShares []*entity.FileShare
|
|
for _, fileshare := range fileshares {
|
|
newFileShares = append(newFileShares, &fileshare)
|
|
}
|
|
if result := tfrConf.Db().Create(newFileShares); result.Error != nil {
|
|
log.Errorf("migrate: error in batch fileshare create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of fileshares transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var filesyncs []entity.FileSync
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&filesyncs, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newFileSyncs []*entity.FileSync
|
|
for _, filesync := range filesyncs {
|
|
newFileSyncs = append(newFileSyncs, &filesync)
|
|
}
|
|
if result := tfrConf.Db().Create(newFileSyncs); result.Error != nil {
|
|
log.Errorf("migrate: error in batch filesync create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of filesyncs transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var folders entity.Folders
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&folders, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newFolders []*entity.Folder
|
|
for _, folder := range folders {
|
|
newFolders = append(newFolders, &folder)
|
|
}
|
|
if result := tfrConf.Db().Create(newFolders); result.Error != nil {
|
|
log.Errorf("migrate: error in batch folder create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of folders transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var links entity.Links
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&links, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newLinks []*entity.Link
|
|
for _, link := range links {
|
|
newLinks = append(newLinks, &link)
|
|
}
|
|
if result := tfrConf.Db().Create(newLinks); result.Error != nil {
|
|
log.Errorf("migrate: error in batch link create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of links transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var markers entity.Markers
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&markers, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newMarkers []*entity.Marker
|
|
for _, marker := range markers {
|
|
newMarkers = append(newMarkers, &marker)
|
|
}
|
|
if result := tfrConf.Db().Create(newMarkers); result.Error != nil {
|
|
log.Errorf("migrate: error in batch marker create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of markers transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var passcodes []entity.Passcode
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&passcodes, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newPasscodes []*entity.Passcode
|
|
for _, passcode := range passcodes {
|
|
newPasscodes = append(newPasscodes, &passcode)
|
|
}
|
|
if result := tfrConf.Db().Create(newPasscodes); result.Error != nil {
|
|
log.Errorf("migrate: error in batch passcode create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of passcodes transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var passwords []entity.Password
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&passwords, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newPasswords []*entity.Password
|
|
for _, password := range passwords {
|
|
newPasswords = append(newPasswords, &password)
|
|
}
|
|
if result := tfrConf.Db().Create(newPasswords); result.Error != nil {
|
|
log.Errorf("migrate: error in batch password create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of passwords transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var photousers []entity.PhotoUser
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&photousers, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newPhotoUsers []*entity.PhotoUser
|
|
for _, photouser := range photousers {
|
|
newPhotoUsers = append(newPhotoUsers, &photouser)
|
|
}
|
|
if result := tfrConf.Db().Create(newPhotoUsers); result.Error != nil {
|
|
log.Errorf("migrate: error in batch photouser create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of photousers transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var reactions []entity.Reaction
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&reactions, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newReactions []*entity.Reaction
|
|
for _, reaction := range reactions {
|
|
newReactions = append(newReactions, &reaction)
|
|
}
|
|
if result := tfrConf.Db().Create(newReactions); result.Error != nil {
|
|
log.Errorf("migrate: error in batch reaction create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of reactions transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
var subjects entity.Subjects
|
|
result = conf.Db().Unscoped().
|
|
FindInBatches(&subjects, batchSize, func(tx *gorm.DB, batch int) error {
|
|
var newSubjects []*entity.Subject
|
|
for _, subject := range subjects {
|
|
newSubjects = append(newSubjects, &subject)
|
|
}
|
|
if result := tfrConf.Db().Create(newSubjects); result.Error != nil {
|
|
log.Errorf("migrate: error in batch subject create %s", result.Error)
|
|
return result.Error
|
|
}
|
|
return nil
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
} else {
|
|
log.Infof("migrate: number of subjects transfered %v", result.RowsAffected)
|
|
}
|
|
|
|
elapsed := time.Since(start)
|
|
|
|
log.Infof("completed in %s", elapsed)
|
|
|
|
return nil
|
|
}
|