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

Move gcupdate "migration" to be handled by the main gochan executable

This commit is contained in:
Eggbertx 2025-08-01 11:54:28 -07:00
parent ee702a2d16
commit 26c44f1d3d
14 changed files with 168 additions and 173 deletions

View file

@ -23,11 +23,11 @@ type pathsForm struct {
WebRoot string `form:"webroot,required" method:"POST"`
}
func (pf *pathsForm) validateDirectory(dir string, createIfNotExist bool) error {
func (*pathsForm) validateDirectory(dir string, createIfNotExist bool) error {
fi, err := os.Stat(dir)
if errors.Is(err, fs.ErrNotExist) {
if createIfNotExist {
if err := os.MkdirAll(dir, 0755); err != nil {
if err := os.MkdirAll(dir, config.DirFileMode); err != nil {
return fmt.Errorf("failed to create directory %s: %w", dir, err)
}
return nil

View file

@ -11,6 +11,7 @@ import (
"github.com/gochan-org/gochan/cmd/gochan-migration/internal/common"
"github.com/gochan-org/gochan/pkg/config"
"github.com/gochan-org/gochan/pkg/gcsql"
"github.com/gochan-org/gochan/pkg/gcsql/migrationutil"
)
type Pre2021Config struct {
@ -65,7 +66,7 @@ func (m *Pre2021Migrator) IsMigrated() (bool, error) {
} else {
sqlConfig = m.config.SQLConfig
}
return common.TableExists(ctx, m.db, nil, "DBPREFIXdatabase_version", &sqlConfig)
return migrationutil.TableExists(ctx, m.db, nil, "DBPREFIXdatabase_version", &sqlConfig)
}
func (m *Pre2021Migrator) renameTablesForInPlace() error {

View file

@ -7,9 +7,9 @@ import (
"os"
"github.com/gochan-org/gochan/cmd/gochan-migration/internal/common"
"github.com/gochan-org/gochan/cmd/gochan-migration/internal/gcupdate"
"github.com/gochan-org/gochan/cmd/gochan-migration/internal/pre2021"
"github.com/gochan-org/gochan/pkg/config"
"github.com/gochan-org/gochan/pkg/gcsql/migrationutil"
"github.com/gochan-org/gochan/pkg/gcsql"
)
@ -36,9 +36,7 @@ func cleanup() {
func main() {
var options common.MigrationOptions
var updateDB bool
flag.BoolVar(&updateDB, "updatedb", false, "If this is set, gochan-migrate will check, and if needed, update gochan's database schema")
flag.StringVar(&options.ChanType, "oldchan", "", "The imageboard we are migrating from (currently only pre2021 is supported, but more are coming")
flag.StringVar(&options.OldChanConfig, "oldconfig", "", "The path to the old chan's configuration file")
flag.Parse()
@ -56,22 +54,17 @@ func main() {
fatalEv.Discard()
}()
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"
if options.ChanType == "" {
flag.PrintDefaults()
fatalEv.Msg("Missing required oldchan value")
} else if options.OldChanConfig == "" {
flag.PrintDefaults()
fatalEv.Msg("Missing required oldconfig value")
}
fatalEv.Str("chanType", options.ChanType)
switch options.ChanType {
case "gcupdate":
migrator = &gcupdate.GCDatabaseUpdater{}
case "pre2021":
migrator = &pre2021.Pre2021Migrator{}
case "kusabax":
@ -92,7 +85,7 @@ func main() {
fatalEv.Err(err).Caller().Msg("Unable to reload configuration")
}
sqlCfg := config.GetSQLConfig()
if migratingInPlace && sqlCfg.DBtype == "sqlite3" && !updateDB {
if migratingInPlace && sqlCfg.DBtype == "sqlite3" {
common.LogWarning().
Str("dbType", sqlCfg.DBtype).
Bool("migrateInPlace", migratingInPlace).
@ -114,7 +107,7 @@ func main() {
var migrated bool
migrated, err = migrator.MigrateDB()
if errors.Is(err, common.ErrNotInstalled) {
if errors.Is(err, migrationutil.ErrNotInstalled) {
common.LogWarning().Msg(err.Error())
return
} else if err != nil {

View file

@ -1,7 +1,9 @@
package main
import (
"errors"
"fmt"
"io/fs"
"os"
"os/signal"
"syscall"
@ -16,6 +18,7 @@ import (
"github.com/gochan-org/gochan/pkg/gcplugin"
"github.com/gochan-org/gochan/pkg/gcsql"
"github.com/gochan-org/gochan/pkg/gcsql/dbupdate"
_ "github.com/gochan-org/gochan/pkg/gcsql/initsql"
"github.com/gochan-org/gochan/pkg/gctemplates"
"github.com/gochan-org/gochan/pkg/posting"
@ -42,10 +45,12 @@ func main() {
cleanup()
}()
err := config.InitConfig()
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
fatalEv.Err(err).Caller()
gcutil.LogArray("searchPaths", config.StandardConfigSearchPaths, fatalEv)
fatalEv.Msg(config.ConfigNotFoundInPathsMessage)
} else if err != nil {
fatalEv.Err(err).Caller().Send()
}
uid, gid := config.GetUser()
@ -134,12 +139,25 @@ func initDB(fatalEv *zerolog.Event, commandLine ...bool) {
Str("DBhost", systemCritical.DBhost).
Msg("Connected to database")
if err := gcsql.CheckAndInitializeDatabase(systemCritical.DBtype, true); err != nil {
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)
if err == nil {
gcutil.LogInfo().
Int("DBVersion", gcsql.DatabaseVersion).
Msg("Database updated successfully")
}
}
}
if err != nil {
cleanup()
if len(commandLine) > 0 && commandLine[0] {
fmt.Fprintln(os.Stderr, "Failed to initialize the database:", err)
}
gcutil.LogFatal().Err(err).Msg("Failed to initialize the database")
fatalEv.Err(err).Msg("Failed to initialize the database")
}
events.TriggerEvent("db-initialized")
if err := gcsql.ResetViews(); err != nil {

View file

@ -22,7 +22,7 @@ const (
InitialSetupComplete
// DirFileMode is the default file mode for directories created by gochan
DirFileMode fs.FileMode = 0775
DirFileMode fs.FileMode = 0750
// NormalFileMode is the default file mode for files created by gochan
NormalFileMode fs.FileMode = 0664

View file

@ -1,4 +1,4 @@
package gcupdate
package dbupdate
import (
"context"
@ -8,34 +8,34 @@ import (
"strings"
"time"
"github.com/gochan-org/gochan/cmd/gochan-migration/internal/common"
"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"
)
type GCDatabaseUpdater struct {
options *common.MigrationOptions
db *gcsql.GCDB
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}
gcutil.LogInfo().Msg("Preparing to update the database")
err := dbUpdater.updateDB()
if err != nil {
return err
}
return nil
}
// IsMigratingInPlace implements common.DBMigrator.
func (*GCDatabaseUpdater) IsMigratingInPlace() bool {
return true
type DatabaseUpdater struct {
DB *gcsql.GCDB
}
func (dbu *GCDatabaseUpdater) Init(options *common.MigrationOptions) error {
dbu.options = options
sqlCfg := config.GetSQLConfig()
var err error
dbu.db, err = gcsql.Open(&sqlCfg)
return err
}
func (dbu *GCDatabaseUpdater) IsMigrated() (bool, error) {
func (dbu *DatabaseUpdater) isUpdated() (bool, error) {
var currentDatabaseVersion int
err := dbu.db.QueryRow(nil, "SELECT version FROM DBPREFIXdatabase_version WHERE component = 'gochan'", nil,
err := dbu.DB.QueryRow(nil, "SELECT version FROM DBPREFIXdatabase_version WHERE component = 'gochan'", nil,
[]any{&currentDatabaseVersion})
if err != nil {
return false, err
@ -50,26 +50,26 @@ func (dbu *GCDatabaseUpdater) IsMigrated() (bool, error) {
return false, nil
}
func (dbu *GCDatabaseUpdater) MigrateDB() (migrated bool, err error) {
errEv := common.LogError()
func (dbu *DatabaseUpdater) updateDB() (err error) {
errEv := gcutil.LogError(nil)
gcsql.SetDB(dbu.db)
gcsql.SetDB(dbu.DB)
sqlConfig := config.GetSQLConfig()
var gochanTablesExist bool
if sqlConfig.DBprefix == "" {
gochanTablesExist, err = common.TableExists(context.Background(), dbu.db, nil, "database_version", &sqlConfig)
gochanTablesExist, err = migrationutil.TableExists(context.Background(), dbu.DB, nil, "database_version", &sqlConfig)
} else {
gochanTablesExist, err = gcsql.DoesGochanPrefixTableExist()
}
if err != nil {
return false, err
return err
}
if !gochanTablesExist {
return false, common.ErrNotInstalled
return migrationutil.ErrNotInstalled
}
migrated, err = dbu.IsMigrated()
updated, err := dbu.isUpdated()
defer func() {
if a := recover(); a != nil {
errEv.Caller(4).Interface("panic", a).Send()
@ -80,28 +80,28 @@ func (dbu *GCDatabaseUpdater) MigrateDB() (migrated bool, err error) {
}
}()
if errors.Is(err, sql.ErrNoRows) {
return migrated, gcsql.ErrInvalidVersion
return gcsql.ErrInvalidVersion
}
if err != nil {
return migrated, err
return err
}
if migrated {
return migrated, nil
if updated {
return nil
}
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
var filterTableExists bool
filterTableExists, err = common.TableExists(ctx, dbu.db, nil, "DBPREFIXfilters", &sqlConfig)
filterTableExists, err = migrationutil.TableExists(ctx, dbu.DB, nil, "DBPREFIXfilters", &sqlConfig)
if err != nil {
return false, err
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 {
return false, err
if err = addFilterTables(ctx, dbu.DB, nil, &sqlConfig, errEv); err != nil {
return err
}
}
@ -114,30 +114,30 @@ func (dbu *GCDatabaseUpdater) MigrateDB() (migrated bool, err error) {
err = updateSqliteDB(ctx, dbu, &sqlConfig, errEv)
}
if err != nil {
return false, err
return err
}
if err = ctx.Err(); err != nil {
return false, err
return err
}
if err = dbu.migrateFilters(ctx, &sqlConfig, errEv); err != nil {
return false, err
if err = dbu.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 = dbu.DB.ExecContextSQL(ctx, nil, query, gcsql.DatabaseVersion)
if err != nil {
return false, err
return err
}
return false, nil
return nil
}
func (dbu *GCDatabaseUpdater) migrateFilters(ctx context.Context, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) {
func (dbu *DatabaseUpdater) updateFilters(ctx context.Context, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) {
var fileBansExist, filenameBansExist, usernameBansExist, wordfiltersExist bool
fileBansExist, err = common.TableExists(ctx, dbu.db, nil, "DBPREFIXfile_ban", sqlConfig)
fileBansExist, err = migrationutil.TableExists(ctx, dbu.DB, nil, "DBPREFIXfile_ban", sqlConfig)
defer func() {
if err != nil {
errEv.Err(err).Caller(1).Send()
@ -148,41 +148,41 @@ func (dbu *GCDatabaseUpdater) migrateFilters(ctx context.Context, sqlConfig *con
return err
}
filenameBansExist, err = common.TableExists(ctx, dbu.db, nil, "DBPREFIXfilename_ban", sqlConfig)
filenameBansExist, err = migrationutil.TableExists(ctx, dbu.DB, nil, "DBPREFIXfilename_ban", sqlConfig)
if err != nil {
return err
}
usernameBansExist, err = common.TableExists(ctx, dbu.db, nil, "DBPREFIXusername_ban", sqlConfig)
usernameBansExist, err = migrationutil.TableExists(ctx, dbu.DB, nil, "DBPREFIXusername_ban", sqlConfig)
if err != nil {
return err
}
wordfiltersExist, err = common.TableExists(ctx, dbu.db, nil, "DBPREFIXwordfilters", sqlConfig)
wordfiltersExist, err = migrationutil.TableExists(ctx, dbu.DB, nil, "DBPREFIXwordfilters", sqlConfig)
if err != nil {
return err
}
if fileBansExist {
if err = dbu.migrateFileBans(ctx, sqlConfig, errEv); err != nil {
if err = dbu.updateFileBans(ctx, sqlConfig, errEv); err != nil {
return err
}
}
if filenameBansExist {
if err = dbu.migrateFilenameBans(ctx, sqlConfig, errEv); err != nil {
if err = dbu.updateFilenameBans(ctx, sqlConfig, errEv); err != nil {
return err
}
}
if usernameBansExist {
if err = dbu.migrateUsernameBans(ctx, sqlConfig, errEv); err != nil {
if err = dbu.updateUsernameBans(ctx, sqlConfig, errEv); err != nil {
return err
}
}
if wordfiltersExist {
if err = dbu.migrateWordfilters(ctx, sqlConfig, errEv); err != nil {
if err = dbu.updateWordfilters(ctx, sqlConfig, errEv); err != nil {
return err
}
}
@ -190,8 +190,8 @@ func (dbu *GCDatabaseUpdater) migrateFilters(ctx context.Context, sqlConfig *con
return nil
}
func (dbu *GCDatabaseUpdater) migrateFileBans(ctx context.Context, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) {
tx, err := dbu.db.BeginTx(ctx, nil)
func (dbu *DatabaseUpdater) updateFileBans(ctx context.Context, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) {
tx, err := dbu.DB.BeginTx(ctx, nil)
defer func() {
if a := recover(); a != nil {
err = fmt.Errorf("recovered: %v", a)
@ -209,7 +209,7 @@ func (dbu *GCDatabaseUpdater) migrateFileBans(ctx context.Context, sqlConfig *co
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 = common.ColumnType(ctx, dbu.db, nil, "fingerprinter", "DBPREFIXfile_ban", sqlConfig)
fingerprinterCol, err = migrationutil.ColumnType(ctx, dbu.DB, nil, "fingerprinter", "DBPREFIXfile_ban", sqlConfig)
if err != nil {
return err
}
@ -219,7 +219,7 @@ func (dbu *GCDatabaseUpdater) migrateFileBans(ctx context.Context, sqlConfig *co
}
var banIPCol string
banIPCol, err = common.ColumnType(ctx, dbu.db, nil, "ban_ip", "DBPREFIXfile_ban", sqlConfig)
banIPCol, err = migrationutil.ColumnType(ctx, dbu.DB, nil, "ban_ip", "DBPREFIXfile_ban", sqlConfig)
if err != nil {
return err
}
@ -227,7 +227,7 @@ func (dbu *GCDatabaseUpdater) migrateFileBans(ctx context.Context, sqlConfig *co
query = strings.ReplaceAll(query, "ban_ip", "FALSE AS ban_ip")
}
rows, err := dbu.db.QueryContextSQL(ctx, nil, query)
rows, err := dbu.DB.QueryContextSQL(ctx, nil, query)
if err != nil {
return err
}
@ -278,8 +278,8 @@ func (dbu *GCDatabaseUpdater) migrateFileBans(ctx context.Context, sqlConfig *co
return tx.Commit()
}
func (dbu *GCDatabaseUpdater) migrateFilenameBans(ctx context.Context, _ *config.SQLConfig, errEv *zerolog.Event) (err error) {
tx, err := dbu.db.BeginTx(ctx, nil)
func (dbu *DatabaseUpdater) updateFilenameBans(ctx context.Context, _ *config.SQLConfig, errEv *zerolog.Event) (err error) {
tx, err := dbu.DB.BeginTx(ctx, nil)
defer func() {
if a := recover(); a != nil {
err = fmt.Errorf("recovered: %v", a)
@ -296,7 +296,7 @@ func (dbu *GCDatabaseUpdater) migrateFilenameBans(ctx context.Context, _ *config
}
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 := dbu.DB.QueryContextSQL(ctx, nil, query)
if err != nil {
return err
}
@ -336,8 +336,8 @@ func (dbu *GCDatabaseUpdater) migrateFilenameBans(ctx context.Context, _ *config
return tx.Commit()
}
func (dbu *GCDatabaseUpdater) migrateUsernameBans(ctx context.Context, _ *config.SQLConfig, errEv *zerolog.Event) (err error) {
tx, err := dbu.db.BeginTx(ctx, nil)
func (dbu *DatabaseUpdater) updateUsernameBans(ctx context.Context, _ *config.SQLConfig, errEv *zerolog.Event) (err error) {
tx, err := dbu.DB.BeginTx(ctx, nil)
defer func() {
if a := recover(); a != nil {
err = fmt.Errorf("recovered: %v", a)
@ -354,7 +354,7 @@ func (dbu *GCDatabaseUpdater) migrateUsernameBans(ctx context.Context, _ *config
}
query := "SELECT board_id, staff_id, staff_note, issued_at, username FROM DBPREFIXusername_ban"
rows, err := dbu.db.QueryContextSQL(ctx, nil, query)
rows, err := dbu.DB.QueryContextSQL(ctx, nil, query)
if err != nil {
return err
}
@ -394,8 +394,8 @@ func (dbu *GCDatabaseUpdater) migrateUsernameBans(ctx context.Context, _ *config
return tx.Commit()
}
func (dbu *GCDatabaseUpdater) migrateWordfilters(ctx context.Context, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) {
tx, err := dbu.db.BeginTx(ctx, nil)
func (dbu *DatabaseUpdater) updateWordfilters(ctx context.Context, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) {
tx, err := dbu.DB.BeginTx(ctx, nil)
defer func() {
if a := recover(); a != nil {
err = fmt.Errorf("recovered: %v", a)
@ -413,7 +413,7 @@ func (dbu *GCDatabaseUpdater) migrateWordfilters(ctx context.Context, sqlConfig
query := "SELECT board_dirs, staff_id, staff_note, issued_at, search, is_regex, change_to FROM DBPREFIXwordfilters"
var boardIDCol string
boardIDCol, err = common.ColumnType(ctx, dbu.db, nil, "board_id", "DBPREFIXwordfilters", sqlConfig)
boardIDCol, err = migrationutil.ColumnType(ctx, dbu.DB, nil, "board_id", "DBPREFIXwordfilters", sqlConfig)
if err != nil {
return err
}
@ -421,7 +421,7 @@ func (dbu *GCDatabaseUpdater) migrateWordfilters(ctx context.Context, sqlConfig
query = strings.ReplaceAll(query, "board_dirs", "board_id")
}
rows, err := dbu.db.QueryContextSQL(ctx, nil, query)
rows, err := dbu.DB.QueryContextSQL(ctx, nil, query)
if err != nil {
return err
}
@ -482,30 +482,3 @@ func (dbu *GCDatabaseUpdater) migrateWordfilters(ctx context.Context, sqlConfig
return tx.Commit()
}
func (*GCDatabaseUpdater) MigrateBoards() error {
return gcutil.ErrNotImplemented
}
func (*GCDatabaseUpdater) MigratePosts() error {
return gcutil.ErrNotImplemented
}
func (*GCDatabaseUpdater) MigrateStaff() error {
return gcutil.ErrNotImplemented
}
func (*GCDatabaseUpdater) MigrateBans() error {
return gcutil.ErrNotImplemented
}
func (*GCDatabaseUpdater) MigrateAnnouncements() error {
return gcutil.ErrNotImplemented
}
func (dbu *GCDatabaseUpdater) Close() error {
if dbu.db != nil {
return dbu.db.Close()
}
return nil
}

View file

@ -1,4 +1,4 @@
package gcupdate
package dbupdate
import (
"context"
@ -7,9 +7,9 @@ import (
"strings"
"time"
"github.com/gochan-org/gochan/cmd/gochan-migration/internal/common"
"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"
)
@ -63,7 +63,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 {
filePath, err := common.GetInitFilePath("initdb_" + sqlConfig.DBtype + ".sql")
filePath, err := migrationutil.GetInitFilePath("initdb_" + sqlConfig.DBtype + ".sql")
defer func() {
if err != nil {
errEv.Err(err).Caller(1).Send()
@ -76,7 +76,7 @@ func addFilterTables(ctx context.Context, db *gcsql.GCDB, tx *sql.Tx, sqlConfig
if err != nil {
return err
}
sqlStr := common.CommentRemover.ReplaceAllString(string(ba), " ")
sqlStr := gcsql.CommentRemover.ReplaceAllString(string(ba), " ")
sqlArr := strings.Split(sqlStr, ";")
for _, stmtStr := range sqlArr {

View file

@ -1,16 +1,16 @@
package gcupdate
package dbupdate
import (
"context"
"database/sql"
"github.com/gochan-org/gochan/cmd/gochan-migration/internal/common"
"github.com/gochan-org/gochan/pkg/config"
"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 *GCDatabaseUpdater, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) {
func updateMysqlDB(ctx context.Context, dbu *DatabaseUpdater, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) {
var query string
var cyclicalType string
defer func() {
@ -23,7 +23,7 @@ func updateMysqlDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *confi
}
}()
dbName := sqlConfig.DBname
db := dbu.db
db := dbu.DB
// fix default collation
query = `ALTER DATABASE ` + dbName + ` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci`
@ -59,7 +59,7 @@ func updateMysqlDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *confi
return err
}
cyclicalType, err = common.ColumnType(ctx, db, nil, "ip", "DBPREFIXip_ban", sqlConfig)
cyclicalType, err = migrationutil.ColumnType(ctx, db, nil, "ip", "DBPREFIXip_ban", sqlConfig)
if err != nil {
return err
}
@ -108,12 +108,12 @@ func updateMysqlDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *confi
}
// Convert DBPREFIXposts.ip to from varchar to varbinary
cyclicalType, err = common.ColumnType(ctx, db, nil, "ip", "DBPREFIXposts", sqlConfig)
cyclicalType, err = migrationutil.ColumnType(ctx, db, nil, "ip", "DBPREFIXposts", sqlConfig)
if err != nil {
errEv.Err(err).Caller().Send()
return err
}
if common.IsStringType(cyclicalType) {
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 {
@ -143,12 +143,12 @@ func updateMysqlDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *confi
}
// Convert DBPREFIXreports.ip to from varchar to varbinary
cyclicalType, err = common.ColumnType(ctx, db, nil, "ip", "DBPREFIXreports", sqlConfig)
cyclicalType, err = migrationutil.ColumnType(ctx, db, nil, "ip", "DBPREFIXreports", sqlConfig)
if err != nil {
errEv.Err(err).Caller().Send()
return err
}
if common.IsStringType(cyclicalType) {
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 {
@ -178,7 +178,7 @@ func updateMysqlDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *confi
}
// add flag column to DBPREFIXposts
cyclicalType, err = common.ColumnType(ctx, db, nil, "flag", "DBPREFIXposts", sqlConfig)
cyclicalType, err = migrationutil.ColumnType(ctx, db, nil, "flag", "DBPREFIXposts", sqlConfig)
if err != nil {
errEv.Err(err).Caller().Send()
return err
@ -192,7 +192,7 @@ func updateMysqlDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *confi
}
// add country column to DBPREFIXposts
cyclicalType, err = common.ColumnType(ctx, db, nil, "country", "DBPREFIXposts", sqlConfig)
cyclicalType, err = migrationutil.ColumnType(ctx, db, nil, "country", "DBPREFIXposts", sqlConfig)
if err != nil {
errEv.Err(err).Caller().Send()
return err
@ -206,7 +206,7 @@ func updateMysqlDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *confi
}
// add is_secure_tripcode column to DBPREFIXposts
cyclicalType, err = common.ColumnType(ctx, db, nil, "is_secure_tripcode", "DBPREFIXposts", sqlConfig)
cyclicalType, err = migrationutil.ColumnType(ctx, db, nil, "is_secure_tripcode", "DBPREFIXposts", sqlConfig)
if err != nil {
errEv.Err(err).Caller().Send()
return err
@ -220,7 +220,7 @@ func updateMysqlDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *confi
}
// add spoilered column to DBPREFIXthreads
cyclicalType, err = common.ColumnType(ctx, db, nil, "is_spoilered", "DBPREFIXthreads", sqlConfig)
cyclicalType, err = migrationutil.ColumnType(ctx, db, nil, "is_spoilered", "DBPREFIXthreads", sqlConfig)
if err != nil {
errEv.Err(err).Caller().Send()
return err
@ -234,12 +234,12 @@ func updateMysqlDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *confi
}
// rename DBPREFIXposts.cyclical to cyclic
cyclicalType, err = common.ColumnType(ctx, db, nil, "cyclical", "DBPREFIXthreads", sqlConfig)
cyclicalType, err = migrationutil.ColumnType(ctx, db, nil, "cyclical", "DBPREFIXthreads", sqlConfig)
if err != nil {
errEv.Err(err).Caller().Send()
return err
}
cyclicType, err := common.ColumnType(ctx, db, nil, "cyclic", "DBPREFIXthreads", sqlConfig)
cyclicType, err := migrationutil.ColumnType(ctx, db, nil, "cyclic", "DBPREFIXthreads", sqlConfig)
if err != nil {
errEv.Err(err).Caller().Send()
return err

View file

@ -1,18 +1,18 @@
package gcupdate
package dbupdate
import (
"context"
"github.com/gochan-org/gochan/cmd/gochan-migration/internal/common"
"github.com/gochan-org/gochan/pkg/config"
"github.com/gochan-org/gochan/pkg/gcsql/migrationutil"
"github.com/rs/zerolog"
)
func updatePostgresDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) {
db := dbu.db
func updatePostgresDB(ctx context.Context, dbu *DatabaseUpdater, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) {
db := dbu.DB
var query, dataType string
dataType, err = common.ColumnType(ctx, db, nil, "ip", "DBPREFIXposts", sqlConfig)
dataType, err = migrationutil.ColumnType(ctx, db, nil, "ip", "DBPREFIXposts", sqlConfig)
defer func() {
if a := recover(); a != nil {
errEv.Caller(4).Interface("panic", a).Send()
@ -25,7 +25,7 @@ func updatePostgresDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *co
if err != nil {
return err
}
if common.IsStringType(dataType) {
if migrationutil.IsStringType(dataType) {
// 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 {
@ -51,7 +51,7 @@ func updatePostgresDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *co
}
}
dataType, err = common.ColumnType(ctx, db, nil, "ip", "DBPREFIXip_ban", sqlConfig)
dataType, err = migrationutil.ColumnType(ctx, db, nil, "ip", "DBPREFIXip_ban", sqlConfig)
if err != nil {
return err
}
@ -70,7 +70,7 @@ func updatePostgresDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *co
}
// add flag column to DBPREFIXposts
dataType, err = common.ColumnType(ctx, db, nil, "flag", "DBPREFIXposts", sqlConfig)
dataType, err = migrationutil.ColumnType(ctx, db, nil, "flag", "DBPREFIXposts", sqlConfig)
if err != nil {
return err
}
@ -82,7 +82,7 @@ func updatePostgresDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *co
}
// add country column to DBPREFIXposts
dataType, err = common.ColumnType(ctx, db, nil, "country", "DBPREFIXposts", sqlConfig)
dataType, err = migrationutil.ColumnType(ctx, db, nil, "country", "DBPREFIXposts", sqlConfig)
if err != nil {
return err
}
@ -94,7 +94,7 @@ func updatePostgresDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *co
}
// add is_secure_tripcode column to DBPREFIXposts
dataType, err = common.ColumnType(ctx, db, nil, "is_secure_tripcode", "DBPREFIXposts", sqlConfig)
dataType, err = migrationutil.ColumnType(ctx, db, nil, "is_secure_tripcode", "DBPREFIXposts", sqlConfig)
if err != nil {
return err
}
@ -106,7 +106,7 @@ func updatePostgresDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *co
}
// add spoilered column to DBPREFIXthreads
dataType, err = common.ColumnType(ctx, db, nil, "is_spoilered", "DBPREFIXthreads", sqlConfig)
dataType, err = migrationutil.ColumnType(ctx, db, nil, "is_spoilered", "DBPREFIXthreads", sqlConfig)
if err != nil {
return err
}
@ -118,7 +118,7 @@ func updatePostgresDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *co
}
// rename DBPREFIXposts.cyclical to cyclic
dataType, err = common.ColumnType(ctx, db, nil, "cyclic", "DBPREFIXposts", sqlConfig)
dataType, err = migrationutil.ColumnType(ctx, db, nil, "cyclic", "DBPREFIXposts", sqlConfig)
if err != nil {
errEv.Err(err).Caller().Send()
return err

View file

@ -1,16 +1,16 @@
package gcupdate
package dbupdate
import (
"context"
"github.com/gochan-org/gochan/cmd/gochan-migration/internal/common"
"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 updateSqliteDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) {
db := dbu.db
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`)
defer func() {
@ -29,7 +29,7 @@ func updateSqliteDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *conf
opts := &gcsql.RequestOptions{Context: ctx}
// simple alterations first
dataType, err := common.ColumnType(ctx, db, nil, "cyclical", "DBPREFIXthreads", sqlConfig)
dataType, err := migrationutil.ColumnType(ctx, db, nil, "cyclical", "DBPREFIXthreads", sqlConfig)
if err != nil {
errEv.Err(err).Caller().Send()
return err
@ -40,7 +40,7 @@ func updateSqliteDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *conf
}
}
if dataType, err = common.ColumnType(ctx, db, nil, "is_secure_tripcode", "DBPREFIXposts", sqlConfig); err != nil {
if dataType, err = migrationutil.ColumnType(ctx, db, nil, "is_secure_tripcode", "DBPREFIXposts", sqlConfig); err != nil {
errEv.Err(err).Caller().Send()
return err
}
@ -50,7 +50,7 @@ func updateSqliteDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *conf
}
}
if dataType, err = common.ColumnType(ctx, db, nil, "flag", "DBPREFIXposts", sqlConfig); err != nil {
if dataType, err = migrationutil.ColumnType(ctx, db, nil, "flag", "DBPREFIXposts", sqlConfig); err != nil {
return err
}
if dataType == "" {
@ -59,7 +59,7 @@ func updateSqliteDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *conf
}
}
if dataType, err = common.ColumnType(ctx, db, nil, "country", "DBPREFIXposts", sqlConfig); err != nil {
if dataType, err = migrationutil.ColumnType(ctx, db, nil, "country", "DBPREFIXposts", sqlConfig); err != nil {
return err
}
if dataType == "" {
@ -68,7 +68,7 @@ func updateSqliteDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *conf
}
}
if dataType, err = common.ColumnType(ctx, db, nil, "expires", "DBPREFIXsessions", sqlConfig); err != nil {
if dataType, err = migrationutil.ColumnType(ctx, db, nil, "expires", "DBPREFIXsessions", sqlConfig); err != nil {
return err
}
if dataType == "" {
@ -77,7 +77,7 @@ func updateSqliteDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *conf
}
}
if dataType, err = common.ColumnType(ctx, db, nil, "data", "DBPREFIXsessions", sqlConfig); err != nil {
if dataType, err = migrationutil.ColumnType(ctx, db, nil, "data", "DBPREFIXsessions", sqlConfig); err != nil {
return err
}
if dataType == "" {
@ -86,7 +86,7 @@ func updateSqliteDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *conf
}
}
dataType, err = common.ColumnType(ctx, db, nil, "range_start", "DBPREFIXip_ban", sqlConfig)
dataType, err = migrationutil.ColumnType(ctx, db, nil, "range_start", "DBPREFIXip_ban", sqlConfig)
if err != nil {
return err
}
@ -99,7 +99,7 @@ func updateSqliteDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *conf
}
}
dataType, err = common.ColumnType(ctx, db, nil, "range_end", "DBPREFIXip_ban", sqlConfig)
dataType, err = migrationutil.ColumnType(ctx, db, nil, "range_end", "DBPREFIXip_ban", sqlConfig)
if err != nil {
return err
}
@ -112,7 +112,7 @@ func updateSqliteDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *conf
}
}
dataType, err = common.ColumnType(ctx, db, nil, "is_spoilered", "DBPREFIXthreads", sqlConfig)
dataType, err = migrationutil.ColumnType(ctx, db, nil, "is_spoilered", "DBPREFIXthreads", sqlConfig)
if err != nil {
return err
}
@ -122,14 +122,14 @@ func updateSqliteDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *conf
}
}
filtersExist, err := common.TableExists(ctx, db, nil, "DBPREFIXfilters", sqlConfig)
filtersExist, err := migrationutil.TableExists(ctx, db, 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 = common.ColumnType(ctx, db, nil, "fingerprinter", "DBPREFIXfile_ban", sqlConfig)
dataType, err = migrationutil.ColumnType(ctx, db, nil, "fingerprinter", "DBPREFIXfile_ban", sqlConfig)
if err != nil {
return err
}
@ -139,7 +139,7 @@ func updateSqliteDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *conf
}
}
dataType, err = common.ColumnType(ctx, db, nil, "ban_ip", "DBPREFIXfile_ban", sqlConfig)
dataType, err = migrationutil.ColumnType(ctx, db, nil, "ban_ip", "DBPREFIXfile_ban", sqlConfig)
if err != nil {
return err
}
@ -149,7 +149,7 @@ func updateSqliteDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *conf
}
}
dataType, err = common.ColumnType(ctx, db, nil, "ban_ip_message", "DBPREFIXfile_ban", sqlConfig)
dataType, err = migrationutil.ColumnType(ctx, db, nil, "ban_ip_message", "DBPREFIXfile_ban", sqlConfig)
if err != nil {
return err
}

View file

@ -1,4 +1,4 @@
package common
package migrationutil
import (
"context"

View file

@ -20,8 +20,6 @@ const (
)
var (
// ErrInvalidVersion is used when the db contains a database_version table
// but zero or more than one versions were found
ErrInvalidVersion = errors.New("database contains database_version table but zero or more than one versions were found")
ErrCorruptedDB = errors.New("database contains gochan prefixed tables but is missing versioning tables (possibly corrupted)")
ErrDeprecatedDB = errors.New("database layout is deprecated, please run gochan-migration -updatedb")

View file

@ -103,11 +103,12 @@ func (s *Staff) ClearSessions() error {
}
func (s *Staff) RankTitle() string {
if s.Rank == 3 {
switch s.Rank {
case 3:
return "Administrator"
} else if s.Rank == 2 {
case 2:
return "Moderator"
} else if s.Rank == 1 {
case 1:
return "Janitor"
}
return ""

View file

@ -5,6 +5,7 @@ import (
"database/sql"
"errors"
"fmt"
"regexp"
"strings"
"time"
@ -17,8 +18,6 @@ const (
OnlyFalse
)
const ()
var (
dateTimeFormats = []string{
"2006-01-02 15:04:05",
@ -26,8 +25,19 @@ var (
}
ErrUnsupportedDB = errors.New("unsupported SQL driver, supported drivers: " + strings.Join(sql.Drivers(), ", "))
ErrNotConnected = errors.New("error connecting to database")
CommentRemover = regexp.MustCompile("--.*\n?")
)
// GetDatabase returns the active database connection. If the database is not connected, it will attempt to connect to
// the configured database
func GetDatabase() (*GCDB, error) {
if gcdb == nil {
sqlCfg := config.GetSQLConfig()
return Open(&sqlCfg)
}
return gcdb, nil
}
// BooleanFilter is used for optionally limiting results to true, false, or both
type BooleanFilter int
@ -37,9 +47,10 @@ func (af BooleanFilter) whereClause(columnName string, and bool) string {
if and {
out = " AND "
}
if af == OnlyTrue {
switch af {
case OnlyTrue:
return out + columnName + " = TRUE"
} else if af == OnlyFalse {
case OnlyFalse:
return out + columnName + " = FALSE"
}
return ""