41c620b988
Fixed the indentation in alerts.go, Atom replaced the tabs with spaces for some reason x.x Made the friendly URL logic more flexible. Made the supermod menu item hiding more JS friendly. strconv is now an optional dependency for compiled template files. Revamped the profile template.
242 lines
6.7 KiB
Go
242 lines
6.7 KiB
Go
package main
|
|
|
|
import "log"
|
|
import "sync"
|
|
import "database/sql"
|
|
import "./query_gen/lib"
|
|
|
|
// TO-DO: Add the watchdog goroutine
|
|
var topics TopicStore
|
|
|
|
type TopicStore interface {
|
|
Load(id int) error
|
|
Get(id int) (*Topic, error)
|
|
GetUnsafe(id int) (*Topic, error)
|
|
CascadeGet(id int) (*Topic, error)
|
|
BypassGet(id int) (*Topic, error)
|
|
Set(item *Topic) error
|
|
Add(item *Topic) error
|
|
AddUnsafe(item *Topic) error
|
|
Remove(id int) error
|
|
RemoveUnsafe(id int) error
|
|
AddLastTopic(item *Topic, fid int) error
|
|
GetLength() int
|
|
GetCapacity() int
|
|
}
|
|
|
|
type MemoryTopicStore struct {
|
|
items map[int]*Topic
|
|
length int
|
|
capacity int
|
|
get *sql.Stmt
|
|
sync.RWMutex
|
|
}
|
|
|
|
func NewMemoryTopicStore(capacity int) *MemoryTopicStore {
|
|
stmt, err := qgen.Builder.SimpleSelect("topics","title, content, createdBy, createdAt, is_closed, sticky, parentID, ipaddress, postCount, likeCount, data","tid = ?","","")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
return &MemoryTopicStore{
|
|
items:make(map[int]*Topic),
|
|
capacity:capacity,
|
|
get:stmt,
|
|
}
|
|
}
|
|
|
|
func (sts *MemoryTopicStore) Get(id int) (*Topic, error) {
|
|
sts.RLock()
|
|
item, ok := sts.items[id]
|
|
sts.RUnlock()
|
|
if ok {
|
|
return item, nil
|
|
}
|
|
return item, ErrNoRows
|
|
}
|
|
|
|
func (sts *MemoryTopicStore) GetUnsafe(id int) (*Topic, error) {
|
|
item, ok := sts.items[id]
|
|
if ok {
|
|
return item, nil
|
|
}
|
|
return item, ErrNoRows
|
|
}
|
|
|
|
func (sts *MemoryTopicStore) CascadeGet(id int) (*Topic, error) {
|
|
sts.RLock()
|
|
topic, ok := sts.items[id]
|
|
sts.RUnlock()
|
|
if ok {
|
|
return topic, nil
|
|
}
|
|
|
|
topic = &Topic{ID:id}
|
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
|
if err == nil {
|
|
topic.Link = build_topic_url(name_to_slug(topic.Title),id)
|
|
sts.Add(topic)
|
|
}
|
|
return topic, err
|
|
}
|
|
|
|
func (sts *MemoryTopicStore) BypassGet(id int) (*Topic, error) {
|
|
topic := &Topic{ID:id}
|
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
|
topic.Link = build_topic_url(name_to_slug(topic.Title),id)
|
|
return topic, err
|
|
}
|
|
|
|
func (sts *MemoryTopicStore) Load(id int) error {
|
|
topic := &Topic{ID:id}
|
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
|
if err == nil {
|
|
topic.Link = build_topic_url(name_to_slug(topic.Title),id)
|
|
sts.Set(topic)
|
|
} else {
|
|
sts.Remove(id)
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (sts *MemoryTopicStore) Set(item *Topic) error {
|
|
sts.Lock()
|
|
_, ok := sts.items[item.ID]
|
|
if ok {
|
|
sts.items[item.ID] = item
|
|
} else if sts.length >= sts.capacity {
|
|
sts.Unlock()
|
|
return ErrStoreCapacityOverflow
|
|
} else {
|
|
sts.items[item.ID] = item
|
|
sts.length++
|
|
}
|
|
sts.Unlock()
|
|
return nil
|
|
}
|
|
|
|
func (sts *MemoryTopicStore) Add(item *Topic) error {
|
|
if sts.length >= sts.capacity {
|
|
return ErrStoreCapacityOverflow
|
|
}
|
|
sts.Lock()
|
|
sts.items[item.ID] = item
|
|
sts.Unlock()
|
|
sts.length++
|
|
return nil
|
|
}
|
|
|
|
func (sts *MemoryTopicStore) AddUnsafe(item *Topic) error {
|
|
if sts.length >= sts.capacity {
|
|
return ErrStoreCapacityOverflow
|
|
}
|
|
sts.items[item.ID] = item
|
|
sts.length++
|
|
return nil
|
|
}
|
|
|
|
func (sts *MemoryTopicStore) Remove(id int) error {
|
|
sts.Lock()
|
|
delete(sts.items,id)
|
|
sts.Unlock()
|
|
sts.length--
|
|
return nil
|
|
}
|
|
|
|
func (sts *MemoryTopicStore) RemoveUnsafe(id int) error {
|
|
delete(sts.items,id)
|
|
sts.length--
|
|
return nil
|
|
}
|
|
|
|
func (sts *MemoryTopicStore) AddLastTopic(item *Topic, fid int) error {
|
|
// Coming Soon...
|
|
return nil
|
|
}
|
|
|
|
func (sts *MemoryTopicStore) GetLength() int {
|
|
return sts.length
|
|
}
|
|
|
|
func (sts *MemoryTopicStore) SetCapacity(capacity int) {
|
|
sts.capacity = capacity
|
|
}
|
|
|
|
func (sts *MemoryTopicStore) GetCapacity() int {
|
|
return sts.capacity
|
|
}
|
|
|
|
type SqlTopicStore struct {
|
|
get *sql.Stmt
|
|
}
|
|
|
|
func NewSqlTopicStore() *SqlTopicStore {
|
|
stmt, err := qgen.Builder.SimpleSelect("topics","title, content, createdBy, createdAt, is_closed, sticky, parentID, ipaddress, postCount, likeCount, data","tid = ?","","")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
return &SqlTopicStore{stmt}
|
|
}
|
|
|
|
func (sts *SqlTopicStore) Get(id int) (*Topic, error) {
|
|
topic := Topic{ID:id}
|
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
|
topic.Link = build_topic_url(name_to_slug(topic.Title),id)
|
|
return &topic, err
|
|
}
|
|
|
|
func (sts *SqlTopicStore) GetUnsafe(id int) (*Topic, error) {
|
|
topic := Topic{ID:id}
|
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
|
topic.Link = build_topic_url(name_to_slug(topic.Title),id)
|
|
return &topic, err
|
|
}
|
|
|
|
func (sts *SqlTopicStore) CascadeGet(id int) (*Topic, error) {
|
|
topic := Topic{ID:id}
|
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
|
topic.Link = build_topic_url(name_to_slug(topic.Title),id)
|
|
return &topic, err
|
|
}
|
|
|
|
func (sts *SqlTopicStore) BypassGet(id int) (*Topic, error) {
|
|
topic := &Topic{ID:id}
|
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
|
topic.Link = build_topic_url(name_to_slug(topic.Title),id)
|
|
return topic, err
|
|
}
|
|
|
|
func (sts *SqlTopicStore) Load(id int) error {
|
|
topic := Topic{ID:id}
|
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
|
topic.Link = build_topic_url(name_to_slug(topic.Title),id)
|
|
return err
|
|
}
|
|
|
|
// Placeholder methods, the actual queries are done elsewhere
|
|
func (sts *SqlTopicStore) Set(item *Topic) error {
|
|
return nil
|
|
}
|
|
func (sts *SqlTopicStore) Add(item *Topic) error {
|
|
return nil
|
|
}
|
|
func (sts *SqlTopicStore) AddUnsafe(item *Topic) error {
|
|
return nil
|
|
}
|
|
func (sts *SqlTopicStore) Remove(id int) error {
|
|
return nil
|
|
}
|
|
func (sts *SqlTopicStore) RemoveUnsafe(id int) error {
|
|
return nil
|
|
}
|
|
func (sts *SqlTopicStore) AddLastTopic(item *Topic, fid int) error {
|
|
// Coming Soon...
|
|
return nil
|
|
}
|
|
func (sts *SqlTopicStore) GetCapacity() int {
|
|
return 0
|
|
}
|
|
|
|
func (sts *SqlTopicStore) GetLength() int {
|
|
return 0 // Return the total number of topics on the forums?
|
|
}
|