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

Refactor database update functions to remove direct database references from dbupdate (holdover from gochan-migration)

This commit is contained in:
Eggbertx 2025-08-08 13:38:34 -07:00
parent a764360415
commit 8b31a224fb
8 changed files with 236 additions and 260 deletions

View file

@ -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()

View file

@ -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{&currentDatabaseVersion})
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{&currentDatabaseVersion})
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
}

View file

@ -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 {

View file

@ -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
}

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -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
}

View file

@ -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": "",/' \