The patcher (schema updating part of the updater) finally works, yay.

Partially rewrote the forum permissions system to make it more stable.

Moved config.go into it's own package in /config/
Removed Go Git as a dependency.
Tweaked the GopherJS pulling.
Fixed inserts where all the columns have default values.
Reverted a silly tweak I made thinking that mOrder == order.
Removed the /common/ hack from the patcher.
Fixed a bug where the forum creator would ignore the visiblity value you provided.
The tests now work again.
Swapped a misplaced fmt.Println with a fmt.Printf.
Fixed a bug in the installer where all the table logs would be on one line in the console.
Added more logging to the installer.
This commit is contained in:
Azareal 2018-04-23 22:08:31 +01:00
parent dbf2b8606e
commit 15420d4d89
30 changed files with 155 additions and 248 deletions

2
.gitignore vendored
View File

@ -20,6 +20,6 @@ out/*
*.log *.log
.DS_Store .DS_Store
.vscode/launch.json .vscode/launch.json
config.go config/config.go
Gosora Gosora
Install Install

View File

@ -6,7 +6,7 @@ before_install:
- cd $HOME - cd $HOME
- git clone https://github.com/Azareal/Gosora - git clone https://github.com/Azareal/Gosora
- cd Gosora - cd Gosora
- mv config_default.noparse config.go - mv config_default.noparse ./config/config.go
- chmod 755 ./update-deps-linux - chmod 755 ./update-deps-linux
- chmod 755 ./dev-update-travis - chmod 755 ./dev-update-travis
- chmod 755 ./run-linux-tests - chmod 755 ./run-linux-tests

View File

@ -120,9 +120,7 @@ go get -u github.com/denisenkom/go-mssqldb
go get -u github.com/fsnotify/fsnotify go get -u github.com/fsnotify/fsnotify
go get -u gopkg.in/src-d/go-git.v4/... go get -u github.com/gopherjs/gopherjs/...
go get -u github.com/gopherjs/gopherjs
go generate go generate

View File

@ -117,7 +117,7 @@ func (forum *Forum) SetPerms(fperms *ForumPerms, preset string, gid int) (err er
if err != nil { if err != nil {
return errors.New("Unable to reload forum") return errors.New("Unable to reload forum")
} }
err = FPStore.ReloadGroup(forum.ID, gid) err = FPStore.Reload(forum.ID)
if err != nil { if err != nil {
return errors.New("Unable to reload the forum permissions") return errors.New("Unable to reload the forum permissions")
} }

View File

@ -14,72 +14,52 @@ type ForumPermsStore interface {
Init() error Init() error
Get(fid int, gid int) (fperms *ForumPerms, err error) Get(fid int, gid int) (fperms *ForumPerms, err error)
GetCopy(fid int, gid int) (fperms ForumPerms, err error) GetCopy(fid int, gid int) (fperms ForumPerms, err error)
ReloadAll() error
Reload(id int) error Reload(id int) error
ReloadGroup(fid int, gid int) error
} }
type ForumPermsCache interface { type ForumPermsCache interface {
} }
type MemoryForumPermsStore struct { type MemoryForumPermsStore struct {
get *sql.Stmt
getByForum *sql.Stmt getByForum *sql.Stmt
getByForumGroup *sql.Stmt getByForumGroup *sql.Stmt
updateMutex sync.Mutex evenForums map[int]map[int]*ForumPerms
oddForums map[int]map[int]*ForumPerms // [fid][gid]*ForumPerms
evenLock sync.RWMutex
oddLock sync.RWMutex
} }
func NewMemoryForumPermsStore() (*MemoryForumPermsStore, error) { func NewMemoryForumPermsStore() (*MemoryForumPermsStore, error) {
acc := qgen.Builder.Accumulator() acc := qgen.Builder.Accumulator()
return &MemoryForumPermsStore{ return &MemoryForumPermsStore{
get: acc.Select("forums_permissions").Columns("gid, fid, permissions").Orderby("gid ASC, fid ASC").Prepare(),
getByForum: acc.Select("forums_permissions").Columns("gid, permissions").Where("fid = ?").Orderby("gid ASC").Prepare(), getByForum: acc.Select("forums_permissions").Columns("gid, permissions").Where("fid = ?").Orderby("gid ASC").Prepare(),
getByForumGroup: acc.Select("forums_permissions").Columns("permissions").Where("fid = ? AND gid = ?").Prepare(), getByForumGroup: acc.Select("forums_permissions").Columns("permissions").Where("fid = ? AND gid = ?").Prepare(),
evenForums: make(map[int]map[int]*ForumPerms),
oddForums: make(map[int]map[int]*ForumPerms),
}, acc.FirstError() }, acc.FirstError()
} }
func (fps *MemoryForumPermsStore) Init() error { func (fps *MemoryForumPermsStore) Init() error {
fps.updateMutex.Lock() DebugLog("Initialising the forum perms store")
defer fps.updateMutex.Unlock() return fps.ReloadAll()
}
func (fps *MemoryForumPermsStore) ReloadAll() error {
DebugLog("Reloading the forum perms")
fids, err := Forums.GetAllIDs() fids, err := Forums.GetAllIDs()
if err != nil { if err != nil {
return err return err
} }
DebugDetail("fids: ", fids) for _, fid := range fids {
err := fps.Reload(fid)
rows, err := fps.get.Query()
if err != nil {
return err
}
defer rows.Close()
DebugLog("Adding the forum permissions")
DebugDetail("forumPerms[gid][fid]")
forumPerms = make(map[int]map[int]*ForumPerms)
for rows.Next() {
var gid, fid int
var perms []byte
err = rows.Scan(&gid, &fid, &perms)
if err != nil { if err != nil {
return err return err
} }
pperms, err := fps.parseForumPerm(perms)
if err != nil {
return err
}
_, ok := forumPerms[gid]
if !ok {
forumPerms[gid] = make(map[int]*ForumPerms)
}
DebugDetail("gid: ", gid)
DebugDetail("fid: ", fid)
DebugDetailf("perms: %+v\n", pperms)
forumPerms[gid][fid] = pperms
} }
return nil
return fps.cascadePermSetToGroups(forumPerms, fids)
} }
func (fps *MemoryForumPermsStore) parseForumPerm(perms []byte) (pperms *ForumPerms, err error) { func (fps *MemoryForumPermsStore) parseForumPerm(perms []byte) (pperms *ForumPerms, err error) {
@ -93,20 +73,14 @@ func (fps *MemoryForumPermsStore) parseForumPerm(perms []byte) (pperms *ForumPer
// TODO: Need a more thread-safe way of doing this. Possibly with sync.Map? // TODO: Need a more thread-safe way of doing this. Possibly with sync.Map?
func (fps *MemoryForumPermsStore) Reload(fid int) error { func (fps *MemoryForumPermsStore) Reload(fid int) error {
fps.updateMutex.Lock()
defer fps.updateMutex.Unlock()
DebugLogf("Reloading the forum permissions for forum #%d", fid) DebugLogf("Reloading the forum permissions for forum #%d", fid)
fids, err := Forums.GetAllIDs()
if err != nil {
return err
}
rows, err := fps.getByForum.Query(fid) rows, err := fps.getByForum.Query(fid)
if err != nil { if err != nil {
return err return err
} }
defer rows.Close() defer rows.Close()
var forumPerms = make(map[int]*ForumPerms)
for rows.Next() { for rows.Next() {
var gid int var gid int
var perms []byte var perms []byte
@ -119,99 +93,104 @@ func (fps *MemoryForumPermsStore) Reload(fid int) error {
if err != nil { if err != nil {
return err return err
} }
_, ok := forumPerms[gid] forumPerms[gid] = pperms
if !ok { }
forumPerms[gid] = make(map[int]*ForumPerms) DebugLogf("forumPerms: %+v\n", forumPerms)
} if fid%2 == 0 {
fps.evenLock.Lock()
forumPerms[gid][fid] = pperms fps.evenForums[fid] = forumPerms
fps.evenLock.Unlock()
} else {
fps.oddLock.Lock()
fps.oddForums[fid] = forumPerms
fps.oddLock.Unlock()
} }
return fps.cascadePermSetToGroups(forumPerms, fids)
}
func (fps *MemoryForumPermsStore) ReloadGroup(fid int, gid int) (err error) {
fps.updateMutex.Lock()
defer fps.updateMutex.Unlock()
var perms []byte
err = fps.getByForumGroup.QueryRow(fid, gid).Scan(&perms)
if err != nil {
return err
}
fperms, err := fps.parseForumPerm(perms)
if err != nil {
return err
}
group, err := Groups.Get(gid)
if err != nil {
return err
}
// TODO: Refactor this
group.Forums[fid] = fperms
return nil
}
func (fps *MemoryForumPermsStore) cascadePermSetToGroups(forumPerms map[int]map[int]*ForumPerms, fids []int) error {
groups, err := Groups.GetAll() groups, err := Groups.GetAll()
if err != nil { if err != nil {
return err return err
} }
fids, err := Forums.GetAllIDs()
if err != nil {
return err
}
for _, group := range groups { for _, group := range groups {
DebugLogf("Updating the forum permissions for Group #%d", group.ID) DebugLogf("Updating the forum permissions for Group #%d", group.ID)
group.Forums = []*ForumPerms{BlankForumPerms()}
group.CanSee = []int{} group.CanSee = []int{}
fps.cascadePermSetToGroup(forumPerms, group, fids) for _, fid := range fids {
DebugDetailf("Forum #%+v\n", fid)
var forumPerms = make(map[int]*ForumPerms)
var ok bool
if fid%2 == 0 {
fps.evenLock.RLock()
forumPerms, ok = fps.evenForums[fid]
fps.evenLock.RUnlock()
} else {
fps.oddLock.RLock()
forumPerms, ok = fps.oddForums[fid]
fps.oddLock.RUnlock()
}
DebugDetailf("group.CanSee (length %d): %+v \n", len(group.CanSee), group.CanSee) var forumPerm *ForumPerms
DebugDetailf("group.Forums (length %d): %+v\n", len(group.Forums), group.Forums) if !ok {
} forumPerm = BlankForumPerms()
return nil } else {
} forumPerm, ok = forumPerms[group.ID]
if !ok {
forumPerm = BlankForumPerms()
}
}
func (fps *MemoryForumPermsStore) cascadePermSetToGroup(forumPerms map[int]map[int]*ForumPerms, group *Group, fids []int) { if forumPerm.Overrides {
for _, fid := range fids { if forumPerm.ViewTopic {
DebugDetailf("Forum #%+v\n", fid) group.CanSee = append(group.CanSee, fid)
forumPerm, ok := forumPerms[group.ID][fid] }
if ok { } else if group.Perms.ViewTopic {
//log.Printf("Overriding permissions for forum #%d",fid)
group.Forums = append(group.Forums, forumPerm)
} else {
//log.Printf("Inheriting from group defaults for forum #%d",fid)
forumPerm = BlankForumPerms()
group.Forums = append(group.Forums, forumPerm)
}
if forumPerm.Overrides {
if forumPerm.ViewTopic {
group.CanSee = append(group.CanSee, fid) group.CanSee = append(group.CanSee, fid)
} }
} else if group.Perms.ViewTopic {
group.CanSee = append(group.CanSee, fid)
}
DebugDetail("group.ID: ", group.ID) DebugDetail("group.ID: ", group.ID)
DebugDetailf("forumPerm: %+v\n", forumPerm) DebugDetailf("forumPerm: %+v\n", forumPerm)
DebugDetail("group.CanSee: ", group.CanSee) DebugDetail("group.CanSee: ", group.CanSee)
}
DebugDetailf("group.CanSee (length %d): %+v \n", len(group.CanSee), group.CanSee)
} }
return nil
} }
// TODO: Add a hook here and have plugin_guilds use it // TODO: Add a hook here and have plugin_guilds use it
// TODO: Check if the forum exists? // TODO: Check if the forum exists?
// TODO: Fix the races // TODO: Fix the races
func (fps *MemoryForumPermsStore) Get(fid int, gid int) (fperms *ForumPerms, err error) { func (fps *MemoryForumPermsStore) Get(fid int, gid int) (fperms *ForumPerms, err error) {
group, err := Groups.Get(gid) var fmap map[int]*ForumPerms
if err != nil { var ok bool
if fid%2 == 0 {
fps.evenLock.RLock()
fmap, ok = fps.evenForums[fid]
fps.evenLock.RUnlock()
} else {
fps.oddLock.RLock()
fmap, ok = fps.oddForums[fid]
fps.oddLock.RUnlock()
}
if !ok {
return fperms, ErrNoRows return fperms, ErrNoRows
} }
return group.Forums[fid], nil
fperms, ok = fmap[gid]
if !ok {
return fperms, ErrNoRows
}
return fperms, nil
} }
// TODO: Check if the forum exists? // TODO: Check if the forum exists?
// TODO: Fix the races // TODO: Fix the races
func (fps *MemoryForumPermsStore) GetCopy(fid int, gid int) (fperms ForumPerms, err error) { func (fps *MemoryForumPermsStore) GetCopy(fid int, gid int) (fperms ForumPerms, err error) {
group, err := Groups.Get(gid) fPermsPtr, err := fps.Get(fid, gid)
if err != nil { if err != nil {
return fperms, ErrNoRows return fperms, err
} }
return *group.Forums[fid], nil return *fPermsPtr, nil
} }

View File

@ -26,7 +26,6 @@ type Group struct {
PermissionsText []byte PermissionsText []byte
PluginPerms map[string]bool // Custom permissions defined by plugins. What if two plugins declare the same permission, but they handle them in incompatible ways? Very unlikely, we probably don't need to worry about this, the plugin authors should be aware of each other to some extent PluginPerms map[string]bool // Custom permissions defined by plugins. What if two plugins declare the same permission, but they handle them in incompatible ways? Very unlikely, we probably don't need to worry about this, the plugin authors should be aware of each other to some extent
PluginPermsText []byte PluginPermsText []byte
Forums []*ForumPerms
CanSee []int // The IDs of the forums this group can see CanSee []int // The IDs of the forums this group can see
UserCount int // ! Might be temporary as I might want to lean on the database instead for this UserCount int // ! Might be temporary as I might want to lean on the database instead for this
} }

View File

@ -226,7 +226,6 @@ func (mgs *MemoryGroupStore) Create(name string, tag string, isAdmin bool, isMod
gid = int(gid64) gid = int(gid64)
var perms = BlankPerms var perms = BlankPerms
var blankForums []*ForumPerms
var blankIntList []int var blankIntList []int
var pluginPerms = make(map[string]bool) var pluginPerms = make(map[string]bool)
var pluginPermsBytes = []byte("{}") var pluginPermsBytes = []byte("{}")
@ -277,15 +276,13 @@ func (mgs *MemoryGroupStore) Create(name string, tag string, isAdmin bool, isMod
} }
mgs.Lock() mgs.Lock()
mgs.groups[gid] = &Group{gid, name, isMod, isAdmin, isBanned, tag, perms, []byte(permstr), pluginPerms, pluginPermsBytes, blankForums, blankIntList, 0} mgs.groups[gid] = &Group{gid, name, isMod, isAdmin, isBanned, tag, perms, []byte(permstr), pluginPerms, pluginPermsBytes, blankIntList, 0}
mgs.groupCount++ mgs.groupCount++
mgs.Unlock() mgs.Unlock()
for _, forum := range fdata { err = FPStore.ReloadAll()
err = FPStore.Reload(forum.ID) if err != nil {
if err != nil { return gid, err
return gid, err
}
} }
return gid, nil return gid, nil

View File

@ -28,11 +28,8 @@ go get -u github.com/bamiaux/rez
echo "Updating fsnotify" echo "Updating fsnotify"
go get -u github.com/fsnotify/fsnotify go get -u github.com/fsnotify/fsnotify
echo "Updating Go Git"
go get -u gopkg.in/src-d/go-git.v4/...
echo "Updating GopherJS" echo "Updating GopherJS"
go get -u github.com/gopherjs/gopherjs go get -u github.com/gopherjs/gopherjs/...
echo "Updating Gosora" echo "Updating Gosora"
rm ./schema/lastSchema.json rm ./schema/lastSchema.json
@ -40,10 +37,6 @@ 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

@ -1,9 +1,5 @@
echo "Building the patcher" echo "Building the patcher"
cp ./schema/schema.json ./schema/lastSchema.json cp ./schema/schema.json ./schema/lastSchema.json
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

@ -85,15 +85,8 @@ if %errorlevel% neq 0 (
exit /b %errorlevel% exit /b %errorlevel%
) )
echo Updating Go Git
go get -u gopkg.in/src-d/go-git.v4/...
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Updating GopherJS echo Updating GopherJS
go get -u github.com/gopherjs/gopherjs go get -u github.com/gopherjs/gopherjs/...
if %errorlevel% neq 0 ( if %errorlevel% neq 0 (
pause pause
exit /b %errorlevel% exit /b %errorlevel%
@ -109,9 +102,6 @@ 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

@ -13,6 +13,7 @@ import (
"time" "time"
"./common" "./common"
"./config"
"./install/install" "./install/install"
"./query_gen/lib" "./query_gen/lib"
"./routes" "./routes"
@ -87,6 +88,7 @@ func gloinit() (err error) {
} }
func init() { func init() {
config.Config()
err := gloinit() err := gloinit()
if err != nil { if err != nil {
log.Print("Something bad happened") log.Print("Something bad happened")

View File

@ -28,11 +28,8 @@ go get -u github.com/bamiaux/rez
echo "Installing fsnotify" echo "Installing fsnotify"
go get -u github.com/fsnotify/fsnotify go get -u github.com/fsnotify/fsnotify
echo "Installing Go Git"
go get -u gopkg.in/src-d/go-git.v4/...
echo "Installing GopherJS" echo "Installing GopherJS"
go get -u github.com/gopherjs/gopherjs go get -u github.com/gopherjs/gopherjs/...
echo "Building the installer" echo "Building the installer"
cd ./install cd ./install

View File

@ -85,15 +85,8 @@ if %errorlevel% neq 0 (
exit /b %errorlevel% exit /b %errorlevel%
) )
echo Installing Go Git
go get -u gopkg.in/src-d/go-git.v4/...
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Installing GopherJS echo Installing GopherJS
go get -u github.com/gopherjs/gopherjs go get -u github.com/gopherjs/gopherjs/...
if %errorlevel% neq 0 ( if %errorlevel% neq 0 (
pause pause
exit /b %errorlevel% exit /b %errorlevel%

View File

@ -13,6 +13,7 @@ import (
"os" "os"
"runtime/debug" "runtime/debug"
"strconv" "strconv"
"strings"
"./install" "./install"
) )
@ -95,11 +96,11 @@ func main() {
return return
} }
configContents := []byte(`package main configContents := []byte(`package config
import "./common" import "../common"
func init() { func Config() {
// Site Info // Site Info
common.Site.ShortName = "` + siteShortName + `" // This should be less than three letters to fit in the navbar common.Site.ShortName = "` + siteShortName + `" // This should be less than three letters to fit in the navbar
common.Site.Name = "` + siteName + `" common.Site.Name = "` + siteName + `"
@ -167,7 +168,7 @@ func init() {
`) `)
fmt.Println("Opening the configuration file") fmt.Println("Opening the configuration file")
configFile, err := os.Create("./config.go") configFile, err := os.Create("./config/config.go")
if err != nil { if err != nil {
abortError(err) abortError(err)
return return
@ -209,7 +210,7 @@ func handleDatabaseDetails() (adap install.InstallAdapter, ok bool) {
if !scanner.Scan() { if !scanner.Scan() {
return nil, false return nil, false
} }
dbAdapter := scanner.Text() dbAdapter := strings.TrimSpace(scanner.Text())
if dbAdapter == "" { if dbAdapter == "" {
dbAdapter = defaultAdapter dbAdapter = defaultAdapter
} }

View File

@ -1,6 +1,8 @@
package install package install
import ( import (
"fmt"
"../../query_gen/lib" "../../query_gen/lib"
) )
@ -28,6 +30,7 @@ func Lookup(name string) (InstallAdapter, bool) {
} }
func createAdmin() error { func createAdmin() error {
fmt.Println("Creating the admin user")
hashedPassword, salt, err := BcryptGeneratePassword("password") hashedPassword, salt, err := BcryptGeneratePassword("password")
if err != nil { if err != nil {
return err return err

View File

@ -105,7 +105,7 @@ func (ins *MysqlInstaller) InitDatabase() (err error) {
} }
func (ins *MysqlInstaller) TableDefs() (err error) { func (ins *MysqlInstaller) TableDefs() (err error) {
//fmt.Println("Creating the tables") fmt.Println("Creating the tables")
files, _ := ioutil.ReadDir("./schema/mysql/") files, _ := ioutil.ReadDir("./schema/mysql/")
for _, f := range files { for _, f := range files {
if !strings.HasPrefix(f.Name(), "query_") { if !strings.HasPrefix(f.Name(), "query_") {
@ -127,7 +127,7 @@ func (ins *MysqlInstaller) TableDefs() (err error) {
return err return err
} }
fmt.Printf("Creating table '%s'", table) fmt.Printf("Creating table '%s'\n", table)
data, err := ioutil.ReadFile("./schema/mysql/" + f.Name()) data, err := ioutil.ReadFile("./schema/mysql/" + f.Name())
if err != nil { if err != nil {
return err return err
@ -148,7 +148,7 @@ func (ins *MysqlInstaller) TableDefs() (err error) {
/*INSERT INTO settings(`name`,`content`,`type`) VALUES ('meta_desc','','html-attribute');*/ /*INSERT INTO settings(`name`,`content`,`type`) VALUES ('meta_desc','','html-attribute');*/
func (ins *MysqlInstaller) InitialData() error { func (ins *MysqlInstaller) InitialData() error {
//fmt.Println("Seeding the tables") fmt.Println("Seeding the tables")
data, err := ioutil.ReadFile("./schema/mysql/inserts.sql") data, err := ioutil.ReadFile("./schema/mysql/inserts.sql")
if err != nil { if err != nil {
return err return err
@ -156,13 +156,15 @@ func (ins *MysqlInstaller) InitialData() error {
data = bytes.TrimSpace(data) data = bytes.TrimSpace(data)
statements := bytes.Split(data, []byte(";")) statements := bytes.Split(data, []byte(";"))
for key, statement := range statements { for key, sBytes := range statements {
if len(statement) == 0 { statement := string(sBytes)
if statement == "" {
continue continue
} }
statement += ";"
fmt.Println("Executing query #" + strconv.Itoa(key) + " " + string(statement)) fmt.Println("Executing query #" + strconv.Itoa(key) + " " + statement)
_, err = ins.db.Exec(string(statement)) _, err = ins.db.Exec(statement)
if err != nil { if err != nil {
return err return err
} }

View File

@ -21,6 +21,7 @@ import (
"./common" "./common"
"./common/counters" "./common/counters"
"./config"
"github.com/fsnotify/fsnotify" "github.com/fsnotify/fsnotify"
) )
@ -78,7 +79,7 @@ func afterDBInit() (err error) {
return err return err
} }
menuHold := common.Menus.Get(1) menuHold := common.Menus.Get(1)
fmt.Println("menuHold: %+v", menuHold) fmt.Printf("menuHold: %+v\n", menuHold)
var b bytes.Buffer var b bytes.Buffer
menuHold.Build(&b, &common.GuestUser) menuHold.Build(&b, &common.GuestUser)
fmt.Println("menuHold output: ", string(b.Bytes())) fmt.Println("menuHold output: ", string(b.Bytes()))
@ -192,6 +193,7 @@ func main() {
} }
log.Printf("tagIndices: %+v\n", tagIndices) log.Printf("tagIndices: %+v\n", tagIndices)
log.Fatal("")*/ log.Fatal("")*/
config.Config()
// TODO: Have a file for each run with the time/date the server started as the file name? // TODO: Have a file for each run with the time/date the server started as the file name?
// TODO: Log panics with recover() // TODO: Log panics with recover()

View File

@ -537,7 +537,7 @@ func topicStoreTest(t *testing.T) {
recordMustExist(t, err, "Couldn't find TID #1") recordMustExist(t, err, "Couldn't find TID #1")
if topic.ID != 1 { if topic.ID != 1 {
t.Error("topic.ID does not match the requested TID. Got '%d' instead.", topic.ID) t.Errorf("topic.ID does not match the requested TID. Got '%d' instead.", topic.ID)
} }
// TODO: Add BulkGetMap() to the TopicStore // TODO: Add BulkGetMap() to the TopicStore
@ -578,7 +578,7 @@ func TestForumStore(t *testing.T) {
recordMustExist(t, err, "Couldn't find FID #1") recordMustExist(t, err, "Couldn't find FID #1")
if forum.ID != 1 { if forum.ID != 1 {
t.Error("forum.ID doesn't not match the requested FID. Got '%d' instead.'", forum.ID) t.Errorf("forum.ID doesn't not match the requested FID. Got '%d' instead.'", forum.ID)
} }
// TODO: Check the preset and forum permissions // TODO: Check the preset and forum permissions
expect(t, forum.Name == "Reports", fmt.Sprintf("FID #0 is named '%s' and not 'Reports'", forum.Name)) expect(t, forum.Name == "Reports", fmt.Sprintf("FID #0 is named '%s' and not 'Reports'", forum.Name))
@ -618,7 +618,7 @@ func TestForumStore(t *testing.T) {
expect(t, forum.ID == 2, fmt.Sprintf("The FID should be 3 not %d", forum.ID)) expect(t, forum.ID == 2, fmt.Sprintf("The FID should be 3 not %d", forum.ID))
expect(t, forum.Name == "Test Forum", fmt.Sprintf("The name of the forum should be 'Test Forum' not '%s'", forum.Name)) expect(t, forum.Name == "Test Forum", fmt.Sprintf("The name of the forum should be 'Test Forum' not '%s'", forum.Name))
expect(t, forum.Active, fmt.Sprintf("The test forum should be active")) expect(t, forum.Active, fmt.Sprintf("The test forum should be active"))
expect(t, forum.Desc == "", fmt.Sprintf("The forum description should be blank not '%s'", expectDesc, forum.Desc)) expect(t, forum.Desc == "", fmt.Sprintf("The forum description should be blank not '%s'", forum.Desc))
// TODO: More forum creation tests // TODO: More forum creation tests
// TODO: Test forum deletion // TODO: Test forum deletion

View File

@ -85,15 +85,8 @@ if %errorlevel% neq 0 (
exit /b %errorlevel% exit /b %errorlevel%
) )
echo Updating Go Git
go get -u gopkg.in/src-d/go-git.v4/...
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Updating GopherJS echo Updating GopherJS
go get -u github.com/gopherjs/gopherjs go get -u github.com/gopherjs/gopherjs/...
if %errorlevel% neq 0 ( if %errorlevel% neq 0 (
pause pause
exit /b %errorlevel% exit /b %errorlevel%

View File

@ -222,7 +222,7 @@ func routePanelForumsCreateSubmit(w http.ResponseWriter, r *http.Request, user c
fname := r.PostFormValue("forum-name") fname := r.PostFormValue("forum-name")
fdesc := r.PostFormValue("forum-desc") fdesc := r.PostFormValue("forum-desc")
fpreset := common.StripInvalidPreset(r.PostFormValue("forum-preset")) fpreset := common.StripInvalidPreset(r.PostFormValue("forum-preset"))
factive := r.PostFormValue("forum-name") factive := r.PostFormValue("forum-active")
active := (factive == "on" || factive == "1") active := (factive == "on" || factive == "1")
_, err := common.Forums.Create(fname, fdesc, active, fpreset) _, err := common.Forums.Create(fname, fdesc, active, fpreset)
@ -331,8 +331,11 @@ func routePanelForumsEdit(w http.ResponseWriter, r *http.Request, user common.Us
if gid == 0 { if gid == 0 {
continue continue
} }
// TODO: Don't access the cache on the group directly forumPerms, err := common.FPStore.Get(fid, group.ID)
gplist = append(gplist, common.GroupForumPermPreset{group, common.ForumPermsToGroupForumPreset(group.Forums[fid])}) if err != nil {
return common.InternalError(err, w, r)
}
gplist = append(gplist, common.GroupForumPermPreset{group, common.ForumPermsToGroupForumPreset(forumPerms)})
} }
if r.FormValue("updated") == "1" { if r.FormValue("updated") == "1" {

View File

@ -10,8 +10,9 @@ import (
"os" "os"
"runtime/debug" "runtime/debug"
"../common"
"../config"
"../query_gen/lib" "../query_gen/lib"
"./common"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
) )
@ -29,7 +30,8 @@ func main() {
} }
}() }()
if common.DbConfig != "mysql" && common.DbConfig != "" { config.Config()
if common.DbConfig.Adapter != "mysql" && common.DbConfig.Adapter != "" {
log.Fatal("Only MySQL is supported for upgrades right now, please wait for a newer build of the patcher") log.Fatal("Only MySQL is supported for upgrades right now, please wait for a newer build of the patcher")
} }
@ -42,15 +44,6 @@ func main() {
if err != nil { if err != nil {
log.Fatal(err) 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)
}
} }
func pressAnyKey(scanner *bufio.Scanner) { func pressAnyKey(scanner *bufio.Scanner) {
@ -73,8 +66,8 @@ func prepMySQL() error {
} }
type SchemaFile struct { type SchemaFile struct {
DBVersion int // Current version of the database schema DBVersion string // Current version of the database schema
DynamicFileVersion int DynamicFileVersion string
MinGoVersion string // TODO: Minimum version of Go needed to install this version 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 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
} }
@ -85,7 +78,7 @@ func patcher(scanner *bufio.Scanner) error {
return err return err
} }
var schemaFile LanguagePack var schemaFile SchemaFile
err = json.Unmarshal(data, &schemaFile) err = json.Unmarshal(data, &schemaFile)
if err != nil { if err != nil {
return err return err

View File

@ -48,12 +48,12 @@ func patch0(scanner *bufio.Scanner) error {
return err return err
} }
var mOrder int var order int
var mOrder = "mid, htmlID, cssClass, position, path, aria, tooltip, guestOnly, memberOnly, staffOnly, adminOnly" var mOrder = "mid, htmlID, cssClass, position, path, aria, tooltip, guestOnly, memberOnly, staffOnly, adminOnly"
var addMenuItem = func(data map[string]interface{}) error { var addMenuItem = func(data map[string]interface{}) error {
cols, values := qgen.InterfaceMapToInsertStrings(data, mOrder) cols, values := qgen.InterfaceMapToInsertStrings(data, mOrder)
err := execStmt(qgen.Builder.SimpleInsert("menu_items", cols+", order", values+","+strconv.Itoa(mOrder))) err := execStmt(qgen.Builder.SimpleInsert("menu_items", cols+", order", values+","+strconv.Itoa(order)))
mOrder++ order++
return err return err
} }

View File

@ -136,12 +136,12 @@ func (adapter *MssqlAdapter) SimpleInsert(name string, table string, columns str
return "", errors.New("You need a name for this table") return "", errors.New("You need a name for this table")
} }
var querystr = "INSERT INTO [" + table + "]" var querystr = "INSERT INTO [" + table + "] ("
if columns == "" { if columns == "" {
querystr += ") VALUES ()"
adapter.pushStatement(name, "insert", querystr) adapter.pushStatement(name, "insert", querystr)
return querystr, nil return querystr, nil
} }
querystr += " ("
// Escape the column names, just in case we've used a reserved keyword // Escape the column names, just in case we've used a reserved keyword
for _, column := range processColumns(columns) { for _, column := range processColumns(columns) {

View File

@ -144,9 +144,9 @@ func (adapter *MysqlAdapter) SimpleInsert(name string, table string, columns str
return "", errors.New("You need a name for this table") return "", errors.New("You need a name for this table")
} }
var querystr = "INSERT INTO `" + table + "`" var querystr = "INSERT INTO `" + table + "`("
if columns != "" { if columns != "" {
querystr += "(" + adapter.buildColumns(columns) + ") VALUES (" querystr += adapter.buildColumns(columns) + ") VALUES ("
for _, field := range processFields(fields) { for _, field := range processFields(fields) {
nameLen := len(field.Name) nameLen := len(field.Name)
if field.Name[0] == '"' && field.Name[nameLen-1] == '"' && nameLen >= 3 { if field.Name[0] == '"' && field.Name[nameLen-1] == '"' && nameLen >= 3 {
@ -157,8 +157,11 @@ func (adapter *MysqlAdapter) SimpleInsert(name string, table string, columns str
} }
querystr += field.Name + "," querystr += field.Name + ","
} }
querystr = querystr[0:len(querystr)-1] + ")" querystr = querystr[0 : len(querystr)-1]
} else {
querystr += ") VALUES ("
} }
querystr += ")"
adapter.pushStatement(name, "insert", querystr) adapter.pushStatement(name, "insert", querystr)
return querystr, nil return querystr, nil

View File

@ -225,36 +225,9 @@ func seedTables(adapter qgen.Adapter) error {
qgen.Install.SimpleInsert("menus", "", "") qgen.Install.SimpleInsert("menus", "", "")
// Go maps have a random iteration order, so we have to do this, otherwise the schema files will become unstable and harder to audit
var order = 0 var order = 0
var mOrder = "mid, htmlID, cssClass, position, path, aria, tooltip, guestOnly, memberOnly, staffOnly, adminOnly" var mOrder = "mid, htmlID, cssClass, position, path, aria, tooltip, guestOnly, memberOnly, staffOnly, adminOnly"
/*var addMenuItem = func(data map[string]interface{}) {
var cols, values string
for col, value := range data {
cols += col + ","
switch value := value.(type) {
case string:
values += "'" + strings.Replace(value, "'", "\\'", -1) + "',"
case int:
values += strconv.Itoa(value) + ","
case LitStr:
values += string(value) + ","
case bool:
if value {
values += "1,"
} else {
values += "0,"
}
}
}
if cols != "" {
cols = cols[:len(cols)-1]
values = values[:len(values)-1]
}
qgen.Install.SimpleInsert("menu_items", cols+", order", values+","+strconv.Itoa(order))
order++
}*/
// Go maps have a random iteration order, so we have to do this, otherwise the schema files will become unstable and harder to audit
var addMenuItem = func(data map[string]interface{}) { var addMenuItem = func(data map[string]interface{}) {
cols, values := qgen.InterfaceMapToInsertStrings(data, mOrder) cols, values := qgen.InterfaceMapToInsertStrings(data, mOrder)
qgen.Install.SimpleInsert("menu_items", cols+", order", values+","+strconv.Itoa(order)) qgen.Install.SimpleInsert("menu_items", cols+", order", values+","+strconv.Itoa(order))

View File

@ -28,7 +28,7 @@ INSERT INTO [forums_permissions] ([gid],[fid],[permissions]) VALUES (5,2,'{"View
INSERT INTO [forums_permissions] ([gid],[fid],[permissions]) VALUES (6,2,'{"ViewTopic":true}'); INSERT INTO [forums_permissions] ([gid],[fid],[permissions]) VALUES (6,2,'{"ViewTopic":true}');
INSERT INTO [topics] ([title],[content],[parsed_content],[createdAt],[lastReplyAt],[lastReplyBy],[createdBy],[parentID],[ipaddress]) VALUES ('Test Topic','A topic automatically generated by the software.','A topic automatically generated by the software.',GETUTCDATE(),GETUTCDATE(),1,1,2,'::1'); INSERT INTO [topics] ([title],[content],[parsed_content],[createdAt],[lastReplyAt],[lastReplyBy],[createdBy],[parentID],[ipaddress]) VALUES ('Test Topic','A topic automatically generated by the software.','A topic automatically generated by the software.',GETUTCDATE(),GETUTCDATE(),1,1,2,'::1');
INSERT INTO [replies] ([tid],[content],[parsed_content],[createdAt],[createdBy],[lastUpdated],[lastEdit],[lastEditBy],[ipaddress]) VALUES (1,'A reply!','A reply!',GETUTCDATE(),1,GETUTCDATE(),0,0,'::1'); INSERT INTO [replies] ([tid],[content],[parsed_content],[createdAt],[createdBy],[lastUpdated],[lastEdit],[lastEditBy],[ipaddress]) VALUES (1,'A reply!','A reply!',GETUTCDATE(),1,GETUTCDATE(),0,0,'::1');
INSERT INTO [menus]; INSERT INTO [menus] () VALUES ();
INSERT INTO [menu_items] ([mid],[htmlID],[position],[path],[aria],[tooltip],[order]) VALUES (1,'menu_forums','left','/forums/','{lang.menu_forums_aria}','{lang.menu_forums_tooltip}',0); INSERT INTO [menu_items] ([mid],[htmlID],[position],[path],[aria],[tooltip],[order]) VALUES (1,'menu_forums','left','/forums/','{lang.menu_forums_aria}','{lang.menu_forums_tooltip}',0);
INSERT INTO [menu_items] ([mid],[htmlID],[cssClass],[position],[path],[aria],[tooltip],[order]) VALUES (1,'menu_topics','menu_topics','left','/topics/','{lang.menu_topics_aria}','{lang.menu_topics_tooltip}',1); INSERT INTO [menu_items] ([mid],[htmlID],[cssClass],[position],[path],[aria],[tooltip],[order]) VALUES (1,'menu_topics','menu_topics','left','/topics/','{lang.menu_topics_aria}','{lang.menu_topics_tooltip}',1);
INSERT INTO [menu_items] ([mid],[htmlID],[cssClass],[position],[tmplName],[order]) VALUES (1,'general_alerts','menu_alerts','right','menu_alerts',2); INSERT INTO [menu_items] ([mid],[htmlID],[cssClass],[position],[tmplName],[order]) VALUES (1,'general_alerts','menu_alerts','right','menu_alerts',2);

View File

@ -28,7 +28,7 @@ INSERT INTO `forums_permissions`(`gid`,`fid`,`permissions`) VALUES (5,2,'{"ViewT
INSERT INTO `forums_permissions`(`gid`,`fid`,`permissions`) VALUES (6,2,'{"ViewTopic":true}'); INSERT INTO `forums_permissions`(`gid`,`fid`,`permissions`) VALUES (6,2,'{"ViewTopic":true}');
INSERT INTO `topics`(`title`,`content`,`parsed_content`,`createdAt`,`lastReplyAt`,`lastReplyBy`,`createdBy`,`parentID`,`ipaddress`) VALUES ('Test Topic','A topic automatically generated by the software.','A topic automatically generated by the software.',UTC_TIMESTAMP(),UTC_TIMESTAMP(),1,1,2,'::1'); INSERT INTO `topics`(`title`,`content`,`parsed_content`,`createdAt`,`lastReplyAt`,`lastReplyBy`,`createdBy`,`parentID`,`ipaddress`) VALUES ('Test Topic','A topic automatically generated by the software.','A topic automatically generated by the software.',UTC_TIMESTAMP(),UTC_TIMESTAMP(),1,1,2,'::1');
INSERT INTO `replies`(`tid`,`content`,`parsed_content`,`createdAt`,`createdBy`,`lastUpdated`,`lastEdit`,`lastEditBy`,`ipaddress`) VALUES (1,'A reply!','A reply!',UTC_TIMESTAMP(),1,UTC_TIMESTAMP(),0,0,'::1'); INSERT INTO `replies`(`tid`,`content`,`parsed_content`,`createdAt`,`createdBy`,`lastUpdated`,`lastEdit`,`lastEditBy`,`ipaddress`) VALUES (1,'A reply!','A reply!',UTC_TIMESTAMP(),1,UTC_TIMESTAMP(),0,0,'::1');
INSERT INTO `menus`; INSERT INTO `menus`() VALUES ();
INSERT INTO `menu_items`(`mid`,`htmlID`,`position`,`path`,`aria`,`tooltip`,`order`) VALUES (1,'menu_forums','left','/forums/','{lang.menu_forums_aria}','{lang.menu_forums_tooltip}',0); INSERT INTO `menu_items`(`mid`,`htmlID`,`position`,`path`,`aria`,`tooltip`,`order`) VALUES (1,'menu_forums','left','/forums/','{lang.menu_forums_aria}','{lang.menu_forums_tooltip}',0);
INSERT INTO `menu_items`(`mid`,`htmlID`,`cssClass`,`position`,`path`,`aria`,`tooltip`,`order`) VALUES (1,'menu_topics','menu_topics','left','/topics/','{lang.menu_topics_aria}','{lang.menu_topics_tooltip}',1); INSERT INTO `menu_items`(`mid`,`htmlID`,`cssClass`,`position`,`path`,`aria`,`tooltip`,`order`) VALUES (1,'menu_topics','menu_topics','left','/topics/','{lang.menu_topics_aria}','{lang.menu_topics_tooltip}',1);
INSERT INTO `menu_items`(`mid`,`htmlID`,`cssClass`,`position`,`tmplName`,`order`) VALUES (1,'general_alerts','menu_alerts','right','menu_alerts',2); INSERT INTO `menu_items`(`mid`,`htmlID`,`cssClass`,`position`,`tmplName`,`order`) VALUES (1,'general_alerts','menu_alerts','right','menu_alerts',2);

View File

@ -28,8 +28,5 @@ go get -u github.com/bamiaux/rez
echo "Updating fsnotify" echo "Updating fsnotify"
go get -u github.com/fsnotify/fsnotify go get -u github.com/fsnotify/fsnotify
echo "Updating Go Git"
go get -u gopkg.in/src-d/go-git.v4/...
echo "Updating GopherJS" echo "Updating GopherJS"
go get -u github.com/gopherjs/gopherjs go get -u github.com/gopherjs/gopherjs/...

View File

@ -82,15 +82,8 @@ if %errorlevel% neq 0 (
exit /b %errorlevel% exit /b %errorlevel%
) )
echo Updating Go Git
go get -u gopkg.in/src-d/go-git.v4/...
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Updating GopherJS echo Updating GopherJS
go get -u github.com/gopherjs/gopherjs go get -u github.com/gopherjs/gopherjs/...
if %errorlevel% neq 0 ( if %errorlevel% neq 0 (
pause pause
exit /b %errorlevel% exit /b %errorlevel%