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

Move database schema updating to gochan-migration

This commit is contained in:
Eggbertx 2023-04-07 14:34:28 -07:00
parent 1da4330780
commit 17c28e5ebe
8 changed files with 260 additions and 119 deletions

View file

@ -4,8 +4,6 @@ import (
"os"
"regexp"
"strings"
"github.com/gochan-org/gochan/pkg/config"
)
var (
@ -44,96 +42,3 @@ func RunSQLFile(path string) error {
}
return tx.Commit()
}
// TODO: get gochan-migration working so this doesn't have to sit here
func tmpSqlAdjust() error {
// first update the crappy wordfilter table structure
var err error
var query string
switch gcdb.driver {
case "mysql":
query = `SELECT COUNT(*) FROM information_schema.TABLE_CONSTRAINTS
WHERE CONSTRAINT_NAME = 'wordfilters_board_id_fk'
AND TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'DBPREFIXwordfilters'`
var numConstraints int
if err = gcdb.QueryRowSQL(query,
interfaceSlice(),
interfaceSlice(&numConstraints)); err != nil {
return err
}
if numConstraints > 0 {
query = `ALTER TABLE DBPREFIXwordfilters DROP FOREIGN KEY wordfilters_board_id_fk`
} else {
query = ""
}
query = `SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'DBPREFIXwordfilters'
AND COLUMN_NAME = 'board_dirs'`
var numColumns int
if err = gcdb.QueryRowSQL(query,
interfaceSlice(),
interfaceSlice(&numColumns)); err != nil {
return err
}
if numColumns == 0 {
query = `ALTER TABLE DBPREFIXwordfilters ADD COLUMN board_dirs varchar(255) DEFAULT '*'`
if _, err = ExecSQL(query); err != nil {
return err
}
}
// Yay, collation! Everybody loves MySQL's default collation!
criticalConfig := config.GetSystemCriticalConfig()
query = `ALTER DATABASE ` + criticalConfig.DBname + ` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci`
if _, err = gcdb.db.Exec(query); err != nil {
return err
}
query = `SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = ?`
rows, err := QuerySQL(query, criticalConfig.DBname)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var tableName string
err = rows.Scan(&tableName)
if err != nil {
return err
}
query = `ALTER TABLE ` + tableName + ` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci`
if _, err = gcdb.db.Exec(query); err != nil {
return err
}
}
err = nil
case "postgres":
_, err = ExecSQL(`ALTER TABLE DBPREFIXwordfilters DROP CONSTRAINT IF EXISTS board_id_fk`)
if err != nil {
return err
}
query = `ALTER TABLE DBPREFIXwordfilters ADD COLUMN IF NOT EXISTS board_dirs varchar(255) DEFAULT '*'`
if _, err = ExecSQL(query); err != nil {
return err
}
case "sqlite3":
_, err = ExecSQL(`PRAGMA foreign_keys = ON`)
if err != nil {
return err
}
query = `SELECT COUNT(*) FROM PRAGMA_TABLE_INFO('DBPREFIXwordfilters') WHERE name = 'board_dirs'`
var numColumns int
if err = QueryRowSQL(query, interfaceSlice(), interfaceSlice(&numColumns)); err != nil {
return err
}
if numColumns == 0 {
query = `ALTER TABLE DBPREFIXwordfilters ADD COLUMN board_dirs varchar(255) DEFAULT '*'`
if _, err = ExecSQL(query); err != nil {
return err
}
}
}
return err
}

View file

@ -84,6 +84,26 @@ func (db *GCDB) ExecSQL(query string, values ...interface{}) (sql.Result, error)
return stmt.Exec(values...)
}
/*
ExecTxSQL automatically escapes the given values and caches the statement
Example:
tx, err := BeginTx()
// do error handling stuff
defer tx.Rollback()
var intVal int
var stringVal string
result, err := db.ExecTxSQL(tx, "INSERT INTO tablename (intval,stringval) VALUES(?,?)",
intVal, stringVal)
*/
func (db *GCDB) ExecTxSQL(tx *sql.Tx, query string, values ...interface{}) (sql.Result, error) {
stmt, err := db.PrepareSQL(query, tx)
if err != nil {
return nil, err
}
return stmt.Exec(values...)
}
/*
Begin creates and returns a new SQL transaction using the GCDB. Note that it doesn't use gochan's
database variables, e.g. DBPREFIX, DBNAME, etc so it should be used sparingly or with
@ -123,6 +143,29 @@ func (db *GCDB) QueryRowSQL(query string, values, out []interface{}) error {
return stmt.QueryRow(values...).Scan(out...)
}
/*
QueryRowTxSQL gets a row from the db with the values in values[] and fills the respective pointers in out[]
Automatically escapes the given values and caches the query
Example:
id := 32
var intVal int
var stringVal string
tx, err := BeginTx()
// do error handling stuff
defer tx.Rollback()
err = QueryRowTxSQL(tx, "SELECT intval,stringval FROM table WHERE id = ?",
[]interface{}{id},
[]interface{}{&intVal, &stringVal})
*/
func (db *GCDB) QueryRowTxSQL(tx *sql.Tx, query string, values, out []interface{}) error {
stmt, err := db.PrepareSQL(query, tx)
if err != nil {
return err
}
return stmt.QueryRow(values...).Scan(out...)
}
/*
QuerySQL gets all rows from the db with the values in values[] and fills the respective pointers in out[]
Automatically escapes the given values and caches the query

View file

@ -16,7 +16,7 @@ const (
DBUpToDate
DBModernButAhead
targetDatabaseVersion = 1
targetDatabaseVersion = 2
)
var (
@ -108,7 +108,7 @@ func CheckAndInitializeDatabase(dbType string) error {
if err != nil {
return err
}
return tmpSqlAdjust()
return nil
}
func buildNewDatabase(dbType string) error {

View file

@ -142,7 +142,7 @@ func QueryRowSQL(query string, values, out []interface{}) error {
}
/*
QueryRowSQL gets a row from the db with the values in values[] and fills the respective pointers in out[]
QueryRowTxSQL gets a row from the db with the values in values[] and fills the respective pointers in out[]
Automatically escapes the given values and caches the query
Example:
@ -160,11 +160,7 @@ func QueryRowTxSQL(tx *sql.Tx, query string, values, out []interface{}) error {
if gcdb == nil {
return ErrNotConnected
}
stmt, err := PrepareSQL(query, tx)
if err != nil {
return err
}
return stmt.QueryRow(values...).Scan(out...)
return gcdb.QueryRowTxSQL(tx, query, values, out)
}
/*