diff --git a/cmd/gochan-migration/internal/common/handler.go b/cmd/gochan-migration/internal/common/handler.go index 3edb3815..fa92a541 100644 --- a/cmd/gochan-migration/internal/common/handler.go +++ b/cmd/gochan-migration/internal/common/handler.go @@ -56,6 +56,11 @@ type DBMigrator interface { // will exit IsMigrated() (bool, error) + // IsMigratingInPlace returns true if the old database name is the same as the new database name, + // meaning that the tables will be altered to match the new schema, instead of creating tables in the + // new database and copying data over + IsMigratingInPlace() bool + // MigrateDB alters the database schema to match the new schema, then migrates the imageboard // data (posts, boards, etc) to the new database. It is assumed that MigrateDB will handle // logging any errors that occur during the migration diff --git a/cmd/gochan-migration/internal/gcupdate/gcupdate.go b/cmd/gochan-migration/internal/gcupdate/gcupdate.go index ff2e0718..7e194781 100644 --- a/cmd/gochan-migration/internal/gcupdate/gcupdate.go +++ b/cmd/gochan-migration/internal/gcupdate/gcupdate.go @@ -2,7 +2,6 @@ package gcupdate import ( "context" - "errors" "fmt" "strings" "time" @@ -22,6 +21,11 @@ type GCDatabaseUpdater struct { TargetDBVer int } +// IsMigratingInPlace implements common.DBMigrator. +func (dbu *GCDatabaseUpdater) IsMigratingInPlace() bool { + return true +} + func (dbu *GCDatabaseUpdater) Init(options *common.MigrationOptions) error { dbu.options = options sqlCfg := config.GetSQLConfig() @@ -174,7 +178,7 @@ func (dbu *GCDatabaseUpdater) migrateFileBans(ctx context.Context, sqlConfig *co tx, err := dbu.db.BeginTx(ctx, nil) defer func() { if a := recover(); a != nil { - err = errors.New(fmt.Sprintf("recovered: %v", a)) + err = fmt.Errorf("recovered: %v", a) errEv.Caller(4).Err(err).Send() errEv.Discard() } else if err != nil { @@ -262,7 +266,7 @@ func (dbu *GCDatabaseUpdater) migrateFilenameBans(ctx context.Context, _ *config tx, err := dbu.db.BeginTx(ctx, nil) defer func() { if a := recover(); a != nil { - err = errors.New(fmt.Sprintf("recovered: %v", a)) + err = fmt.Errorf("recovered: %v", a) errEv.Caller(4).Err(err).Send() errEv.Discard() } else if err != nil { @@ -320,7 +324,7 @@ func (dbu *GCDatabaseUpdater) migrateUsernameBans(ctx context.Context, _ *config tx, err := dbu.db.BeginTx(ctx, nil) defer func() { if a := recover(); a != nil { - err = errors.New(fmt.Sprintf("recovered: %v", a)) + err = fmt.Errorf("recovered: %v", a) errEv.Caller(4).Err(err).Send() errEv.Discard() } else if err != nil { @@ -378,7 +382,7 @@ func (dbu *GCDatabaseUpdater) migrateWordfilters(ctx context.Context, sqlConfig tx, err := dbu.db.BeginTx(ctx, nil) defer func() { if a := recover(); a != nil { - err = errors.New(fmt.Sprintf("recovered: %v", a)) + err = fmt.Errorf("recovered: %v", a) errEv.Caller(4).Err(err).Send() errEv.Discard() } else if err != nil { diff --git a/cmd/gochan-migration/internal/pre2021/boards.go b/cmd/gochan-migration/internal/pre2021/boards.go index c5aa1c20..6497c34c 100644 --- a/cmd/gochan-migration/internal/pre2021/boards.go +++ b/cmd/gochan-migration/internal/pre2021/boards.go @@ -1,12 +1,19 @@ package pre2021 import ( + "fmt" "log" + "github.com/gochan-org/gochan/cmd/gochan-migration/internal/common" "github.com/gochan-org/gochan/pkg/gcsql" ) func (m *Pre2021Migrator) MigrateBoards() error { + defer func() { + if r := recover(); r != nil { + common.LogFatal().Interface("recover", r).Msg("Recovered from panic in MigrateBoards") + } + }() if m.oldBoards == nil { m.oldBoards = map[int]string{} } @@ -14,10 +21,14 @@ func (m *Pre2021Migrator) MigrateBoards() error { m.newBoards = map[int]string{} } // get all boards from new db + fmt.Println("0") err := gcsql.ResetBoardSectionArrays() + fmt.Println("1") if err != nil { + fmt.Println("2") return nil } + fmt.Println("3") // get boards from old db rows, err := m.db.QuerySQL(boardsQuery) diff --git a/cmd/gochan-migration/internal/pre2021/pre2021.go b/cmd/gochan-migration/internal/pre2021/pre2021.go index 0d3ffcc1..ae5ebdd0 100644 --- a/cmd/gochan-migration/internal/pre2021/pre2021.go +++ b/cmd/gochan-migration/internal/pre2021/pre2021.go @@ -12,12 +12,6 @@ import ( type Pre2021Config struct { config.SQLConfig - // DBtype string - // DBhost string - // DBname string - // DBusername string - // DBpassword string - // DBprefix string DocumentRoot string } @@ -31,6 +25,11 @@ type Pre2021Migrator struct { newBoards map[int]string // map[board]dir } +// IsMigratingInPlace implements common.DBMigrator. +func (m *Pre2021Migrator) IsMigratingInPlace() bool { + return m.config.DBname == config.GetSQLConfig().DBname +} + func (m *Pre2021Migrator) readConfig() error { ba, err := os.ReadFile(m.options.OldChanConfig) if err != nil { @@ -68,7 +67,7 @@ func (m *Pre2021Migrator) IsMigrated() (bool, error) { return false, gcsql.ErrUnsupportedDB } if err = m.db.QueryRowSQL(query, - []interface{}{m.config.DBprefix + "migrated", m.config.DBname}, + []interface{}{m.config.DBprefix + "database_version", m.config.DBname}, []interface{}{&migrated}); err != nil { return migrated, err } @@ -82,12 +81,14 @@ func (m *Pre2021Migrator) MigrateDB() (bool, error) { } if migrated { // db is already migrated, stop + common.LogWarning().Msg("Database is already migrated (database_version table exists)") return true, nil } if err := m.MigrateBoards(); err != nil { return false, err } + common.LogInfo().Msg("Migrated boards") // if err = m.MigratePosts(); err != nil { // return false, err // } diff --git a/cmd/gochan-migration/main.go b/cmd/gochan-migration/main.go index bf84f45a..c52e87fd 100644 --- a/cmd/gochan-migration/main.go +++ b/cmd/gochan-migration/main.go @@ -56,9 +56,14 @@ func main() { fatalEv.Discard() }() - if !updateDB && (options.ChanType == "" || options.OldChanConfig == "") { - flag.PrintDefaults() - fatalEv.Msg("Missing required oldchan value") + if !updateDB { + if options.ChanType == "" { + flag.PrintDefaults() + fatalEv.Msg("Missing required oldchan value") + } else if options.OldChanConfig == "" { + flag.PrintDefaults() + fatalEv.Msg("Missing required oldconfig value") + } } else if updateDB { options.ChanType = "gcupdate" } @@ -82,8 +87,15 @@ func main() { default: fatalEv.Msg("Unsupported chan type, Currently only pre2021 database migration is supported") } + migratingInPlace := migrator.IsMigratingInPlace() + common.LogInfo(). + Str("oldChanType", options.ChanType). + Str("oldChanConfig", options.OldChanConfig). + Bool("migratingInPlace", migratingInPlace). + Msg("Starting database migration") + config.InitConfig(versionStr) - if !updateDB { + if !migratingInPlace { sqlCfg := config.GetSQLConfig() err = gcsql.ConnectToDB(&sqlCfg) if err != nil { diff --git a/pkg/gcsql/database.go b/pkg/gcsql/database.go index 163c5554..f9cdb51a 100644 --- a/pkg/gcsql/database.go +++ b/pkg/gcsql/database.go @@ -416,8 +416,7 @@ func SetupMockDB(driver string) (sqlmock.Sqlmock, error) { return mock, err } -// Open opens and returns a new gochan database connection with the provided host, driver, DB name, -// username, password, and table prefix +// Open opens and returns a new gochan database connection with the provided SQL options func Open(cfg *config.SQLConfig) (db *GCDB, err error) { db, err = setupDBConn(cfg) if err != nil {