Reduce boilerplate.

Prealloc in AnalyticsViews.
Remove some old debug code.
Normalise the URL ID error for CreateTopicSubmit.
Reduce the number of allocations for action posts.
Use aliases to shorten a few queries.
This commit is contained in:
Azareal 2019-07-29 09:19:46 +10:00
parent 937c3314ca
commit 377a5dc5ea
8 changed files with 82 additions and 85 deletions

View File

@ -59,12 +59,12 @@ func NewMemoryGroupStore() (*MemoryGroupStore, error) {
}
// TODO: Move this query from the global stmt store into this store
func (mgs *MemoryGroupStore) LoadGroups() error {
mgs.Lock()
defer mgs.Unlock()
mgs.groups[0] = &Group{ID: 0, Name: "Unknown"}
func (s *MemoryGroupStore) LoadGroups() error {
s.Lock()
defer s.Unlock()
s.groups[0] = &Group{ID: 0, Name: "Unknown"}
rows, err := mgs.getAll.Query()
rows, err := s.getAll.Query()
if err != nil {
return err
}
@ -72,26 +72,26 @@ func (mgs *MemoryGroupStore) LoadGroups() error {
i := 1
for ; rows.Next(); i++ {
group := &Group{ID: 0}
err := rows.Scan(&group.ID, &group.Name, &group.PermissionsText, &group.PluginPermsText, &group.IsMod, &group.IsAdmin, &group.IsBanned, &group.Tag)
g := &Group{ID: 0}
err := rows.Scan(&g.ID, &g.Name, &g.PermissionsText, &g.PluginPermsText, &g.IsMod, &g.IsAdmin, &g.IsBanned, &g.Tag)
if err != nil {
return err
}
err = mgs.initGroup(group)
err = s.initGroup(g)
if err != nil {
return err
}
mgs.groups[group.ID] = group
s.groups[g.ID] = g
}
err = rows.Err()
if err != nil {
return err
}
mgs.groupCount = i
s.groupCount = i
DebugLog("Binding the Not Loggedin Group")
GuestPerms = mgs.dirtyGetUnsafe(6).Perms
GuestPerms = s.dirtyGetUnsafe(6).Perms
TopicListThaw.Thaw()
return nil
}
@ -140,26 +140,26 @@ func (s *MemoryGroupStore) GetCopy(gid int) (Group, error) {
func (s *MemoryGroupStore) Reload(id int) error {
// TODO: Reload this data too
group, err := s.Get(id)
g, err := s.Get(id)
if err != nil {
LogError(errors.New("can't get cansee data for group #" + strconv.Itoa(id)))
return nil
}
canSee := group.CanSee
canSee := g.CanSee
group = &Group{ID: id, CanSee: canSee}
err = s.get.QueryRow(id).Scan(&group.Name, &group.PermissionsText, &group.PluginPermsText, &group.IsMod, &group.IsAdmin, &group.IsBanned, &group.Tag)
g = &Group{ID: id, CanSee: canSee}
err = s.get.QueryRow(id).Scan(&g.Name, &g.PermissionsText, &g.PluginPermsText, &g.IsMod, &g.IsAdmin, &g.IsBanned, &g.Tag)
if err != nil {
return err
}
err = s.initGroup(group)
err = s.initGroup(g)
if err != nil {
LogError(err)
return nil
}
s.CacheSet(group)
s.CacheSet(g)
TopicListThaw.Thaw()
return nil
}
@ -227,7 +227,7 @@ func (s *MemoryGroupStore) Exists(gid int) bool {
// ? Allow two groups with the same name?
// TODO: Refactor this
func (s *MemoryGroupStore) Create(name string, tag string, isAdmin bool, isMod bool, isBanned bool) (gid int, err error) {
var permstr = "{}"
permstr := "{}"
tx, err := qgen.Builder.Begin()
if err != nil {
return 0, err
@ -249,10 +249,10 @@ func (s *MemoryGroupStore) Create(name string, tag string, isAdmin bool, isMod b
}
gid = int(gid64)
var perms = BlankPerms
var blankIntList []int
var pluginPerms = make(map[string]bool)
var pluginPermsBytes = []byte("{}")
perms := BlankPerms
blankIntList := []int{}
pluginPerms := make(map[string]bool)
pluginPermsBytes := []byte("{}")
GetHookTable().Vhook("create_group_preappend", &pluginPerms, &pluginPermsBytes)
// Generate the forum permissions based on the presets...
@ -261,8 +261,8 @@ func (s *MemoryGroupStore) Create(name string, tag string, isAdmin bool, isMod b
return 0, err
}
var presetSet = make(map[int]string)
var permSet = make(map[int]*ForumPerms)
presetSet := make(map[int]string)
permSet := make(map[int]*ForumPerms)
for _, forum := range fdata {
var thePreset string
switch {
@ -329,9 +329,9 @@ func (s *MemoryGroupStore) GetAllMap() (map[int]*Group, error) {
// ? - Set the lower and higher numbers to 0 to remove the bounds
// TODO: Might be a little slow right now, maybe we can cache the groups in a slice or break the map up into chunks
func (mgs *MemoryGroupStore) GetRange(lower int, higher int) (groups []*Group, err error) {
func (s *MemoryGroupStore) GetRange(lower int, higher int) (groups []*Group, err error) {
if lower == 0 && higher == 0 {
return mgs.GetAll()
return s.GetAll()
}
// TODO: Simplify these four conditionals into two
@ -345,13 +345,13 @@ func (mgs *MemoryGroupStore) GetRange(lower int, higher int) (groups []*Group, e
}
}
mgs.RLock()
for gid, group := range mgs.groups {
s.RLock()
for gid, group := range s.groups {
if gid >= lower && (gid <= higher || higher == 0) {
groups = append(groups, group)
}
}
mgs.RUnlock()
s.RUnlock()
sort.Sort(SortGroup(groups))
return groups, nil

View File

@ -34,22 +34,22 @@ type MFAItem struct {
Scratch []string
}
func (item *MFAItem) BurnScratch(index int) error {
if index < 0 || len(item.Scratch) <= index {
func (i *MFAItem) BurnScratch(index int) error {
if index < 0 || len(i.Scratch) <= index {
return ErrMFAScratchIndexOutOfBounds
}
newScratch, err := mfaCreateScratch()
if err != nil {
return err
}
item.Scratch[index] = newScratch
i.Scratch[index] = newScratch
_, err = mfaItemStmts.update.Exec(item.Scratch[0], item.Scratch[1], item.Scratch[2], item.Scratch[3], item.Scratch[4], item.Scratch[5], item.Scratch[6], item.Scratch[7], item.UID)
_, err = mfaItemStmts.update.Exec(i.Scratch[0], i.Scratch[1], i.Scratch[2], i.Scratch[3], i.Scratch[4], i.Scratch[5], i.Scratch[6], i.Scratch[7], i.UID)
return err
}
func (item *MFAItem) Delete() error {
_, err := mfaItemStmts.delete.Exec(item.UID)
func (i *MFAItem) Delete() error {
_, err := mfaItemStmts.delete.Exec(i.UID)
return err
}
@ -76,16 +76,16 @@ func NewSQLMFAStore(acc *qgen.Accumulator) (*SQLMFAStore, error) {
}
// TODO: Write a test for this
func (store *SQLMFAStore) Get(id int) (*MFAItem, error) {
item := MFAItem{UID: id, Scratch: make([]string, 8)}
err := store.get.QueryRow(id).Scan(&item.Secret, &item.Scratch[0], &item.Scratch[1], &item.Scratch[2], &item.Scratch[3], &item.Scratch[4], &item.Scratch[5], &item.Scratch[6], &item.Scratch[7])
return &item, err
func (s *SQLMFAStore) Get(id int) (*MFAItem, error) {
i := MFAItem{UID: id, Scratch: make([]string, 8)}
err := s.get.QueryRow(id).Scan(&i.Secret, &i.Scratch[0], &i.Scratch[1], &i.Scratch[2], &i.Scratch[3], &i.Scratch[4], &i.Scratch[5], &i.Scratch[6], &i.Scratch[7])
return &i, err
}
// TODO: Write a test for this
func (store *SQLMFAStore) Create(secret string, uid int) (err error) {
var params = make([]interface{}, 10)
func (s *SQLMFAStore) Create(secret string, uid int) (err error) {
params := make([]interface{}, 10)
params[0] = uid
params[1] = secret
for i := 2; i < len(params); i++ {
@ -96,6 +96,6 @@ func (store *SQLMFAStore) Create(secret string, uid int) (err error) {
params[i] = code
}
_, err = store.create.Exec(params...)
_, err = s.create.Exec(params...)
return err
}

View File

@ -51,8 +51,7 @@ func (reply *ProfileReply) Delete() error {
func (reply *ProfileReply) SetBody(content string) error {
content = PreparseMessage(html.UnescapeString(content))
parsedContent := ParseMessage(content, 0, "")
_, err := profileReplyStmts.edit.Exec(content, parsedContent, reply.ID)
_, err := profileReplyStmts.edit.Exec(content, ParseMessage(content, 0, ""), reply.ID)
return err
}

View File

@ -212,7 +212,7 @@ func init() {
DbInits.Add(func(acc *qgen.Accumulator) error {
topicStmts = TopicStmts{
getRids: acc.Select("replies").Columns("rid").Where("tid = ?").Orderby("rid ASC").Limit("?,?").Prepare(),
getReplies: acc.SimpleLeftJoin("replies", "users", "replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress, replies.likeCount, replies.attachCount, replies.actionType", "replies.createdBy = users.uid", "replies.tid = ?", "replies.rid ASC", "?,?"),
getReplies: acc.SimpleLeftJoin("replies AS r", "users AS u", "r.rid, r.content, r.createdBy, r.createdAt, r.lastEdit, r.lastEditBy, u.avatar, u.name, u.group, u.url_prefix, u.url_name, u.level, r.ipaddress, r.likeCount, r.attachCount, r.actionType", "r.createdBy = u.uid", "r.tid = ?", "r.rid ASC", "?,?"),
addReplies: acc.Update("topics").Set("postCount = postCount + ?, lastReplyBy = ?, lastReplyAt = UTC_TIMESTAMP()").Where("tid = ?").Prepare(),
updateLastReply: acc.Update("topics").Set("lastReplyID = ?").Where("lastReplyID > ? AND tid = ?").Prepare(),
lock: acc.Update("topics").Set("is_closed = 1").Where("tid = ?").Prepare(),
@ -230,8 +230,8 @@ func init() {
setPoll: acc.Update("topics").Set("poll = ?").Where("tid = ? AND poll = 0").Prepare(),
createAction: acc.Insert("replies").Columns("tid, actionType, ipaddress, createdBy, createdAt, lastUpdated, content, parsed_content").Fields("?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),'',''").Prepare(),
getTopicUser: acc.SimpleLeftJoin("topics", "users", "topics.title, topics.content, topics.createdBy, topics.createdAt, topics.lastReplyAt, topics.lastReplyBy, topics.lastReplyID, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.views, topics.postCount, topics.likeCount, topics.attachCount,topics.poll, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level", "topics.createdBy = users.uid", "tid = ?", "", ""),
getByReplyID: acc.SimpleLeftJoin("replies", "topics", "topics.tid, topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.views, topics.postCount, topics.likeCount, topics.poll, topics.data", "replies.tid = topics.tid", "rid = ?", "", ""),
getTopicUser: acc.SimpleLeftJoin("topics AS t", "users AS u", "t.title, t.content, t.createdBy, t.createdAt, t.lastReplyAt, t.lastReplyBy, t.lastReplyID, t.is_closed, t.sticky, t.parentID, t.ipaddress, t.views, t.postCount, t.likeCount, t.attachCount,t.poll, u.name, u.avatar, u.group, u.url_prefix, u.url_name, u.level", "t.createdBy = u.uid", "tid = ?", "", ""),
getByReplyID: acc.SimpleLeftJoin("replies AS r", "topics AS t", "t.tid, t.title, t.content, t.createdBy, t.createdAt, t.is_closed, t.sticky, t.parentID, t.ipaddress, t.views, t.postCount, t.likeCount, t.poll, t.data", "r.tid = t.tid", "rid = ?", "", ""),
}
return acc.FirstError()
})
@ -422,6 +422,11 @@ func GetRidsForTopic(tid int, offset int) (rids []int, err error) {
return rids, rows.Err()
}
var aipost = ";&#xFE0E"
var lockai = "&#x1F512"+aipost
var unlockai = "&#x1F513"
var stickai = "&#x1F4CC"
var unstickai = "&#x1F4CC"+aipost
func (ru *ReplyUser) Init() error {
ru.UserLink = BuildProfileURL(NameToSlug(ru.CreatedByName), ru.CreatedBy)
ru.ContentLines = strings.Count(ru.Content, "\n")
@ -447,16 +452,16 @@ func (ru *ReplyUser) Init() error {
switch aarr[0] {
case "lock":
action = aarr[0]
ru.ActionIcon = "&#x1F512;&#xFE0E"
ru.ActionIcon = lockai
case "unlock":
action = aarr[0]
ru.ActionIcon = "&#x1F513;&#xFE0E"
ru.ActionIcon = unlockai
case "stick":
action = aarr[0]
ru.ActionIcon = "&#x1F4CC;&#xFE0E"
ru.ActionIcon = stickai
case "unstick":
action = aarr[0]
ru.ActionIcon = "&#x1F4CC;&#xFE0E"
ru.ActionIcon = unstickai
case "move":
if len(aarr) == 2 {
fid, _ := strconv.Atoi(aarr[1])

View File

@ -142,27 +142,27 @@ var userStmts UserStmts
func init() {
DbInits.Add(func(acc *qgen.Accumulator) error {
var where = "uid = ?"
var w = "uid = ?"
userStmts = UserStmts{
activate: acc.SimpleUpdate("users", "active = 1", where),
changeGroup: acc.SimpleUpdate("users", "group = ?", where), // TODO: Implement user_count for users_groups here
delete: acc.SimpleDelete("users", where),
setAvatar: acc.Update("users").Set("avatar = ?").Where(where).Prepare(),
setUsername: acc.Update("users").Set("name = ?").Where(where).Prepare(),
incrementTopics: acc.SimpleUpdate("users", "topics = topics + ?", where),
updateLevel: acc.SimpleUpdate("users", "level = ?", where),
update: acc.Update("users").Set("name = ?, email = ?, group = ?").Where("uid = ?").Prepare(), // TODO: Implement user_count for users_groups on things which use this
activate: acc.SimpleUpdate("users", "active = 1", w),
changeGroup: acc.SimpleUpdate("users", "group = ?", w), // TODO: Implement user_count for users_groups here
delete: acc.SimpleDelete("users", w),
setAvatar: acc.Update("users").Set("avatar = ?").Where(w).Prepare(),
setUsername: acc.Update("users").Set("name = ?").Where(w).Prepare(),
incrementTopics: acc.SimpleUpdate("users", "topics = topics + ?", w),
updateLevel: acc.SimpleUpdate("users", "level = ?", w),
update: acc.Update("users").Set("name = ?, email = ?, group = ?").Where(w).Prepare(), // TODO: Implement user_count for users_groups on things which use this
incrementScore: acc.SimpleUpdate("users", "score = score + ?", where),
incrementPosts: acc.SimpleUpdate("users", "posts = posts + ?", where),
incrementBigposts: acc.SimpleUpdate("users", "posts = posts + ?, bigposts = bigposts + ?", where),
incrementMegaposts: acc.SimpleUpdate("users", "posts = posts + ?, bigposts = bigposts + ?, megaposts = megaposts + ?", where),
incrementLiked: acc.SimpleUpdate("users", "liked = liked + ?, lastLiked = UTC_TIMESTAMP()", where),
decrementLiked: acc.SimpleUpdate("users", "liked = liked - ?", where),
incrementScore: acc.SimpleUpdate("users", "score = score + ?", w),
incrementPosts: acc.SimpleUpdate("users", "posts = posts + ?", w),
incrementBigposts: acc.SimpleUpdate("users", "posts = posts + ?, bigposts = bigposts + ?", w),
incrementMegaposts: acc.SimpleUpdate("users", "posts = posts + ?, bigposts = bigposts + ?, megaposts = megaposts + ?", w),
incrementLiked: acc.SimpleUpdate("users", "liked = liked + ?, lastLiked = UTC_TIMESTAMP()", w),
decrementLiked: acc.SimpleUpdate("users", "liked = liked - ?", w),
//recalcLastLiked: acc...
updateLastIP: acc.SimpleUpdate("users", "last_ip = ?", where),
updateLastIP: acc.SimpleUpdate("users", "last_ip = ?", w),
setPassword: acc.Update("users").Set("password = ?, salt = ?").Where(where).Prepare(),
setPassword: acc.Update("users").Set("password = ?, salt = ?").Where(w).Prepare(),
scheduleAvatarResize: acc.Insert("users_avatar_queue").Columns("uid").Fields("?").Prepare(),
}

View File

@ -230,12 +230,13 @@ func AnalyticsViews(w http.ResponseWriter, r *http.Request, user c.User) c.Route
return c.InternalError(err, w, r)
}
var viewList []int64
var viewItems []c.PanelAnalyticsItem
for _, value := range revLabelList {
viewList = append(viewList, viewMap[value])
viewItems = append(viewItems, c.PanelAnalyticsItem{Time: value, Count: viewMap[value]})
viewList := make([]int64,len(revLabelList))
viewItems := make([]c.PanelAnalyticsItem,len(revLabelList))
for i, value := range revLabelList {
viewList[i] = viewMap[value]
viewItems[i] = c.PanelAnalyticsItem{Time: value, Count: viewMap[value]}
}
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
c.DebugLogf("graph: %+v\n", graph)
var ttime string

View File

@ -328,7 +328,7 @@ func CreateTopic(w http.ResponseWriter, r *http.Request, user c.User, header *c.
func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
fid, err := strconv.Atoi(r.PostFormValue("topic-board"))
if err != nil {
return c.LocalError("The provided ForumID is not a valid number.", w, r, user)
return c.LocalError(phrases.GetErrorPhrase("id_must_be_integer"),w,r,user)
}
// TODO: Add hooks to make use of headerLite
lite, ferr := c.SimpleForumUserCheck(w, r, &user, fid)
@ -863,13 +863,11 @@ func addTopicAction(action string, topic *c.Topic, user c.User) error {
// TODO: Refactor this
func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError {
//fmt.Println("i1")
isJs := (r.PostFormValue("isJs") == "1")
tid, err := strconv.Atoi(stid)
if err != nil {
return c.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, isJs)
}
//fmt.Println("i2")
topic, err := c.Topics.Get(tid)
if err == sql.ErrNoRows {
@ -877,7 +875,6 @@ func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
}
//fmt.Println("i3")
// TODO: Add hooks to make use of headerLite
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID)
@ -890,7 +887,6 @@ func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
if topic.CreatedBy == user.ID {
return c.LocalErrorJSQ("You can't like your own topics", w, r, user, isJs)
}
//fmt.Println("i4")
_, err = c.Users.Get(topic.CreatedBy)
if err != nil && err == sql.ErrNoRows {
@ -898,7 +894,6 @@ func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
}
//fmt.Println("i5")
score := 1
err = topic.Like(score, user.ID)
@ -907,7 +902,6 @@ func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
}
//fmt.Println("i6")
// ! Be careful about leaking per-route permission state with &user
alert := c.Alert{ActorID: user.ID, TargetUserID: topic.CreatedBy, Event: "like", ElementType: "topic", ElementID: tid, Actor: &user}
@ -915,13 +909,11 @@ func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
}
//fmt.Println("i7")
skip, rerr := lite.Hooks.VhookSkippable("action_end_like_topic", topic.ID, &user)
if skip || rerr != nil {
return rerr
}
//fmt.Println("i8")
if !isJs {
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)

View File

@ -3,11 +3,11 @@
</div>
<div id="panel_users" class="colstack_item rowlist bgavatars">
{{range .ItemList}}
<div class="rowitem" style="background-image: url('{{.Avatar}}');">
<a class="rowAvatar"{{if $.CurrentUser.Perms.EditUser}} href="/panel/users/edit/{{.ID}}?session={{$.CurrentUser.Session}}"{{end}}>
<div class="rowitem" style="background-image:url('{{.Avatar}}');">
<a class="rowAvatar"{{if $.CurrentUser.Perms.EditUser}} href="/panel/users/edit/{{.ID}}?s={{$.CurrentUser.Session}}"{{end}}>
<img class="bgsub" src="{{.Avatar}}" alt="Avatar" aria-hidden="true" />
</a>
<a class="rowTitle"{{if $.CurrentUser.Perms.EditUser}} href="/panel/users/edit/{{.ID}}?session={{$.CurrentUser.Session}}"{{end}}>{{.Name}}</a>
<a class="rowTitle"{{if $.CurrentUser.Perms.EditUser}} href="/panel/users/edit/{{.ID}}?s={{$.CurrentUser.Session}}"{{end}}>{{.Name}}</a>
<span class="panel_floater">
<a href="{{.Link}}" class="tag-mini profile_url">{{lang "panel_users_profile"}}</a>
{{if (.Tag) and (.IsSuperMod)}}<span class="panel_tag">{{.Tag}}</span></span>{{end}}