1
0
Fork 0
mirror of https://github.com/Eggbertx/gochan.git synced 2025-08-18 07:36:24 -07:00

Implement pre-2021 staff migration to new DB

This commit is contained in:
Eggbertx 2025-01-05 15:18:11 -08:00
parent 1dc22b6571
commit 7cb3100140
7 changed files with 122 additions and 14 deletions

View file

@ -29,7 +29,7 @@ func TestMigrateBansToNewDB(t *testing.T) {
if !assert.NoError(t, err) {
t.FailNow()
}
assert.Equal(t, 4, len(bans), "Expected to have 4 valid bans")
assert.Equal(t, 6, len(bans), "Expected to have 4 valid bans")
var numInvalidBans int
assert.NoError(t, gcsql.QueryRowSQL("SELECT COUNT(*) FROM DBPREFIXip_ban WHERE message = ?", []any{"Full ban on 8.8.0.0/16"}, []any{&numInvalidBans}))

View file

@ -171,6 +171,11 @@ func (m *Pre2021Migrator) migratePostsToNewDB() error {
}
migratedThreads++
}
if err = rows.Close(); err != nil {
errEv.Err(err).Caller().Msg("Failed to close posts rows")
return err
}
if len(threadIDsWithInvalidBoards) > 0 {
errEv.Caller().
Ints("threadIDs", threadIDsWithInvalidBoards).

View file

@ -22,8 +22,9 @@ type Pre2021Migrator struct {
options *common.MigrationOptions
config Pre2021Config
boards []migrationBoard
sections []migrationSection
migrationUser *gcsql.Staff
boards []migrationBoard
sections []migrationSection
}
// IsMigratingInPlace implements common.DBMigrator.

View file

@ -14,6 +14,8 @@ bumped, stickied, locked FROM DBPREFIXposts WHERE deleted_timestamp IS NULL`
threadsQuery = postsQuery + " AND parentid = 0"
staffQuery = `SELECT username, rank, boards, added_on, last_active FROM DBPREFIXstaff`
bansQuery = `SELECT id, allow_read, COALESCE(ip, '') as ip, name, name_is_regex, filename, file_checksum, boards, staff,
timestamp, expires, permaban, reason, type, staff_note, appeal_at, can_appeal FROM DBPREFIXbanlist`
)

View file

@ -1,31 +1,125 @@
package pre2021
import (
"errors"
"strings"
"time"
"github.com/gochan-org/gochan/cmd/gochan-migration/internal/common"
"github.com/gochan-org/gochan/pkg/gcsql"
"github.com/gochan-org/gochan/pkg/gcutil"
"github.com/rs/zerolog"
)
type migrationStaff struct {
gcsql.Staff
oldID int
boardIDs []int
}
func (*Pre2021Migrator) migrateStaffInPlace() error {
err := common.NewMigrationError("pre2021", "migrateSectionsInPlace not yet implemented")
common.LogError().Err(err).Caller().Msg("Failed to migrate sections")
return err
}
func (*Pre2021Migrator) migrateStaffToNewDB() error {
func (m *Pre2021Migrator) getMigrationUser(errEv *zerolog.Event) (*gcsql.Staff, error) {
if m.migrationUser != nil {
return m.migrationUser, nil
}
user := &gcsql.Staff{
Username: "pre2021-migration" + gcutil.RandomString(15),
AddedOn: time.Now(),
}
_, err := gcsql.ExecSQL("INSERT INTO DBPREFIXstaff(username,password_checksum,global_rank,is_active) values(?,'',0,0)", user.Username)
if err != nil {
errEv.Err(err).Caller().Str("username", user.Username).Msg("Failed to create migration user")
return nil, err
}
if err = gcsql.QueryRowSQL("SELECT id FROM DBPREFIXstaff WHERE username = ?", []any{user.Username}, []any{&user.ID}); err != nil {
errEv.Err(err).Caller().Str("username", user.Username).Msg("Failed to get migration user ID")
return nil, err
}
m.migrationUser = user
return user, nil
}
func (m *Pre2021Migrator) migrateStaffToNewDB() error {
errEv := common.LogError()
defer errEv.Discard()
err := common.NewMigrationError("pre2021", "migrateStaffToNewDB not yet implemented")
errEv.Err(err).Caller().Msg("Failed to migrate sections")
_, err := m.getMigrationUser(errEv)
if err != nil {
return err
}
return err
rows, err := m.db.QuerySQL(staffQuery)
if err != nil {
errEv.Err(err).Caller().Msg("Failed to get ban rows")
return err
}
defer rows.Close()
for rows.Next() {
var username string
var rank int
var boards string
var addedOn, lastActive time.Time
if err = rows.Scan(&username, &rank, &boards, &addedOn, &lastActive); err != nil {
errEv.Err(err).Caller().Msg("Failed to scan staff row")
return err
}
_, err = gcsql.GetStaffByUsername(username, false)
if err == nil {
// found staff
gcutil.LogInfo().Str("username", username).Int("rank", rank).Msg("Found matching staff account")
}
if errors.Is(err, gcsql.ErrUnrecognizedUsername) {
// staff doesn't exist, create it (with invalid checksum to be updated by the admin)
if _, err2 := gcsql.ExecSQL(
"INSERT INTO DBPREFIXstaff(username,password_checksum,global_rank,added_on,last_login,is_active) values(?,'',?,?,?,1)",
username, rank, addedOn, lastActive,
); err2 != nil {
errEv.Err(err2).Caller().
Str("username", username).Int("rank", rank).
Msg("Failed to migrate staff account")
return err
}
gcutil.LogInfo().Str("username", username).Int("rank", rank).Msg("Successfully migrated staff account")
} else if err != nil {
errEv.Err(err).Caller().Str("username", username).Msg("Failed to get staff account info")
return err
}
staffID, err := gcsql.GetStaffID(username)
if err != nil {
errEv.Err(err).Caller().Str("username", username).Msg("Failed to get staff account ID")
return err
}
if boards != "" && boards != "*" {
boardsArr := strings.Split(boards, ",")
for _, board := range boardsArr {
board = strings.TrimSpace(board)
boardID, err := gcsql.GetBoardIDFromDir(board)
if err != nil {
errEv.Err(err).Caller().
Str("username", username).
Str("board", board).
Msg("Failed to get board ID")
return err
}
if _, err = gcsql.ExecSQL("INSERT INTO DBPREFIXboard_staff(board_id,staff_id) VALUES(?,?)", boardID, staffID); err != nil {
errEv.Err(err).Caller().
Str("username", username).
Str("board", board).
Msg("Failed to apply staff board info")
return err
}
}
}
}
if err = rows.Close(); err != nil {
errEv.Err(err).Caller().Msg("Failed to close staff rows")
return err
}
return nil
}
func (m *Pre2021Migrator) MigrateStaff() error {

View file

@ -3,6 +3,7 @@ package pre2021
import (
"testing"
"github.com/gochan-org/gochan/pkg/gcsql"
"github.com/stretchr/testify/assert"
)
@ -20,4 +21,9 @@ func TestMigrateStaffToNewDB(t *testing.T) {
if !assert.NoError(t, migrator.MigrateStaff()) {
t.FailNow()
}
migratedAdmin, err := gcsql.GetStaffByUsername("migratedadmin", true)
if !assert.NoError(t, err) {
t.FailNow()
}
assert.Equal(t, 3, migratedAdmin.Rank)
}

Binary file not shown.