2018-03-31 05:25:27 +00:00
package main
import (
"bufio"
2018-12-27 05:42:41 +00:00
"database/sql"
2018-04-23 08:38:25 +00:00
"encoding/json"
2018-03-31 05:25:27 +00:00
"fmt"
2018-04-23 08:38:25 +00:00
"io/ioutil"
2018-04-22 14:27:04 +00:00
"log"
2018-03-31 05:25:27 +00:00
"os"
"runtime/debug"
2018-05-14 08:56:56 +00:00
"strconv"
2018-03-31 05:25:27 +00:00
2019-04-19 06:36:26 +00:00
c "github.com/Azareal/Gosora/common"
2018-10-27 03:21:02 +00:00
"github.com/Azareal/Gosora/query_gen"
2018-04-22 14:27:04 +00:00
_ "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 ) {
patches [ index ] = handle
}
2018-03-31 05:25:27 +00:00
func main ( ) {
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 ( ) {
2020-11-09 06:28:14 +00:00
if r := recover ( ) r != nil {
2018-03-31 05:25:27 +00:00
fmt . Println ( r )
debug . PrintStack ( )
pressAnyKey ( scanner )
2018-05-11 05:41:51 +00:00
log . Fatal ( "" )
2018-03-31 05:25:27 +00:00
return
}
} ( )
2018-06-17 07:28:18 +00:00
log . Print ( "Loading the configuration data" )
2019-04-19 06:36:26 +00:00
err := c . LoadConfig ( )
2018-06-17 07:28:18 +00:00
if err != nil {
log . Fatal ( err )
}
log . Print ( "Processing configuration data" )
2019-04-19 06:36:26 +00:00
err = c . ProcessConfig ( )
2018-06-17 07:28:18 +00:00
if err != nil {
log . Fatal ( err )
}
2019-04-19 06:36:26 +00:00
if c . DbConfig . Adapter != "mysql" && c . DbConfig . Adapter != "" {
2018-04-22 14:27:04 +00:00
log . Fatal ( "Only MySQL is supported for upgrades right now, please wait for a newer build of the patcher" )
}
2018-06-17 07:28:18 +00:00
err = prepMySQL ( )
2018-03-31 05:25:27 +00:00
if err != nil {
2018-04-22 14:27:04 +00:00
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 ) {
fmt . Println ( "Please press enter to exit..." )
for scanner . Scan ( ) {
_ = scanner . Text ( )
return
}
}
2018-04-22 14:27:04 +00:00
func prepMySQL ( ) error {
2018-04-23 08:38:25 +00:00
return qgen . Builder . Init ( "mysql" , map [ string ] string {
2019-04-19 06:36:26 +00:00
"host" : c . DbConfig . Host ,
"port" : c . DbConfig . Port ,
"name" : c . DbConfig . Dbname ,
"username" : c . DbConfig . Username ,
"password" : c . DbConfig . Password ,
2018-04-22 14:27:04 +00:00
"collation" : "utf8mb4_general_ci" ,
} )
}
2018-04-23 08:38:25 +00:00
type SchemaFile struct {
2018-04-23 21:08:31 +00:00
DBVersion string // Current version of the database schema
DynamicFileVersion string
2018-04-23 08:38:25 +00:00
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 ) {
2018-05-11 05:41:51 +00:00
fmt . Println ( "Loading the schema file" )
2018-04-23 08:38:25 +00:00
data , err := ioutil . ReadFile ( "./schema/lastSchema.json" )
2018-04-22 14:27:04 +00:00
if err != nil {
2018-12-27 05:42:41 +00:00
return schemaFile , err
2018-04-22 14:27:04 +00:00
}
2018-04-23 08:38:25 +00:00
err = json . Unmarshal ( data , & schemaFile )
2018-12-27 05:42:41 +00:00
return schemaFile , err
}
func patcher ( scanner * bufio . Scanner ) error {
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 {
2018-05-14 08:56:56 +00:00
return err
}
2018-05-11 05:41:51 +00:00
fmt . Println ( "Applying the patches" )
2018-05-16 10:46:14 +00:00
var pslice = make ( [ ] func ( * bufio . Scanner ) error , len ( patches ) )
for i := 0 ; i < len ( patches ) ; i ++ {
pslice [ i ] = patches [ i ]
2018-04-22 14:27:04 +00:00
}
2018-03-31 05:25:27 +00:00
2018-05-16 10:46:14 +00:00
// Run the queued up patches
2018-12-27 05:42:41 +00:00
var patched int
2018-05-16 10:46:14 +00:00
for index , patch := range pslice {
if dbVersion > index {
continue
}
err := patch ( scanner )
2018-03-31 05:25:27 +00:00
if err != nil {
2019-11-10 02:37:53 +00:00
fmt . Println ( "Failed to apply patch " + strconv . Itoa ( index + 1 ) )
2018-03-31 05:25:27 +00:00
return err
}
2019-11-10 02:37:53 +00:00
fmt . Println ( "Applied patch " + strconv . Itoa ( index + 1 ) )
2018-12-27 05:42:41 +00:00
patched ++
}
if patched > 0 {
_ , err := qgen . NewAcc ( ) . Update ( "updates" ) . Set ( "dbVersion = ?" ) . Exec ( len ( pslice ) )
if err != nil {
return err
}
2019-11-10 02:37:53 +00:00
} else {
fmt . Println ( "No new patches found." )
2018-03-31 05:25:27 +00:00
}
2018-05-16 10:46:14 +00:00
return nil
2018-03-31 05:25:27 +00:00
}