2018-03-31 05:25:27 +00:00
package main
import (
2022-02-21 03:32:53 +00:00
"bufio"
"database/sql"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"runtime/debug"
"strconv"
c "github.com/Azareal/Gosora/common"
qgen "github.com/Azareal/Gosora/query_gen"
_ "github.com/go-sql-driver/mysql"
2018-03-31 05:25:27 +00:00
)
2018-05-16 10:46:14 +00:00
var patches = make ( map [ int ] func ( * bufio . Scanner ) error )
func addPatch ( index int , handle func ( * bufio . Scanner ) error ) {
2022-02-21 03:32:53 +00:00
patches [ index ] = handle
2018-05-16 10:46:14 +00:00
}
2018-03-31 05:25:27 +00:00
func main ( ) {
2022-02-21 03:32:53 +00:00
scanner := bufio . NewScanner ( os . Stdin )
// Capture panics instead of closing the window at a superhuman speed before the user can read the message on Windows
defer func ( ) {
if r := recover ( ) ; r != nil {
fmt . Println ( r )
debug . PrintStack ( )
pressAnyKey ( scanner )
log . Fatal ( "" )
return
}
} ( )
log . Print ( "Loading the configuration data" )
err := c . LoadConfig ( )
if err != nil {
log . Fatal ( err )
}
log . Print ( "Processing configuration data" )
err = c . ProcessConfig ( )
if err != nil {
log . Fatal ( err )
}
if c . DbConfig . Adapter != "mysql" && c . DbConfig . Adapter != "" {
log . Fatal ( "Only MySQL is supported for upgrades right now, please wait for a newer build of the patcher" )
}
err = prepMySQL ( )
if err != nil {
log . Fatal ( err )
}
err = patcher ( scanner )
if err != nil {
log . Fatal ( err )
}
2018-03-31 05:25:27 +00:00
}
func pressAnyKey ( scanner * bufio . Scanner ) {
2022-02-21 03:32:53 +00:00
fmt . Println ( "Please press enter to exit..." )
for scanner . Scan ( ) {
_ = scanner . Text ( )
return
}
2018-03-31 05:25:27 +00:00
}
2018-04-22 14:27:04 +00:00
func prepMySQL ( ) error {
2022-02-21 03:32:53 +00:00
return qgen . Builder . Init ( "mysql" , map [ string ] string {
"host" : c . DbConfig . Host ,
"port" : c . DbConfig . Port ,
"name" : c . DbConfig . Dbname ,
"username" : c . DbConfig . Username ,
"password" : c . DbConfig . Password ,
"collation" : "utf8mb4_general_ci" ,
} )
2018-04-22 14:27:04 +00:00
}
2018-04-23 08:38:25 +00:00
type SchemaFile struct {
2022-02-21 03:32:53 +00:00
DBVersion string // Current version of the database schema
DynamicFileVersion string
MinGoVersion string // TODO: Minimum version of Go needed to install this version
MinVersion string // TODO: Minimum version of Gosora to jump to this version, might be tricky as we don't store this in the schema file, maybe store it in the database
2018-04-22 14:27:04 +00:00
}
2018-12-27 05:42:41 +00:00
func loadSchema ( ) ( schemaFile SchemaFile , err error ) {
2022-02-21 03:32:53 +00:00
fmt . Println ( "Loading the schema file" )
data , err := ioutil . ReadFile ( "./schema/lastSchema.json" )
if err != nil {
return schemaFile , err
}
err = json . Unmarshal ( data , & schemaFile )
return schemaFile , err
2018-12-27 05:42:41 +00:00
}
func patcher ( scanner * bufio . Scanner ) error {
2022-02-21 03:32:53 +00:00
var dbVersion int
err := qgen . NewAcc ( ) . Select ( "updates" ) . Columns ( "dbVersion" ) . QueryRow ( ) . Scan ( & dbVersion )
if err == sql . ErrNoRows {
schemaFile , err := loadSchema ( )
if err != nil {
return err
}
dbVersion , err = strconv . Atoi ( schemaFile . DBVersion )
if err != nil {
return err
}
} else if err != nil {
return err
}
fmt . Println ( "Applying the patches" )
var pslice = make ( [ ] func ( * bufio . Scanner ) error , len ( patches ) )
for i := 0 ; i < len ( patches ) ; i ++ {
pslice [ i ] = patches [ i ]
}
// Run the queued up patches
var patched int
for index , patch := range pslice {
if dbVersion > index {
continue
}
err := patch ( scanner )
if err != nil {
fmt . Println ( "Failed to apply patch " + strconv . Itoa ( index + 1 ) )
return err
}
fmt . Println ( "Applied patch " + strconv . Itoa ( index + 1 ) )
patched ++
}
if patched > 0 {
_ , err := qgen . NewAcc ( ) . Update ( "updates" ) . Set ( "dbVersion = ?" ) . Exec ( len ( pslice ) )
if err != nil {
return err
}
} else {
fmt . Println ( "No new patches found." )
}
return nil
2018-03-31 05:25:27 +00:00
}