gosora/common/reply_store.go
Azareal ea1037bd63 track favicon stats
experiment with tracking average route performance
temporary error route stub
optimise dumprequest
add DisableAnalytics config setting
fix double hyphens in slugs being mistaken for sql injection
more querygen tests

You wil need to run the updater / patcher for this commit.
2020-02-26 20:34:38 +10:00

139 lines
3.8 KiB
Go

package common
//import "log"
import (
"database/sql"
qgen "github.com/Azareal/Gosora/query_gen"
)
var Rstore ReplyStore
type ReplyStore interface {
Get(id int) (*Reply, error)
Each(f func(*Reply) error) error
Exists(id int) bool
Create(t *Topic, content, ip string, uid int) (id int, err error)
Count() (count int)
CountUser(uid int) (count int)
CountMegaUser(uid int) (count int)
CountBigUser(uid int) (count int)
SetCache(cache ReplyCache)
GetCache() ReplyCache
}
type SQLReplyStore struct {
cache ReplyCache
get *sql.Stmt
getAll *sql.Stmt
exists *sql.Stmt
create *sql.Stmt
count *sql.Stmt
countUser *sql.Stmt
countWordUser *sql.Stmt
}
func NewSQLReplyStore(acc *qgen.Accumulator, cache ReplyCache) (*SQLReplyStore, error) {
if cache == nil {
cache = NewNullReplyCache()
}
re := "replies"
return &SQLReplyStore{
cache: cache,
get: acc.Select(re).Columns("tid, content, createdBy, createdAt, lastEdit, lastEditBy, ip, likeCount, attachCount, actionType").Where("rid=?").Prepare(),
getAll: acc.Select(re).Columns("rid,tid, content, createdBy, createdAt, lastEdit, lastEditBy, ip, likeCount, attachCount, actionType").Prepare(),
exists: acc.Exists(re, "rid").Prepare(),
create: acc.Insert(re).Columns("tid, content, parsed_content, createdAt, lastUpdated, ip, words, createdBy").Fields("?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?").Prepare(),
count: acc.Count(re).Prepare(),
countUser: acc.Count(re).Where("createdBy=?").Prepare(),
countWordUser: acc.Count(re).Where("createdBy=? AND words>=?").Prepare(),
}, acc.FirstError()
}
func (s *SQLReplyStore) Get(id int) (*Reply, error) {
r, err := s.cache.Get(id)
if err == nil {
return r, nil
}
r = &Reply{ID: id}
err = s.get.QueryRow(id).Scan(&r.ParentID, &r.Content, &r.CreatedBy, &r.CreatedAt, &r.LastEdit, &r.LastEditBy, &r.IP, &r.LikeCount, &r.AttachCount, &r.ActionType)
if err == nil {
_ = s.cache.Set(r)
}
return r, err
}
/*func (s *SQLReplyStore) eachr(f func(*sql.Rows) error) error {
return eachall(s.getAll, f)
}*/
func (s *SQLReplyStore) Each(f func(*Reply) error) error {
rows, err := s.getAll.Query()
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
r := new(Reply)
if err := rows.Scan(&r.ID, &r.ParentID, &r.Content, &r.CreatedBy, &r.CreatedAt, &r.LastEdit, &r.LastEditBy, &r.IP, &r.LikeCount, &r.AttachCount, &r.ActionType); err != nil {
return err
}
if err := f(r); err != nil {
return err
}
}
return rows.Err()
}
func (s *SQLReplyStore) Exists(id int) bool {
err := s.exists.QueryRow(id).Scan(&id)
if err != nil && err != ErrNoRows {
LogError(err)
}
return err != ErrNoRows
}
// TODO: Write a test for this
func (s *SQLReplyStore) Create(t *Topic, content, ip string, uid int) (id int, err error) {
if Config.DisablePostIP {
ip = ""
}
res, err := s.create.Exec(t.ID, content, ParseMessage(content, t.ParentID, "forums", nil, nil), ip, WordCount(content), uid)
if err != nil {
return 0, err
}
lastID, err := res.LastInsertId()
if err != nil {
return 0, err
}
id = int(lastID)
return id, t.AddReply(id, uid)
}
// TODO: Write a test for this
// Count returns the total number of topic replies on these forums
func (s *SQLReplyStore) Count() (count int) {
return Countf(s.count)
}
func (s *SQLReplyStore) CountUser(uid int) (count int) {
return Countf(s.countUser, uid)
}
func (s *SQLReplyStore) CountMegaUser(uid int) (count int) {
return Countf(s.countWordUser, uid, SettingBox.Load().(SettingMap)["megapost_min_words"].(int))
}
func (s *SQLReplyStore) CountBigUser(uid int) (count int) {
return Countf(s.countWordUser, uid, SettingBox.Load().(SettingMap)["bigpost_min_words"].(int))
}
func (s *SQLReplyStore) SetCache(cache ReplyCache) {
s.cache = cache
}
func (s *SQLReplyStore) GetCache() ReplyCache {
return s.cache
}