From 377a5dc5eac5749edb9e836891365b16d08f7f30 Mon Sep 17 00:00:00 2001 From: Azareal Date: Mon, 29 Jul 2019 09:19:46 +1000 Subject: [PATCH] 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. --- common/group_store.go | 58 +++++++++++++++++++------------------- common/mfa_store.go | 26 ++++++++--------- common/profile_reply.go | 3 +- common/topic.go | 19 ++++++++----- common/user.go | 34 +++++++++++----------- routes/panel/analytics.go | 11 ++++---- routes/topic.go | 10 +------ templates/panel_users.html | 6 ++-- 8 files changed, 82 insertions(+), 85 deletions(-) diff --git a/common/group_store.go b/common/group_store.go index 0f5d7398..0b76c248 100644 --- a/common/group_store.go +++ b/common/group_store.go @@ -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 diff --git a/common/mfa_store.go b/common/mfa_store.go index 2ec5ae31..ba9bd614 100644 --- a/common/mfa_store.go +++ b/common/mfa_store.go @@ -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 } diff --git a/common/profile_reply.go b/common/profile_reply.go index 51b77809..9c78132d 100644 --- a/common/profile_reply.go +++ b/common/profile_reply.go @@ -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 } diff --git a/common/topic.go b/common/topic.go index 7bb68603..4f4f4356 100644 --- a/common/topic.go +++ b/common/topic.go @@ -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 = ";︎" +var lockai = "🔒"+aipost +var unlockai = "🔓" +var stickai = "📌" +var unstickai = "📌"+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 = "🔒︎" + ru.ActionIcon = lockai case "unlock": action = aarr[0] - ru.ActionIcon = "🔓︎" + ru.ActionIcon = unlockai case "stick": action = aarr[0] - ru.ActionIcon = "📌︎" + ru.ActionIcon = stickai case "unstick": action = aarr[0] - ru.ActionIcon = "📌︎" + ru.ActionIcon = unstickai case "move": if len(aarr) == 2 { fid, _ := strconv.Atoi(aarr[1]) diff --git a/common/user.go b/common/user.go index f6997b9c..d50ae1d9 100644 --- a/common/user.go +++ b/common/user.go @@ -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(), } diff --git a/routes/panel/analytics.go b/routes/panel/analytics.go index 0323b992..b4e3daf8 100644 --- a/routes/panel/analytics.go +++ b/routes/panel/analytics.go @@ -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 diff --git a/routes/topic.go b/routes/topic.go index 5b69cdbc..7e7389bf 100644 --- a/routes/topic.go +++ b/routes/topic.go @@ -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) diff --git a/templates/panel_users.html b/templates/panel_users.html index 859561ba..983998bd 100644 --- a/templates/panel_users.html +++ b/templates/panel_users.html @@ -3,11 +3,11 @@
{{range .ItemList}} -
- +
+ - {{.Name}} + {{.Name}} {{lang "panel_users_profile"}} {{if (.Tag) and (.IsSuperMod)}}{{.Tag}}{{end}}