The patcher can now update the schema for MySQL.

Added the adapter config value, to be used in the main system soon.
Commented out the debug code for the menus.

We're pushing some schema changes in this commit, so we'll see how well the patcher goes and whether it'll need to be patched.
This commit is contained in:
Azareal 2018-04-22 15:27:04 +01:00
parent 10f4c59cb5
commit f102c97606
9 changed files with 147 additions and 36 deletions

View File

@ -110,9 +110,9 @@ func (hold *MenuListHolder) Preparse() error {
var addVariation = func(index int, callback func(mitem MenuItem) bool) { var addVariation = func(index int, callback func(mitem MenuItem) bool) {
renderBuffer, variableIndices := hold.Scan(tmpls, callback) renderBuffer, variableIndices := hold.Scan(tmpls, callback)
hold.Variations[index] = menuTmpl{renderBuffer, variableIndices} hold.Variations[index] = menuTmpl{renderBuffer, variableIndices}
fmt.Print("renderBuffer: ") //fmt.Print("renderBuffer: ")
menuDumpSlice(renderBuffer) //menuDumpSlice(renderBuffer)
fmt.Printf("\nvariableIndices: %+v\n", variableIndices) //fmt.Printf("\nvariableIndices: %+v\n", variableIndices)
} }
// Guest Menu // Guest Menu
@ -243,12 +243,12 @@ func (hold *MenuListHolder) Parse(name string, tmplData []byte) (menuTmpl MenuTm
renderList = append(renderList, menuRenderItem{0, len(textBuffer) - 1}) renderList = append(renderList, menuRenderItem{0, len(textBuffer) - 1})
} }
fmt.Println("name: ", name) //fmt.Println("name: ", name)
fmt.Print("textBuffer: ") //fmt.Print("textBuffer: ")
menuDumpSlice(textBuffer) //menuDumpSlice(textBuffer)
fmt.Print("\nvariableBuffer: ") //fmt.Print("\nvariableBuffer: ")
menuDumpSlice(variableBuffer) //menuDumpSlice(variableBuffer)
fmt.Printf("\nrenderList: %+v\n", renderList) //fmt.Printf("\nrenderList: %+v\n", renderList)
return MenuTmpl{name, textBuffer, variableBuffer, renderList} return MenuTmpl{name, textBuffer, variableBuffer, renderList}
} }
@ -263,7 +263,7 @@ func (hold *MenuListHolder) Scan(menuTmpls map[string]MenuTmpl, showItem func(mi
if !ok { if !ok {
menuTmpl = menuTmpls["menu_item"] menuTmpl = menuTmpls["menu_item"]
} }
fmt.Println("menuTmpl: ", menuTmpl) //fmt.Println("menuTmpl: ", menuTmpl)
for _, renderItem := range menuTmpl.RenderList { for _, renderItem := range menuTmpl.RenderList {
if renderItem.Type == 0 { if renderItem.Type == 0 {
renderBuffer = append(renderBuffer, menuTmpl.TextBuffer[renderItem.Index]) renderBuffer = append(renderBuffer, menuTmpl.TextBuffer[renderItem.Index])
@ -271,15 +271,15 @@ func (hold *MenuListHolder) Scan(menuTmpls map[string]MenuTmpl, showItem func(mi
} }
variable := menuTmpl.VariableBuffer[renderItem.Index] variable := menuTmpl.VariableBuffer[renderItem.Index]
fmt.Println("initial variable: ", string(variable)) //fmt.Println("initial variable: ", string(variable))
dotAt, hasDot := skipUntilIfExists(variable, 0, '.') dotAt, hasDot := skipUntilIfExists(variable, 0, '.')
if !hasDot { if !hasDot {
fmt.Println("no dot") //fmt.Println("no dot")
continue continue
} }
if bytes.Equal(variable[:dotAt], []byte("lang")) { if bytes.Equal(variable[:dotAt], []byte("lang")) {
fmt.Println("lang: ", string(bytes.TrimPrefix(variable[dotAt:], []byte(".")))) //fmt.Println("lang: ", string(bytes.TrimPrefix(variable[dotAt:], []byte("."))))
renderBuffer = append(renderBuffer, []byte(GetTmplPhrase(string(bytes.TrimPrefix(variable[dotAt:], []byte(".")))))) renderBuffer = append(renderBuffer, []byte(GetTmplPhrase(string(bytes.TrimPrefix(variable[dotAt:], []byte("."))))))
} else { } else {
var renderItem []byte var renderItem []byte
@ -300,7 +300,7 @@ func (hold *MenuListHolder) Scan(menuTmpls map[string]MenuTmpl, showItem func(mi
_, hasInnerVar := skipUntilIfExists(renderItem, 0, '{') _, hasInnerVar := skipUntilIfExists(renderItem, 0, '{')
if hasInnerVar { if hasInnerVar {
fmt.Println("inner var: ", string(renderItem)) //fmt.Println("inner var: ", string(renderItem))
dotAt, hasDot := skipUntilIfExists(renderItem, 0, '.') dotAt, hasDot := skipUntilIfExists(renderItem, 0, '.')
endFence, hasEndFence := skipUntilIfExists(renderItem, dotAt, '}') endFence, hasEndFence := skipUntilIfExists(renderItem, dotAt, '}')
if !hasDot || !hasEndFence || (endFence-dotAt) <= 1 { if !hasDot || !hasEndFence || (endFence-dotAt) <= 1 {
@ -310,10 +310,10 @@ func (hold *MenuListHolder) Scan(menuTmpls map[string]MenuTmpl, showItem func(mi
} }
if bytes.Equal(renderItem[1:dotAt], []byte("lang")) { if bytes.Equal(renderItem[1:dotAt], []byte("lang")) {
fmt.Println("lang var: ", string(renderItem[dotAt+1:endFence])) //fmt.Println("lang var: ", string(renderItem[dotAt+1:endFence]))
renderBuffer = append(renderBuffer, []byte(GetTmplPhrase(string(renderItem[dotAt+1:endFence])))) renderBuffer = append(renderBuffer, []byte(GetTmplPhrase(string(renderItem[dotAt+1:endFence]))))
} else { } else {
fmt.Println("other var: ", string(variable[:dotAt])) //fmt.Println("other var: ", string(variable[:dotAt]))
if len(renderItem) > 0 { if len(renderItem) > 0 {
renderBuffer = append(renderBuffer, renderItem) renderBuffer = append(renderBuffer, renderItem)
variableIndices = append(variableIndices, len(renderBuffer)-1) variableIndices = append(variableIndices, len(renderBuffer)-1)
@ -322,7 +322,7 @@ func (hold *MenuListHolder) Scan(menuTmpls map[string]MenuTmpl, showItem func(mi
continue continue
} }
fmt.Println("normal var: ", string(variable[:dotAt])) //fmt.Println("normal var: ", string(variable[:dotAt]))
if len(renderItem) > 0 { if len(renderItem) > 0 {
renderBuffer = append(renderBuffer, renderItem) renderBuffer = append(renderBuffer, renderItem)
} }
@ -347,9 +347,9 @@ func (hold *MenuListHolder) Build(w io.Writer, user *User) error {
} }
if len(mTmpl.VariableIndices) == 0 { if len(mTmpl.VariableIndices) == 0 {
fmt.Println("no variable indices") //fmt.Println("no variable indices")
for _, renderItem := range mTmpl.RenderBuffer { for _, renderItem := range mTmpl.RenderBuffer {
fmt.Printf("renderItem: %+v\n", renderItem) //fmt.Printf("renderItem: %+v\n", renderItem)
w.Write(renderItem) w.Write(renderItem)
} }
return nil return nil
@ -358,12 +358,12 @@ func (hold *MenuListHolder) Build(w io.Writer, user *User) error {
var nearIndex = 0 var nearIndex = 0
for index, renderItem := range mTmpl.RenderBuffer { for index, renderItem := range mTmpl.RenderBuffer {
if index != mTmpl.VariableIndices[nearIndex] { if index != mTmpl.VariableIndices[nearIndex] {
fmt.Println("wrote text: ", string(renderItem)) //fmt.Println("wrote text: ", string(renderItem))
w.Write(renderItem) w.Write(renderItem)
continue continue
} }
fmt.Println("variable: ", string(renderItem)) //fmt.Println("variable: ", string(renderItem))
variable := renderItem variable := renderItem
// ? - I can probably remove this check now that I've kicked it upstream, or we could keep it here for safety's sake? // ? - I can probably remove this check now that I've kicked it upstream, or we could keep it here for safety's sake?
if len(variable) == 0 { if len(variable) == 0 {
@ -386,7 +386,7 @@ func (hold *MenuListHolder) Build(w io.Writer, user *User) error {
continue continue
} }
if bytes.Equal(variable[fenceStart:dotAt], []byte("me")) { if bytes.Equal(variable[fenceStart:dotAt], []byte("me")) {
fmt.Println("maybe me variable") //fmt.Println("maybe me variable")
w.Write(variable[prevIndex:fenceStart]) w.Write(variable[prevIndex:fenceStart])
switch string(variable[dotAt:fenceEnd]) { switch string(variable[dotAt:fenceEnd]) {
case "Link": case "Link":
@ -397,8 +397,8 @@ func (hold *MenuListHolder) Build(w io.Writer, user *User) error {
prevIndex = fenceEnd prevIndex = fenceEnd
} }
} }
fmt.Println("prevIndex: ", prevIndex) //fmt.Println("prevIndex: ", prevIndex)
fmt.Println("len(variable)-1: ", len(variable)-1) //fmt.Println("len(variable)-1: ", len(variable)-1)
w.Write(variable[prevIndex : len(variable)-1]) w.Write(variable[prevIndex : len(variable)-1])
if len(mTmpl.VariableIndices) > (nearIndex + 1) { if len(mTmpl.VariableIndices) > (nearIndex + 1) {
nearIndex++ nearIndex++

View File

@ -32,6 +32,7 @@ type site struct {
type dbConfig struct { type dbConfig struct {
// Production database // Production database
Adapter string
Host string Host string
Username string Username string
Password string Password string
@ -39,6 +40,7 @@ type dbConfig struct {
Port string Port string
// Test database. Split this into a separate variable? // Test database. Split this into a separate variable?
TestAdapter string
TestHost string TestHost string
TestUsername string TestUsername string
TestPassword string TestPassword string

View File

@ -5,7 +5,6 @@ import (
"bytes" "bytes"
"database/sql" "database/sql"
"encoding/json" "encoding/json"
"fmt"
"html/template" "html/template"
"strings" "strings"
"sync" "sync"
@ -128,18 +127,15 @@ func BuildWidget(dock string, header *Header) (sbody string) {
return sbody return sbody
} }
fmt.Println("dock: ", dock)
switch dock { switch dock {
case "leftOfNav": case "leftOfNav":
widgets = Docks.LeftOfNav widgets = Docks.LeftOfNav
case "rightOfNav": case "rightOfNav":
widgets = Docks.RightOfNav widgets = Docks.RightOfNav
case "topMenu": case "topMenu":
fmt.Println("topMenu")
// 1 = id for the default menu // 1 = id for the default menu
mhold := Menus.Get(1) mhold := Menus.Get(1)
if mhold != nil { if mhold != nil {
fmt.Println("header.Writer: ", header.Writer)
err := mhold.Build(header.Writer, &header.CurrentUser) err := mhold.Build(header.Writer, &header.CurrentUser)
if err != nil { if err != nil {
LogError(err) LogError(err)

View File

@ -40,6 +40,10 @@ cp ./schema/schema.json ./schema/lastSchema.json
git pull origin master git pull origin master
echo "Patching Gosora" echo "Patching Gosora"
rm ./patcher/config.go
cp ./config.go ./patcher/config.go
rm ./patcher/common/site.go
cp ./common/site.go ./patcher/common/site.go
cd ./patcher cd ./patcher
go generate go generate
go build -o Patcher go build -o Patcher

View File

@ -109,6 +109,9 @@ if %errorlevel% neq 0 (
) )
echo Patching Gosora echo Patching Gosora
rem Temporary hack until we switch to JSON or TOML for config files
copy ./config.go ./patcher/config.go
copy ./common/site.go ./patcher/common/site.go
go generate go generate
go build ./patcher go build ./patcher
patcher.exe patcher.exe

View File

@ -114,6 +114,7 @@ func init() {
common.Site.Language = "english" common.Site.Language = "english"
// Database details // Database details
common.DbConfig.Adapter = "` + adap.Name() + `"
common.DbConfig.Host = "` + adap.DBHost() + `" common.DbConfig.Host = "` + adap.DBHost() + `"
common.DbConfig.Username = "` + adap.DBUsername() + `" common.DbConfig.Username = "` + adap.DBUsername() + `"
common.DbConfig.Password = "` + adap.DBPassword() + `" common.DbConfig.Password = "` + adap.DBPassword() + `"
@ -121,10 +122,11 @@ func init() {
common.DbConfig.Port = "` + adap.DBPort() + `" // You probably won't need to change this common.DbConfig.Port = "` + adap.DBPort() + `" // You probably won't need to change this
// Test Database details // Test Database details
common.DbConfig.TestHost = "" common.DbConfig.TestAdapter = "` + adap.Name() + `"
common.DbConfig.TestUsername = "" common.DbConfig.TestHost = ""
common.DbConfig.TestPassword = "" common.DbConfig.TestUsername = ""
common.DbConfig.TestDbname = "" // The name of the test database, leave blank to disable. DON'T USE YOUR PRODUCTION DATABASE FOR THIS. LEAVE BLANK IF YOU DON'T KNOW WHAT THIS MEANS. common.DbConfig.TestPassword = ""
common.DbConfig.TestDbname = "" // The name of the test database, leave blank to disable. DON'T USE YOUR PRODUCTION DATABASE FOR THIS. LEAVE BLANK IF YOU DON'T KNOW WHAT THIS MEANS.
common.DbConfig.TestPort = "" common.DbConfig.TestPort = ""
// Limiters // Limiters

View File

@ -3,7 +3,7 @@
/* /*
* *
* Gosora MySQL Interface * Gosora MySQL Interface
* Copyright Azareal 2016 - 2018 * Copyright Azareal 2016 - 2019
* *
*/ */
package main package main
@ -51,7 +51,6 @@ func initMySQL() (err error) {
} }
// Ready the query builder // Ready the query builder
qgen.Builder.SetConn(db)
err = qgen.Builder.SetAdapter("mysql") err = qgen.Builder.SetAdapter("mysql")
if err != nil { if err != nil {
return err return err

View File

@ -0,0 +1 @@
This file is here so that Git will include this folder in the repository.

View File

@ -4,12 +4,17 @@ import (
"bufio" "bufio"
"database/sql" "database/sql"
"fmt" "fmt"
"log"
"os" "os"
"runtime/debug" "runtime/debug"
"../query_gen/lib" "../query_gen/lib"
"./common"
_ "github.com/go-sql-driver/mysql"
) )
var db *sql.DB
func main() { func main() {
scanner := bufio.NewScanner(os.Stdin) scanner := bufio.NewScanner(os.Stdin)
@ -24,9 +29,27 @@ func main() {
} }
}() }()
err := patcher(scanner) if common.DbConfig != "mysql" && common.DbConfig != "" {
log.Fatal("Only MySQL is supported for upgrades right now, please wait for a newer build of the patcher")
}
err := prepMySQL()
if err != nil { if err != nil {
fmt.Println(err) log.Fatal(err)
}
err = patcher(scanner)
if err != nil {
log.Fatal(err)
}
err = os.Remove("./patcher/config.go")
if err != nil {
log.Fatal(err)
}
err = os.Remove("./patcher/common/site.go")
if err != nil {
log.Fatal(err)
} }
} }
@ -38,7 +61,88 @@ func pressAnyKey(scanner *bufio.Scanner) {
} }
} }
func prepMySQL() error {
err := qgen.Builder.Init("mysql", map[string]string{
"host": common.DbConfig.Host,
"port": common.DbConfig.Port,
"name": common.DbConfig.Dbname,
"username": common.DbConfig.Username,
"password": common.DbConfig.Password,
"collation": "utf8mb4_general_ci",
})
if err != nil {
return err
}
// Ready the query builder
db = qgen.Builder.GetConn()
return qgen.Builder.SetAdapter("mysql")
}
func execStmt(stmt *sql.Stmt, err error) error {
if err != nil {
return err
}
_, err = stmt.Exec()
return err
}
func patcher(scanner *bufio.Scanner) error { func patcher(scanner *bufio.Scanner) error {
err := execStmt(qgen.Builder.CreateTable("menus", "", "",
[]qgen.DBTableColumn{
qgen.DBTableColumn{"mid", "int", 0, false, true, ""},
},
[]qgen.DBTableKey{
qgen.DBTableKey{"mid", "primary"},
},
))
if err != nil {
return err
}
err = execStmt(qgen.Builder.CreateTable("menu_items", "", "",
[]qgen.DBTableColumn{
qgen.DBTableColumn{"mid", "int", 0, false, false, ""},
qgen.DBTableColumn{"htmlID", "varchar", 200, false, false, "''"},
qgen.DBTableColumn{"cssClass", "varchar", 200, false, false, "''"},
qgen.DBTableColumn{"position", "varchar", 100, false, false, ""},
qgen.DBTableColumn{"path", "varchar", 200, false, false, "''"},
qgen.DBTableColumn{"aria", "varchar", 200, false, false, "''"},
qgen.DBTableColumn{"tooltip", "varchar", 200, false, false, "''"},
qgen.DBTableColumn{"tmplName", "varchar", 200, false, false, "''"},
qgen.DBTableColumn{"order", "int", 0, false, false, "0"},
qgen.DBTableColumn{"guestOnly", "boolean", 0, false, false, "0"},
qgen.DBTableColumn{"memberOnly", "boolean", 0, false, false, "0"},
qgen.DBTableColumn{"staffOnly", "boolean", 0, false, false, "0"},
qgen.DBTableColumn{"adminOnly", "boolean", 0, false, false, "0"},
},
[]qgen.DBTableKey{},
))
if err != nil {
return err
}
err = execStmt(qgen.Builder.SimpleInsert("menus", "", ""))
if err != nil {
return err
}
err = execStmt(qgen.Builder.SimpleInsert("menu_items", "mid, htmlID, position, path, aria, tooltip, order", "1,'menu_forums','left','/forums/','{lang.menu_forums_aria}','{lang.menu_forums_tooltip}',0"))
if err != nil {
return err
}
err = execStmt(qgen.Builder.SimpleInsert("menu_items", "mid, htmlID, cssClass, position, path, aria, tooltip, order", "1,'menu_topics','menu_topics','left','/topics/','{lang.menu_topics_aria}','{lang.menu_topics_tooltip}',1"))
if err != nil {
return err
}
stmt, err = execStmt(qgen.Builder.SimpleInsert("menu_items", "mid, htmlID, cssClass, position, tmplName, order", "1,'general_alerts','menu_alerts','right','menu_alerts',2"))
if err != nil {
return err
}
return nil return nil
} }