diff --git a/cmd/gochan/main.go b/cmd/gochan/main.go index 74ad5c2b..deccde9f 100644 --- a/cmd/gochan/main.go +++ b/cmd/gochan/main.go @@ -141,12 +141,8 @@ func initDB(fatalEv *zerolog.Event, commandLine ...bool) { Msg("Connected to database") err := gcsql.CheckAndInitializeDatabase(systemCritical.DBtype, true) - var db *gcsql.GCDB if errors.Is(err, gcsql.ErrDeprecatedDB) { - db, err = gcsql.GetDatabase() - if err == nil { - err = dbupdate.UpdateDatabase(db) - } + err = dbupdate.UpdateDatabase() } if err != nil { cleanup() diff --git a/pkg/gcsql/dbupdate/dbupdate.go b/pkg/gcsql/dbupdate/dbupdate.go index fae522ce..b7db1336 100644 --- a/pkg/gcsql/dbupdate/dbupdate.go +++ b/pkg/gcsql/dbupdate/dbupdate.go @@ -19,49 +19,21 @@ var ( ErrInvalidVersion = errors.New("database contains database_version table but zero or more than one versions were found") ) -func UpdateDatabase(db *gcsql.GCDB) error { - dbUpdater := &DatabaseUpdater{DB: db} +func UpdateDatabase() error { gcutil.LogInfo().Msg("Preparing to update the database") - err := dbUpdater.updateDB() - if err != nil { - return err - } - gcutil.LogInfo(). - Int("DBVersion", gcsql.DatabaseVersion). - Msg("Database updated successfully") - return nil -} - -type DatabaseUpdater struct { - DB *gcsql.GCDB -} - -func (dbu *DatabaseUpdater) isUpdated() (bool, error) { - var currentDatabaseVersion int - err := dbu.DB.QueryRow(nil, "SELECT version FROM DBPREFIXdatabase_version WHERE component = 'gochan'", nil, - []any{¤tDatabaseVersion}) - if err != nil { - return false, err - } - if currentDatabaseVersion == gcsql.DatabaseVersion { - return true, nil - } - if currentDatabaseVersion > gcsql.DatabaseVersion { - return false, fmt.Errorf("database layout is ahead of current version (%d), target version: %d", - currentDatabaseVersion, gcsql.DatabaseVersion) - } - return false, nil -} - -func (dbu *DatabaseUpdater) updateDB() (err error) { errEv := gcutil.LogError(nil) - gcsql.SetDB(dbu.DB) - sqlConfig := config.GetSQLConfig() var gochanTablesExist bool + + db, err := gcsql.GetDatabase() + if err != nil { + errEv.Err(err).Caller().Send() + return err + } + if sqlConfig.DBprefix == "" { - gochanTablesExist, err = migrationutil.TableExists(context.Background(), dbu.DB, nil, "database_version", &sqlConfig) + gochanTablesExist, err = migrationutil.TableExists(context.Background(), db, nil, "database_version", &sqlConfig) } else { gochanTablesExist, err = gcsql.DoesGochanPrefixTableExist() } @@ -72,7 +44,7 @@ func (dbu *DatabaseUpdater) updateDB() (err error) { return migrationutil.ErrNotInstalled } - updated, err := dbu.isUpdated() + updated, err := isUpdated() defer func() { if a := recover(); a != nil { errEv.Caller(4).Interface("panic", a).Send() @@ -96,25 +68,25 @@ func (dbu *DatabaseUpdater) updateDB() (err error) { defer cancel() var filterTableExists bool - filterTableExists, err = migrationutil.TableExists(ctx, dbu.DB, nil, "DBPREFIXfilters", &sqlConfig) + filterTableExists, err = migrationutil.TableExists(ctx, db, nil, "DBPREFIXfilters", &sqlConfig) if err != nil { return err } if !filterTableExists { // DBPREFIXfilters not found, create it and migrate data from DBPREFIXfile_ban, DBPREFIXfilename_ban, and DBPREFIXusername_ban, - if err = addFilterTables(ctx, dbu.DB, nil, &sqlConfig, errEv); err != nil { + if err = addFilterTables(ctx, nil, &sqlConfig, errEv); err != nil { return err } } switch sqlConfig.DBtype { case "mysql": - err = updateMysqlDB(ctx, dbu, &sqlConfig, errEv) + err = updateMysqlDB(ctx, &sqlConfig, errEv) case "postgres": - err = updatePostgresDB(ctx, dbu, &sqlConfig, errEv) + err = updatePostgresDB(ctx, &sqlConfig, errEv) case "sqlite3": - err = updateSqliteDB(ctx, dbu, &sqlConfig, errEv) + err = updateSqliteDB(ctx, &sqlConfig, errEv) } if err != nil { return err @@ -124,23 +96,43 @@ func (dbu *DatabaseUpdater) updateDB() (err error) { return err } - if err = dbu.updateFilters(ctx, &sqlConfig, errEv); err != nil { + if err = updateFilters(ctx, &sqlConfig, errEv); err != nil { return err } query := `UPDATE DBPREFIXdatabase_version SET version = ? WHERE component = 'gochan'` - _, err = dbu.DB.ExecContextSQL(ctx, nil, query, gcsql.DatabaseVersion) + _, err = gcsql.ExecContextSQL(ctx, nil, query, gcsql.DatabaseVersion) if err != nil { return err } + gcutil.LogInfo(). + Int("DBVersion", gcsql.DatabaseVersion). + Msg("Database updated successfully") return nil } -func (dbu *DatabaseUpdater) updateFilters(ctx context.Context, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) { +func isUpdated() (bool, error) { + var currentDatabaseVersion int + err := gcsql.QueryRow(nil, "SELECT version FROM DBPREFIXdatabase_version WHERE component = 'gochan'", nil, + []any{¤tDatabaseVersion}) + if err != nil { + return false, err + } + if currentDatabaseVersion == gcsql.DatabaseVersion { + return true, nil + } + if currentDatabaseVersion > gcsql.DatabaseVersion { + return false, fmt.Errorf("database layout is ahead of current version (%d), target version: %d", + currentDatabaseVersion, gcsql.DatabaseVersion) + } + return false, nil +} + +func updateFilters(ctx context.Context, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) { var fileBansExist, filenameBansExist, usernameBansExist, wordfiltersExist bool - fileBansExist, err = migrationutil.TableExists(ctx, dbu.DB, nil, "DBPREFIXfile_ban", sqlConfig) + fileBansExist, err = migrationutil.TableExists(ctx, nil, nil, "DBPREFIXfile_ban", sqlConfig) defer func() { if err != nil { errEv.Err(err).Caller(1).Send() @@ -151,41 +143,41 @@ func (dbu *DatabaseUpdater) updateFilters(ctx context.Context, sqlConfig *config return err } - filenameBansExist, err = migrationutil.TableExists(ctx, dbu.DB, nil, "DBPREFIXfilename_ban", sqlConfig) + filenameBansExist, err = migrationutil.TableExists(ctx, nil, nil, "DBPREFIXfilename_ban", sqlConfig) if err != nil { return err } - usernameBansExist, err = migrationutil.TableExists(ctx, dbu.DB, nil, "DBPREFIXusername_ban", sqlConfig) + usernameBansExist, err = migrationutil.TableExists(ctx, nil, nil, "DBPREFIXusername_ban", sqlConfig) if err != nil { return err } - wordfiltersExist, err = migrationutil.TableExists(ctx, dbu.DB, nil, "DBPREFIXwordfilters", sqlConfig) + wordfiltersExist, err = migrationutil.TableExists(ctx, nil, nil, "DBPREFIXwordfilters", sqlConfig) if err != nil { return err } if fileBansExist { - if err = dbu.updateFileBans(ctx, sqlConfig, errEv); err != nil { + if err = updateFileBans(ctx, sqlConfig, errEv); err != nil { return err } } if filenameBansExist { - if err = dbu.updateFilenameBans(ctx, sqlConfig, errEv); err != nil { + if err = updateFilenameBans(ctx, sqlConfig, errEv); err != nil { return err } } if usernameBansExist { - if err = dbu.updateUsernameBans(ctx, sqlConfig, errEv); err != nil { + if err = updateUsernameBans(ctx, sqlConfig, errEv); err != nil { return err } } if wordfiltersExist { - if err = dbu.updateWordfilters(ctx, sqlConfig, errEv); err != nil { + if err = updateWordfilters(ctx, sqlConfig, errEv); err != nil { return err } } @@ -193,8 +185,8 @@ func (dbu *DatabaseUpdater) updateFilters(ctx context.Context, sqlConfig *config return nil } -func (dbu *DatabaseUpdater) updateFileBans(ctx context.Context, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) { - tx, err := dbu.DB.BeginTx(ctx, nil) +func updateFileBans(ctx context.Context, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) { + tx, err := gcsql.BeginContextTx(ctx) defer func() { if a := recover(); a != nil { err = fmt.Errorf("recovered: %v", a) @@ -212,7 +204,7 @@ func (dbu *DatabaseUpdater) updateFileBans(ctx context.Context, sqlConfig *confi query := "SELECT board_id, staff_id, staff_note, issued_at, checksum, fingerprinter, ban_ip, ban_ip_message FROM DBPREFIXfile_ban" var fingerprinterCol string - fingerprinterCol, err = migrationutil.ColumnType(ctx, dbu.DB, nil, "fingerprinter", "DBPREFIXfile_ban", sqlConfig) + fingerprinterCol, err = migrationutil.ColumnType(ctx, nil, nil, "fingerprinter", "DBPREFIXfile_ban", sqlConfig) if err != nil { return err } @@ -222,7 +214,7 @@ func (dbu *DatabaseUpdater) updateFileBans(ctx context.Context, sqlConfig *confi } var banIPCol string - banIPCol, err = migrationutil.ColumnType(ctx, dbu.DB, nil, "ban_ip", "DBPREFIXfile_ban", sqlConfig) + banIPCol, err = migrationutil.ColumnType(ctx, nil, nil, "ban_ip", "DBPREFIXfile_ban", sqlConfig) if err != nil { return err } @@ -230,7 +222,7 @@ func (dbu *DatabaseUpdater) updateFileBans(ctx context.Context, sqlConfig *confi query = strings.ReplaceAll(query, "ban_ip", "FALSE AS ban_ip") } - rows, err := dbu.DB.QueryContextSQL(ctx, nil, query) + rows, err := gcsql.QueryContextSQL(ctx, nil, query) if err != nil { return err } @@ -281,8 +273,8 @@ func (dbu *DatabaseUpdater) updateFileBans(ctx context.Context, sqlConfig *confi return tx.Commit() } -func (dbu *DatabaseUpdater) updateFilenameBans(ctx context.Context, _ *config.SQLConfig, errEv *zerolog.Event) (err error) { - tx, err := dbu.DB.BeginTx(ctx, nil) +func updateFilenameBans(ctx context.Context, _ *config.SQLConfig, errEv *zerolog.Event) (err error) { + tx, err := gcsql.BeginContextTx(ctx) defer func() { if a := recover(); a != nil { err = fmt.Errorf("recovered: %v", a) @@ -299,7 +291,7 @@ func (dbu *DatabaseUpdater) updateFilenameBans(ctx context.Context, _ *config.SQ } query := "SELECT board_id, staff_id, staff_note, issued_at, filename, is_regex FROM DBPREFIXfilename_ban" - rows, err := dbu.DB.QueryContextSQL(ctx, nil, query) + rows, err := gcsql.QueryContextSQL(ctx, nil, query) if err != nil { return err } @@ -339,8 +331,8 @@ func (dbu *DatabaseUpdater) updateFilenameBans(ctx context.Context, _ *config.SQ return tx.Commit() } -func (dbu *DatabaseUpdater) updateUsernameBans(ctx context.Context, _ *config.SQLConfig, errEv *zerolog.Event) (err error) { - tx, err := dbu.DB.BeginTx(ctx, nil) +func updateUsernameBans(ctx context.Context, _ *config.SQLConfig, errEv *zerolog.Event) (err error) { + tx, err := gcsql.BeginContextTx(ctx) defer func() { if a := recover(); a != nil { err = fmt.Errorf("recovered: %v", a) @@ -357,7 +349,7 @@ func (dbu *DatabaseUpdater) updateUsernameBans(ctx context.Context, _ *config.SQ } query := "SELECT board_id, staff_id, staff_note, issued_at, username FROM DBPREFIXusername_ban" - rows, err := dbu.DB.QueryContextSQL(ctx, nil, query) + rows, err := gcsql.QueryContextSQL(ctx, nil, query) if err != nil { return err } @@ -397,8 +389,8 @@ func (dbu *DatabaseUpdater) updateUsernameBans(ctx context.Context, _ *config.SQ return tx.Commit() } -func (dbu *DatabaseUpdater) updateWordfilters(ctx context.Context, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) { - tx, err := dbu.DB.BeginTx(ctx, nil) +func updateWordfilters(ctx context.Context, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) { + tx, err := gcsql.BeginContextTx(ctx) defer func() { if a := recover(); a != nil { err = fmt.Errorf("recovered: %v", a) @@ -416,7 +408,7 @@ func (dbu *DatabaseUpdater) updateWordfilters(ctx context.Context, sqlConfig *co query := "SELECT board_dirs, staff_id, staff_note, issued_at, search, is_regex, change_to FROM DBPREFIXwordfilters" var boardIDCol string - boardIDCol, err = migrationutil.ColumnType(ctx, dbu.DB, nil, "board_id", "DBPREFIXwordfilters", sqlConfig) + boardIDCol, err = migrationutil.ColumnType(ctx, nil, nil, "board_id", "DBPREFIXwordfilters", sqlConfig) if err != nil { return err } @@ -424,7 +416,7 @@ func (dbu *DatabaseUpdater) updateWordfilters(ctx context.Context, sqlConfig *co query = strings.ReplaceAll(query, "board_dirs", "board_id") } - rows, err := dbu.DB.QueryContextSQL(ctx, nil, query) + rows, err := gcsql.QueryContextSQL(ctx, nil, query) if err != nil { return err } diff --git a/pkg/gcsql/dbupdate/filters.go b/pkg/gcsql/dbupdate/filters.go index 60afc864..e87b86f5 100644 --- a/pkg/gcsql/dbupdate/filters.go +++ b/pkg/gcsql/dbupdate/filters.go @@ -62,7 +62,7 @@ type FileBan struct { } // addFilterTables is used for the db version 4 upgrade to create the filter tables from the respective SQL init file -func addFilterTables(ctx context.Context, db *gcsql.GCDB, tx *sql.Tx, sqlConfig *config.SQLConfig, errEv *zerolog.Event) error { +func addFilterTables(ctx context.Context, tx *sql.Tx, sqlConfig *config.SQLConfig, errEv *zerolog.Event) error { filePath, err := migrationutil.GetInitFilePath("initdb_" + sqlConfig.DBtype + ".sql") defer func() { if err != nil { @@ -84,7 +84,7 @@ func addFilterTables(ctx context.Context, db *gcsql.GCDB, tx *sql.Tx, sqlConfig if !strings.HasPrefix(stmtStr, "CREATE TABLE DBPREFIXfilter") { continue } - if _, err = db.Exec(&gcsql.RequestOptions{ + if _, err = gcsql.Exec(&gcsql.RequestOptions{ Context: ctx, Tx: tx, }, stmtStr); err != nil { diff --git a/pkg/gcsql/dbupdate/updatemysql.go b/pkg/gcsql/dbupdate/updatemysql.go index 2535e3ad..5a917fe4 100644 --- a/pkg/gcsql/dbupdate/updatemysql.go +++ b/pkg/gcsql/dbupdate/updatemysql.go @@ -5,14 +5,13 @@ import ( "database/sql" "github.com/gochan-org/gochan/pkg/config" + "github.com/gochan-org/gochan/pkg/gcsql" "github.com/gochan-org/gochan/pkg/gcsql/migrationutil" "github.com/gochan-org/gochan/pkg/gcutil" "github.com/rs/zerolog" ) -func updateMysqlDB(ctx context.Context, dbu *DatabaseUpdater, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) { - var query string - var cyclicalType string +func updateMysqlDB(ctx context.Context, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) { defer func() { if a := recover(); a != nil { errEv.Caller(4).Interface("panic", a).Send() @@ -23,18 +22,22 @@ func updateMysqlDB(ctx context.Context, dbu *DatabaseUpdater, sqlConfig *config. } }() dbName := sqlConfig.DBname - db := dbu.DB // fix default collation - query = `ALTER DATABASE ` + dbName + ` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci` + db, err := gcsql.GetDatabase() + if err != nil { + return err + } + query := `ALTER DATABASE ` + dbName + ` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci` + // use the base sql.DB, since our database automatically prepares all queries, and ALTER DATABASE + // will cause Error 1295 (HY000): This command is not supported in the prepared statement protocol yet if _, err = db.GetBaseDB().ExecContext(ctx, query); err != nil { - errEv.Err(err).Caller().Send() return err } var rows *sql.Rows query = `SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_TYPE = 'BASE TABLE'` - rows, err = db.QueryContextSQL(ctx, nil, query, dbName) + rows, err = gcsql.QueryContextSQL(ctx, nil, query, dbName) if err != nil { errEv.Err(err).Caller().Send() return err @@ -50,8 +53,7 @@ func updateMysqlDB(ctx context.Context, dbu *DatabaseUpdater, sqlConfig *config. return err } query = `ALTER TABLE ` + tableName + ` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { - errEv.Err(err).Caller().Send() + if _, err = gcsql.ExecContextSQL(ctx, nil, query); err != nil { return err } } @@ -59,23 +61,22 @@ func updateMysqlDB(ctx context.Context, dbu *DatabaseUpdater, sqlConfig *config. return err } - cyclicalType, err = migrationutil.ColumnType(ctx, db, nil, "ip", "DBPREFIXip_ban", sqlConfig) + // split DBPREFIXposts.ip into range_start and range_end as varbinary + dataType, err := migrationutil.ColumnType(ctx, nil, nil, "ip", "DBPREFIXip_ban", sqlConfig) if err != nil { return err } - if cyclicalType != "" { + if dataType != "" { // add range_start and range_end columns query = `ALTER TABLE DBPREFIXip_ban ADD COLUMN IF NOT EXISTS range_start VARBINARY(16) NOT NULL, ADD COLUMN IF NOT EXISTS range_end VARBINARY(16) NOT NULL` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { - errEv.Err(err).Caller().Send() + if _, err = gcsql.ExecContextSQL(ctx, nil, query); err != nil { return err } // convert ban IP string to IP range - if rows, err = db.QueryContextSQL(ctx, nil, "SELECT id, ip FROM DBPREFIXip_ban"); err != nil { - errEv.Err(err).Caller().Send() + if rows, err = gcsql.QueryContextSQL(ctx, nil, "SELECT id, ip FROM DBPREFIXip_ban"); err != nil { return err } var rangeStart, rangeEnd string @@ -83,7 +84,6 @@ func updateMysqlDB(ctx context.Context, dbu *DatabaseUpdater, sqlConfig *config. var id int var ipOrCIDR string if err = rows.Scan(&id, &ipOrCIDR); err != nil { - errEv.Err(err).Caller().Send() return err } if rangeStart, rangeEnd, err = gcutil.ParseIPRange(ipOrCIDR); err != nil { @@ -91,168 +91,132 @@ func updateMysqlDB(ctx context.Context, dbu *DatabaseUpdater, sqlConfig *config. } query = `UPDATE DBPREFIXip_ban SET range_start = INET6_ATON(?), range_end = INET6_ATON(?) WHERE id = ?` - if _, err = db.ExecContextSQL(ctx, nil, query, rangeStart, rangeEnd, id); err != nil { - errEv.Err(err).Caller().Send() + if _, err = gcsql.ExecContextSQL(ctx, nil, query, rangeStart, rangeEnd, id); err != nil { return err } query = `ALTER TABLE DBPREFIXip_ban DROP COLUMN IF EXISTS ip` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { - errEv.Err(err).Caller().Send() + if _, err = gcsql.ExecContextSQL(ctx, nil, query); err != nil { return err } } if err = rows.Close(); err != nil { - errEv.Err(err).Caller().Send() return err } } // Convert DBPREFIXposts.ip to from varchar to varbinary - cyclicalType, err = migrationutil.ColumnType(ctx, db, nil, "ip", "DBPREFIXposts", sqlConfig) + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "ip", "DBPREFIXposts", sqlConfig) if err != nil { errEv.Err(err).Caller().Send() return err } - if migrationutil.IsStringType(cyclicalType) { - // rename `ip` to a temporary column to then be removed - query = "ALTER TABLE DBPREFIXposts CHANGE ip ip_str varchar(45)" - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { - errEv.Err(err).Caller().Send() - return err + if migrationutil.IsStringType(dataType) { + alterPostsIP := []string{ + "ALTER TABLE DBPREFIXposts CHANGE ip ip_str VARCHAR(45)", + "ALTER TABLE DBPREFIXposts ADD COLUMN ip VARBINARY(16)", + "UPDATE DBPREFIXposts SET ip = INET6_ATON(ip_str)", + "ALTER TABLE DBPREFIXposts CHANGE ip ip VARBINARY(16) NOT NULL", + "ALTER TABLE DBPREFIXposts DROP COLUMN ip_str", } - - query = `ALTER TABLE DBPREFIXposts - ADD COLUMN IF NOT EXISTS ip VARBINARY(16) NOT NULL` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { - errEv.Err(err).Caller().Send() - return err - } - - // convert post IP VARCHAR(45) to VARBINARY(16) - query = `UPDATE DBPREFIXposts SET ip = INET6_ATON(ip_str)` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { - errEv.Err(err).Caller().Send() - return err - } - - query = `ALTER TABLE DBPREFIXposts DROP COLUMN IF EXISTS ip_str` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { - errEv.Err(err).Caller().Send() - return err + for _, query = range alterPostsIP { + if _, err = gcsql.ExecContextSQL(ctx, nil, query); err != nil { + return err + } } } // Convert DBPREFIXreports.ip to from varchar to varbinary - cyclicalType, err = migrationutil.ColumnType(ctx, db, nil, "ip", "DBPREFIXreports", sqlConfig) + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "ip", "DBPREFIXreports", sqlConfig) if err != nil { - errEv.Err(err).Caller().Send() return err } - if migrationutil.IsStringType(cyclicalType) { - // rename `ip` to a temporary column to then be removed - query = "ALTER TABLE DBPREFIXreports CHANGE ip ip_str varchar(45)" - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { - errEv.Err(err).Caller().Send() - return err + if migrationutil.IsStringType(dataType) { + alterReportsIP := []string{ + "ALTER TABLE DBPREFIXreports CHANGE ip ip_str VARCHAR(45)", + "ALTER TABLE DBPREFIXreports ADD COLUMN ip VARBINARY(16)", + "UPDATE DBPREFIXreports SET ip = INET6_ATON(ip_str)", + "ALTER TABLE DBPREFIXreports CHANGE ip ip VARBINARY(45) NOT NULL", + "ALTER TABLE DBPREFIXreports DROP COLUMN ip_str", } - query = `ALTER TABLE DBPREFIXreports - ADD COLUMN IF NOT EXISTS ip VARBINARY(16) NOT NULL` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { - errEv.Err(err).Caller().Send() - return err - } - - // convert report IP VARCHAR(45) to VARBINARY(16) - query = `UPDATE DBPREFIXreports SET ip = INET6_ATON(ip_str)` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { - errEv.Err(err).Caller().Send() - return err - } - - query = `ALTER TABLE DBPREFIXreports DROP COLUMN IF EXISTS ip_str` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { - errEv.Err(err).Caller().Send() - return err + for _, query := range alterReportsIP { + if _, err = gcsql.ExecContextSQL(ctx, nil, query); err != nil { + errEv.Str("query", query) + return err + } } } // add flag column to DBPREFIXposts - cyclicalType, err = migrationutil.ColumnType(ctx, db, nil, "flag", "DBPREFIXposts", sqlConfig) + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "flag", "DBPREFIXposts", sqlConfig) if err != nil { errEv.Err(err).Caller().Send() return err } - if cyclicalType == "" { - query = `ALTER TABLE DBPREFIXposts ADD COLUMN flag VARCHAR(45) NOT NULL DEFAULT ''` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { + if dataType == "" { + if _, err = gcsql.ExecContextSQL(ctx, nil, "ALTER TABLE DBPREFIXposts ADD COLUMN flag VARCHAR(45) NOT NULL DEFAULT ''"); err != nil { errEv.Err(err).Caller().Send() return err } } // add country column to DBPREFIXposts - cyclicalType, err = migrationutil.ColumnType(ctx, db, nil, "country", "DBPREFIXposts", sqlConfig) + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "country", "DBPREFIXposts", sqlConfig) if err != nil { errEv.Err(err).Caller().Send() return err } - if cyclicalType == "" { - query = `ALTER TABLE DBPREFIXposts ADD COLUMN country VARCHAR(80) NOT NULL DEFAULT ''` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { + if dataType == "" { + if _, err = gcsql.ExecContextSQL(ctx, nil, "ALTER TABLE DBPREFIXposts ADD COLUMN country VARCHAR(80) NOT NULL DEFAULT ''"); err != nil { errEv.Err(err).Caller().Send() return err } } // add is_secure_tripcode column to DBPREFIXposts - cyclicalType, err = migrationutil.ColumnType(ctx, db, nil, "is_secure_tripcode", "DBPREFIXposts", sqlConfig) + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "is_secure_tripcode", "DBPREFIXposts", sqlConfig) if err != nil { errEv.Err(err).Caller().Send() return err } - if cyclicalType == "" { - query = `ALTER TABLE DBPREFIXposts ADD COLUMN is_secure_tripcode BOOL NOT NULL DEFAULT FALSE` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { + if dataType == "" { + if _, err = gcsql.ExecContextSQL(ctx, nil, "ALTER TABLE DBPREFIXposts ADD COLUMN is_secure_tripcode BOOL NOT NULL DEFAULT FALSE"); err != nil { errEv.Err(err).Caller().Send() return err } } // add spoilered column to DBPREFIXthreads - cyclicalType, err = migrationutil.ColumnType(ctx, db, nil, "is_spoilered", "DBPREFIXthreads", sqlConfig) + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "is_spoilered", "DBPREFIXthreads", sqlConfig) if err != nil { errEv.Err(err).Caller().Send() return err } - if cyclicalType == "" { - query = `ALTER TABLE DBPREFIXthreads ADD COLUMN is_spoilered BOOL NOT NULL DEFAULT FALSE` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { + if dataType == "" { + if _, err = gcsql.ExecContextSQL(ctx, nil, "ALTER TABLE DBPREFIXthreads ADD COLUMN is_spoilered BOOL NOT NULL DEFAULT FALSE"); err != nil { errEv.Err(err).Caller().Send() return err } } // rename DBPREFIXposts.cyclical to cyclic - cyclicalType, err = migrationutil.ColumnType(ctx, db, nil, "cyclical", "DBPREFIXthreads", sqlConfig) + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "cyclical", "DBPREFIXthreads", sqlConfig) if err != nil { errEv.Err(err).Caller().Send() return err } - cyclicType, err := migrationutil.ColumnType(ctx, db, nil, "cyclic", "DBPREFIXthreads", sqlConfig) + cyclicType, err := migrationutil.ColumnType(ctx, nil, nil, "cyclic", "DBPREFIXthreads", sqlConfig) if err != nil { errEv.Err(err).Caller().Send() return err } - if cyclicalType == "" && cyclicType == "" { - query = `ALTER TABLE DBPREFIXthreads ADD COLUMN cyclic BOOL NOT NULL DEFAULT FALSE` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { + if dataType == "" && cyclicType == "" { + if _, err = gcsql.ExecContextSQL(ctx, nil, "ALTER TABLE DBPREFIXthreads ADD COLUMN cyclic BOOL NOT NULL DEFAULT FALSE"); err != nil { errEv.Err(err).Caller().Send() return err } - } else if cyclicalType != "" { - query = `ALTER TABLE DBPREFIXthreads CHANGE cyclical cyclic BOOL NOT NULL DEFAULT FALSE` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { + } else if dataType != "" { + if _, err = gcsql.ExecContextSQL(ctx, nil, "ALTER TABLE DBPREFIXthreads CHANGE cyclical cyclic BOOL NOT NULL DEFAULT FALSE"); err != nil { errEv.Err(err).Caller().Send() return err } diff --git a/pkg/gcsql/dbupdate/updatepostgres.go b/pkg/gcsql/dbupdate/updatepostgres.go index 23eda519..a6a2c946 100644 --- a/pkg/gcsql/dbupdate/updatepostgres.go +++ b/pkg/gcsql/dbupdate/updatepostgres.go @@ -4,15 +4,12 @@ import ( "context" "github.com/gochan-org/gochan/pkg/config" + "github.com/gochan-org/gochan/pkg/gcsql" "github.com/gochan-org/gochan/pkg/gcsql/migrationutil" "github.com/rs/zerolog" ) -func updatePostgresDB(ctx context.Context, dbu *DatabaseUpdater, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) { - db := dbu.DB - var query, dataType string - - dataType, err = migrationutil.ColumnType(ctx, db, nil, "ip", "DBPREFIXposts", sqlConfig) +func updatePostgresDB(ctx context.Context, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) { defer func() { if a := recover(); a != nil { errEv.Caller(4).Interface("panic", a).Send() @@ -22,111 +19,129 @@ func updatePostgresDB(ctx context.Context, dbu *DatabaseUpdater, sqlConfig *conf errEv.Discard() } }() + + dataType, err := migrationutil.ColumnType(ctx, nil, nil, "ip", "DBPREFIXposts", sqlConfig) if err != nil { return err } + var query string if migrationutil.IsStringType(dataType) { + alterPostsIP := []string{ + "ALTER TABLE DBPREFIXposts RENAME COLUMN ip TO ip_str", + "ALTER TABLE DBPREFIXposts ADD COLUMN IF NOT EXISTS ip INET", + "UPDATE DBPREFIXposts SET ip = ip_str", + "ALTER TABLE DBPREFIXposts DROP COLUMN ip_str", + "ALTER TABLE DBPREFIXposts ALTER COLUMN ip SET NOT NULL", + } + for _, query = range alterPostsIP { + if _, err = gcsql.ExecContextSQL(ctx, nil, query); err != nil { + return err + } + } + // change ip column to temporary ip_str query = `ALTER TABLE DBPREFIXposts RENAME COLUMN ip TO ip_str,` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { - return err - } - - // add ip column with INET type, default '127.0.0.1' because it throws an error otherwise - // because it is non-nil - query = `ALTER TABLE DBPREFIXposts - ADD COLUMN IF NOT EXISTS ip INET NOT NULL DEFAULT '127.0.0.1'` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { - return err - } - - query = `UPDATE TABLE DBPREFIXposts SET ip = ip_str` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { - return err - } - - query = `ALTER TABLE DBPREFIXposts DROP COLUMN ip_str` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { + if _, err = gcsql.ExecContextSQL(ctx, nil, query); err != nil { return err } } - dataType, err = migrationutil.ColumnType(ctx, db, nil, "ip", "DBPREFIXip_ban", sqlConfig) + // Convert DBPREFIXreports.ip to from varchar to inet + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "ip", "DBPREFIXreports", sqlConfig) + if err != nil { + errEv.Err(err).Caller().Send() + return err + } + if migrationutil.IsStringType(dataType) { + alterReportsIP := []string{ + "ALTER TABLE DBPREFIXreports CHANGE ip ip_str varchar(45)", + "ALTER TABLE DBPREFIXreports ADD COLUMN ip INET", + "UPDATE DBPREFIXreports SET ip = ip_str", + "ALTER TABLE DBPREFIXreports ALTER COLUMN ip SET NOT NULL", + "ALTER TABLE DBPREFIXreports DROP COLUMN ip_str", + } + for _, query := range alterReportsIP { + if _, err = gcsql.ExecContextSQL(ctx, nil, query); err != nil { + errEv.Err(err).Caller().Send() + return err + } + } + } + + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "ip", "DBPREFIXip_ban", sqlConfig) if err != nil { return err } if dataType != "" { - query = `ALTER TABLE DBPREFIXip_ban - ADD COLUMN IF NOT EXISTS range_start INET NOT NULL, - ADD COLUMN IF NOT EXISTS range_end INET NOT NULL` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { - return err + alterIPBanIP := []string{ + `ALTER TABLE DBPREFIXip_ban + ADD COLUMN IF NOT EXISTS range_start INET, + ADD COLUMN IF NOT EXISTS range_end INET`, + "UPDATE DBPREFIXip_ban SET range_start = ip::INET, range_end = ip::INET", + `ALTER TABLE DBPREFIXip_ban + ALTER COLUMN range_start SET NOT NULL, + ALTER COLUMN range_end SET NOT NULL`, + "ALTER TABLE DBPREFIXip_ban DROP COLUMN ip", } - - query = `UPDATE DBPREFIXip_ban SET range_start = ip::INET, SET range_end = ip::INET` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { - return err + for _, query = range alterIPBanIP { + if _, err = gcsql.ExecContextSQL(ctx, nil, query); err != nil { + return err + } } } // add flag column to DBPREFIXposts - dataType, err = migrationutil.ColumnType(ctx, db, nil, "flag", "DBPREFIXposts", sqlConfig) + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "flag", "DBPREFIXposts", sqlConfig) if err != nil { return err } if dataType == "" { - query = `ALTER TABLE DBPREFIXposts ADD COLUMN flag VARCHAR(45) NOT NULL DEFAULT ''` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { + if _, err = gcsql.ExecContextSQL(ctx, nil, "ALTER TABLE DBPREFIXposts ADD COLUMN flag VARCHAR(45) NOT NULL DEFAULT ''"); err != nil { return err } } // add country column to DBPREFIXposts - dataType, err = migrationutil.ColumnType(ctx, db, nil, "country", "DBPREFIXposts", sqlConfig) + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "country", "DBPREFIXposts", sqlConfig) if err != nil { return err } if dataType == "" { - query = `ALTER TABLE DBPREFIXposts ADD COLUMN country VARCHAR(80) NOT NULL DEFAULT ''` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { + if _, err = gcsql.ExecContextSQL(ctx, nil, "ALTER TABLE DBPREFIXposts ADD COLUMN country VARCHAR(80) NOT NULL DEFAULT ''"); err != nil { return err } } // add is_secure_tripcode column to DBPREFIXposts - dataType, err = migrationutil.ColumnType(ctx, db, nil, "is_secure_tripcode", "DBPREFIXposts", sqlConfig) + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "is_secure_tripcode", "DBPREFIXposts", sqlConfig) if err != nil { return err } if dataType == "" { - query = `ALTER TABLE DBPREFIXposts ADD COLUMN is_secure_tripcode BOOL NOT NULL DEFAULT FALSE` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { + if _, err = gcsql.ExecContextSQL(ctx, nil, "ALTER TABLE DBPREFIXposts ADD COLUMN is_secure_tripcode BOOL NOT NULL DEFAULT FALSE"); err != nil { return err } } // add spoilered column to DBPREFIXthreads - dataType, err = migrationutil.ColumnType(ctx, db, nil, "is_spoilered", "DBPREFIXthreads", sqlConfig) + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "is_spoilered", "DBPREFIXthreads", sqlConfig) if err != nil { return err } if dataType == "" { - query = `ALTER TABLE DBPREFIXthreads ADD COLUMN is_spoilered BOOL NOT NULL DEFAULT FALSE` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { + if _, err = gcsql.ExecContextSQL(ctx, nil, "ALTER TABLE DBPREFIXthreads ADD COLUMN is_spoilered BOOL NOT NULL DEFAULT FALSE"); err != nil { return err } } - // rename DBPREFIXposts.cyclical to cyclic - dataType, err = migrationutil.ColumnType(ctx, db, nil, "cyclic", "DBPREFIXposts", sqlConfig) + // rename DBPREFIXthreads.cyclical to cyclic if cyclical exists + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "cyclic", "DBPREFIXthreads", sqlConfig) if err != nil { errEv.Err(err).Caller().Send() return err } if dataType == "" { - query = `ALTER TABLE DBPREFIXposts CHANGE cyclical cyclic BOOL NOT NULL DEFAULT FALSE` - if _, err = db.ExecContextSQL(ctx, nil, query); err != nil { - errEv.Err(err).Caller().Send() + if _, err = gcsql.ExecContextSQL(ctx, nil, "ALTER TABLE DBPREFIXthreads RENAME cyclical TO cyclic"); err != nil { return err } } diff --git a/pkg/gcsql/dbupdate/updatesqlite3.go b/pkg/gcsql/dbupdate/updatesqlite3.go index cc11761c..74ae13ba 100644 --- a/pkg/gcsql/dbupdate/updatesqlite3.go +++ b/pkg/gcsql/dbupdate/updatesqlite3.go @@ -9,10 +9,7 @@ import ( "github.com/rs/zerolog" ) -func updateSqliteDB(ctx context.Context, dbu *DatabaseUpdater, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) { - db := dbu.DB - - _, err = db.ExecContextSQL(ctx, nil, `PRAGMA foreign_keys = ON`) +func updateSqliteDB(ctx context.Context, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) { defer func() { if a := recover(); a != nil { errEv.Caller(4).Interface("panic", a).Send() @@ -22,6 +19,8 @@ func updateSqliteDB(ctx context.Context, dbu *DatabaseUpdater, sqlConfig *config errEv.Discard() } }() + + _, err = gcsql.ExecContextSQL(ctx, nil, `PRAGMA foreign_keys = ON`) if err != nil { return err } @@ -29,132 +28,132 @@ func updateSqliteDB(ctx context.Context, dbu *DatabaseUpdater, sqlConfig *config opts := &gcsql.RequestOptions{Context: ctx} // simple alterations first - dataType, err := migrationutil.ColumnType(ctx, db, nil, "cyclical", "DBPREFIXthreads", sqlConfig) + dataType, err := migrationutil.ColumnType(ctx, nil, nil, "cyclical", "DBPREFIXthreads", sqlConfig) if err != nil { errEv.Err(err).Caller().Send() return err } if dataType != "" { - if _, err = db.Exec(opts, "ALTER TABLE DBPREFIXthreads RENAME COLUMN cyclical TO cyclic"); err != nil { + if _, err = gcsql.Exec(opts, "ALTER TABLE DBPREFIXthreads RENAME COLUMN cyclical TO cyclic"); err != nil { return err } } - if dataType, err = migrationutil.ColumnType(ctx, db, nil, "is_secure_tripcode", "DBPREFIXposts", sqlConfig); err != nil { + if dataType, err = migrationutil.ColumnType(ctx, nil, nil, "is_secure_tripcode", "DBPREFIXposts", sqlConfig); err != nil { errEv.Err(err).Caller().Send() return err } if dataType == "" { - if _, err = db.Exec(opts, "ALTER TABLE DBPREFIXposts ADD COLUMN is_secure_tripcode BOOL NOT NULL DEFAULT FALSE"); err != nil { + if _, err = gcsql.Exec(opts, "ALTER TABLE DBPREFIXposts ADD COLUMN is_secure_tripcode BOOL NOT NULL DEFAULT FALSE"); err != nil { return err } } - if dataType, err = migrationutil.ColumnType(ctx, db, nil, "flag", "DBPREFIXposts", sqlConfig); err != nil { + if dataType, err = migrationutil.ColumnType(ctx, nil, nil, "flag", "DBPREFIXposts", sqlConfig); err != nil { return err } if dataType == "" { - if _, err = db.Exec(opts, "ALTER TABLE DBPREFIXposts ADD COLUMN flag VARCHAR(45) NOT NULL DEFAULT ''"); err != nil { + if _, err = gcsql.Exec(opts, "ALTER TABLE DBPREFIXposts ADD COLUMN flag VARCHAR(45) NOT NULL DEFAULT ''"); err != nil { return err } } - if dataType, err = migrationutil.ColumnType(ctx, db, nil, "country", "DBPREFIXposts", sqlConfig); err != nil { + if dataType, err = migrationutil.ColumnType(ctx, nil, nil, "country", "DBPREFIXposts", sqlConfig); err != nil { return err } if dataType == "" { - if _, err = db.Exec(opts, "ALTER TABLE DBPREFIXposts ADD COLUMN country VARCHAR(80) NOT NULL DEFAULT ''"); err != nil { + if _, err = gcsql.Exec(opts, "ALTER TABLE DBPREFIXposts ADD COLUMN country VARCHAR(80) NOT NULL DEFAULT ''"); err != nil { return err } } - if dataType, err = migrationutil.ColumnType(ctx, db, nil, "expires", "DBPREFIXsessions", sqlConfig); err != nil { + if dataType, err = migrationutil.ColumnType(ctx, nil, nil, "expires", "DBPREFIXsessions", sqlConfig); err != nil { return err } if dataType == "" { - if _, err = db.Exec(opts, "ALTER TABLE DBPREFIXsessions ADD COLUMN expires TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP"); err != nil { + if _, err = gcsql.Exec(opts, "ALTER TABLE DBPREFIXsessions ADD COLUMN expires TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP"); err != nil { return err } } - if dataType, err = migrationutil.ColumnType(ctx, db, nil, "data", "DBPREFIXsessions", sqlConfig); err != nil { + if dataType, err = migrationutil.ColumnType(ctx, nil, nil, "data", "DBPREFIXsessions", sqlConfig); err != nil { return err } if dataType == "" { - if _, err = db.Exec(opts, "ALTER TABLE DBPREFIXsessions ADD COLUMN data VARCHAR(45) NOT NULL DEFAULT ''"); err != nil { + if _, err = gcsql.Exec(opts, "ALTER TABLE DBPREFIXsessions ADD COLUMN data VARCHAR(45) NOT NULL DEFAULT ''"); err != nil { return err } } - dataType, err = migrationutil.ColumnType(ctx, db, nil, "range_start", "DBPREFIXip_ban", sqlConfig) + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "range_start", "DBPREFIXip_ban", sqlConfig) if err != nil { return err } if dataType == "" { - if _, err = db.Exec(opts, "ALTER TABLE DBPREFIXip_ban ADD COLUMN range_start VARCHAR(45) NOT NULL DEFAULT ''"); err != nil { + if _, err = gcsql.Exec(opts, "ALTER TABLE DBPREFIXip_ban ADD COLUMN range_start VARCHAR(45) NOT NULL DEFAULT ''"); err != nil { return err } - if _, err = db.Exec(opts, "UPDATE DBPREFIXip_ban SET range_start = ip"); err != nil { + if _, err = gcsql.Exec(opts, "UPDATE DBPREFIXip_ban SET range_start = ip"); err != nil { return err } } - dataType, err = migrationutil.ColumnType(ctx, db, nil, "range_end", "DBPREFIXip_ban", sqlConfig) + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "range_end", "DBPREFIXip_ban", sqlConfig) if err != nil { return err } if dataType == "" { - if _, err = db.Exec(opts, "ALTER TABLE DBPREFIXip_ban ADD COLUMN range_end VARCHAR(45) NOT NULL DEFAULT ''"); err != nil { + if _, err = gcsql.Exec(opts, "ALTER TABLE DBPREFIXip_ban ADD COLUMN range_end VARCHAR(45) NOT NULL DEFAULT ''"); err != nil { return err } - if _, err = db.Exec(opts, "UPDATE DBPREFIXip_ban SET range_end = ip"); err != nil { + if _, err = gcsql.Exec(opts, "UPDATE DBPREFIXip_ban SET range_end = ip"); err != nil { return err } } - dataType, err = migrationutil.ColumnType(ctx, db, nil, "is_spoilered", "DBPREFIXthreads", sqlConfig) + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "is_spoilered", "DBPREFIXthreads", sqlConfig) if err != nil { return err } if dataType == "" { - if _, err = db.Exec(opts, "ALTER TABLE DBPREFIXthreads ADD COLUMN is_spoilered BOOL NOT NULL DEFAULT FALSE"); err != nil { + if _, err = gcsql.Exec(opts, "ALTER TABLE DBPREFIXthreads ADD COLUMN is_spoilered BOOL NOT NULL DEFAULT FALSE"); err != nil { return err } } - filtersExist, err := migrationutil.TableExists(ctx, db, nil, "DBPREFIXfilters", sqlConfig) + filtersExist, err := migrationutil.TableExists(ctx, nil, nil, "DBPREFIXfilters", sqlConfig) if err != nil { return err } if !filtersExist { // update pre-filter tables to make sure they can be migrated to the new filter tables - dataType, err = migrationutil.ColumnType(ctx, db, nil, "fingerprinter", "DBPREFIXfile_ban", sqlConfig) + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "fingerprinter", "DBPREFIXfile_ban", sqlConfig) if err != nil { return err } if dataType == "" { - if _, err = db.Exec(opts, "ALTER TABLE DBPREFIXfile_ban ADD COLUMN fingerprinter VARCHAR(64) DEFAULT ''"); err != nil { + if _, err = gcsql.Exec(opts, "ALTER TABLE DBPREFIXfile_ban ADD COLUMN fingerprinter VARCHAR(64) DEFAULT ''"); err != nil { return err } } - dataType, err = migrationutil.ColumnType(ctx, db, nil, "ban_ip", "DBPREFIXfile_ban", sqlConfig) + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "ban_ip", "DBPREFIXfile_ban", sqlConfig) if err != nil { return err } if dataType == "" { - if _, err = db.Exec(opts, "ALTER TABLE DBPREFIXfile_ban ADD COLUMN ban_ip BOOL NOT NULL DEFAULT FALSE"); err != nil { + if _, err = gcsql.Exec(opts, "ALTER TABLE DBPREFIXfile_ban ADD COLUMN ban_ip BOOL NOT NULL DEFAULT FALSE"); err != nil { return err } } - dataType, err = migrationutil.ColumnType(ctx, db, nil, "ban_ip_message", "DBPREFIXfile_ban", sqlConfig) + dataType, err = migrationutil.ColumnType(ctx, nil, nil, "ban_ip_message", "DBPREFIXfile_ban", sqlConfig) if err != nil { return err } if dataType == "" { - if _, err = db.Exec(opts, "ALTER TABLE DBPREFIXfile_ban ADD COLUMN ban_ip_message TEXT"); err != nil { + if _, err = gcsql.Exec(opts, "ALTER TABLE DBPREFIXfile_ban ADD COLUMN ban_ip_message TEXT"); err != nil { return err } } diff --git a/pkg/gcsql/migrationutil/migrationutil.go b/pkg/gcsql/migrationutil/migrationutil.go index 52dd0975..f5e73f76 100644 --- a/pkg/gcsql/migrationutil/migrationutil.go +++ b/pkg/gcsql/migrationutil/migrationutil.go @@ -20,8 +20,8 @@ var ( ErrNotInstalled = errors.New("database is empty or corrupted (missing tables), run gochan to install and initialize it") ) -// ColumnType returns a string representation of the column's data type. It does not return an error -// if the column does not exist, instead returning an empty string. +// ColumnType returns a string representation of the column's data type. It does not return an error if the column +// does not exist, instead returning an empty string. If db is nil, it will use the currently loaded "default" database func ColumnType(ctx context.Context, db *gcsql.GCDB, tx *sql.Tx, columnName string, tableName string, sqlConfig *config.SQLConfig) (string, error) { var query string var dataType string @@ -45,7 +45,11 @@ func ColumnType(ctx context.Context, db *gcsql.GCDB, tx *sql.Tx, columnName stri default: return "", gcsql.ErrUnsupportedDB } - err = db.QueryRowContextSQL(ctx, tx, query, params, []any{&dataType}) + if db == nil { + err = gcsql.QueryRowContextSQL(ctx, tx, query, params, []any{&dataType}) + } else { + err = db.QueryRowContextSQL(ctx, tx, query, params, []any{&dataType}) + } if errors.Is(err, sql.ErrNoRows) { return "", nil } @@ -53,6 +57,7 @@ func ColumnType(ctx context.Context, db *gcsql.GCDB, tx *sql.Tx, columnName stri } // TableExists returns true if the given table exists in the given database, and an error if one occured +// If db is nil, it will use the currently loaded "default" database func TableExists(ctx context.Context, db *gcsql.GCDB, tx *sql.Tx, tableName string, sqlConfig *config.SQLConfig) (bool, error) { tableName = strings.ReplaceAll(tableName, "DBPREFIX", sqlConfig.DBprefix) var query string @@ -67,7 +72,12 @@ func TableExists(ctx context.Context, db *gcsql.GCDB, tx *sql.Tx, tableName stri return false, gcsql.ErrUnsupportedDB } var count int - err := db.QueryRowContextSQL(ctx, tx, query, []any{tableName}, []any{&count}) + var err error + if db == nil { + err = gcsql.QueryRowContextSQL(ctx, tx, query, []any{tableName}, []any{&count}) + } else { + err = db.QueryRowContextSQL(ctx, tx, query, []any{tableName}, []any{&count}) + } return count == 1, err } diff --git a/tools/get_previous_version.sh b/tools/get_previous_version.sh index b94665b0..4c013f9f 100755 --- a/tools/get_previous_version.sh +++ b/tools/get_previous_version.sh @@ -50,7 +50,7 @@ if [ ! -f gochan.json ]; then -e 's/"DBname": "gochan"/"DBname": "gochan_prev"/' \ -e 's/"DBprefix": .*/"DBprefix": "",/' \ -e 's/"SiteName": "Gochan"/"SiteName": "Gochan Migration Test"/' \ - -e 's/"SiteSlogan": ""/"SiteSlogan": "Gochan instance used for testing gochan-migrate -updatedb"/' \ + -e 's/"SiteSlogan": ""/"SiteSlogan": "Gochan instance used for testing gochan migration"/' \ -e 's/"DebugMode": false/"DebugMode": true/' \ -e 's/"Verbosity": 0/"Verbosity": 1/' \ -e 's/"GeoIPType": .*/"GeoIPType": "",/' \