2017-09-13 15:09:13 +00:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Gosora Topic Store
|
|
|
|
* Copyright Azareal 2017 - 2018
|
|
|
|
*
|
|
|
|
*/
|
2017-06-13 07:12:58 +00:00
|
|
|
package main
|
|
|
|
|
2017-06-13 08:56:48 +00:00
|
|
|
import "log"
|
2017-06-13 07:12:58 +00:00
|
|
|
import "sync"
|
|
|
|
import "database/sql"
|
2017-06-13 08:56:48 +00:00
|
|
|
import "./query_gen/lib"
|
2017-06-13 07:12:58 +00:00
|
|
|
|
2017-09-10 16:57:22 +00:00
|
|
|
// TODO: Add the watchdog goroutine
|
2017-06-13 07:12:58 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2017-06-15 11:40:35 +00:00
|
|
|
type MemoryTopicStore struct {
|
2017-09-03 04:50:31 +00:00
|
|
|
items map[int]*Topic
|
|
|
|
length int
|
2017-06-13 07:12:58 +00:00
|
|
|
capacity int
|
2017-09-03 04:50:31 +00:00
|
|
|
get *sql.Stmt
|
2017-06-13 07:12:58 +00:00
|
|
|
sync.RWMutex
|
|
|
|
}
|
|
|
|
|
2017-09-13 15:09:13 +00:00
|
|
|
// NewMemoryTopicStore gives you a new instance of MemoryTopicStore
|
2017-06-15 11:40:35 +00:00
|
|
|
func NewMemoryTopicStore(capacity int) *MemoryTopicStore {
|
2017-09-03 04:50:31 +00:00
|
|
|
stmt, err := qgen.Builder.SimpleSelect("topics", "title, content, createdBy, createdAt, is_closed, sticky, parentID, ipaddress, postCount, likeCount, data", "tid = ?", "", "")
|
2017-06-13 08:56:48 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2017-06-15 11:40:35 +00:00
|
|
|
return &MemoryTopicStore{
|
2017-09-03 04:50:31 +00:00
|
|
|
items: make(map[int]*Topic),
|
2017-08-27 09:33:45 +00:00
|
|
|
capacity: capacity,
|
2017-09-03 04:50:31 +00:00
|
|
|
get: stmt,
|
2017-06-13 08:56:48 +00:00
|
|
|
}
|
2017-06-13 07:12:58 +00:00
|
|
|
}
|
|
|
|
|
2017-06-15 11:40:35 +00:00
|
|
|
func (sts *MemoryTopicStore) Get(id int) (*Topic, error) {
|
2017-06-13 07:12:58 +00:00
|
|
|
sts.RLock()
|
|
|
|
item, ok := sts.items[id]
|
|
|
|
sts.RUnlock()
|
|
|
|
if ok {
|
|
|
|
return item, nil
|
|
|
|
}
|
2017-06-28 12:05:26 +00:00
|
|
|
return item, ErrNoRows
|
2017-06-13 07:12:58 +00:00
|
|
|
}
|
|
|
|
|
2017-06-15 11:40:35 +00:00
|
|
|
func (sts *MemoryTopicStore) GetUnsafe(id int) (*Topic, error) {
|
2017-06-13 07:12:58 +00:00
|
|
|
item, ok := sts.items[id]
|
|
|
|
if ok {
|
|
|
|
return item, nil
|
|
|
|
}
|
2017-06-28 12:05:26 +00:00
|
|
|
return item, ErrNoRows
|
2017-06-13 07:12:58 +00:00
|
|
|
}
|
|
|
|
|
2017-06-15 11:40:35 +00:00
|
|
|
func (sts *MemoryTopicStore) CascadeGet(id int) (*Topic, error) {
|
2017-06-13 07:12:58 +00:00
|
|
|
sts.RLock()
|
|
|
|
topic, ok := sts.items[id]
|
|
|
|
sts.RUnlock()
|
|
|
|
if ok {
|
|
|
|
return topic, nil
|
|
|
|
}
|
|
|
|
|
2017-09-03 04:50:31 +00:00
|
|
|
topic = &Topic{ID: id}
|
|
|
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
2017-06-13 07:12:58 +00:00
|
|
|
if err == nil {
|
2017-09-03 04:50:31 +00:00
|
|
|
topic.Link = buildTopicURL(nameToSlug(topic.Title), id)
|
|
|
|
_ = sts.Add(topic)
|
2017-06-13 07:12:58 +00:00
|
|
|
}
|
|
|
|
return topic, err
|
|
|
|
}
|
|
|
|
|
2017-06-15 11:40:35 +00:00
|
|
|
func (sts *MemoryTopicStore) BypassGet(id int) (*Topic, error) {
|
2017-09-03 04:50:31 +00:00
|
|
|
topic := &Topic{ID: id}
|
|
|
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
|
|
|
topic.Link = buildTopicURL(nameToSlug(topic.Title), id)
|
2017-06-13 07:12:58 +00:00
|
|
|
return topic, err
|
|
|
|
}
|
|
|
|
|
2017-06-15 11:40:35 +00:00
|
|
|
func (sts *MemoryTopicStore) Load(id int) error {
|
2017-09-03 04:50:31 +00:00
|
|
|
topic := &Topic{ID: id}
|
|
|
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
2017-06-13 07:12:58 +00:00
|
|
|
if err == nil {
|
2017-09-03 04:50:31 +00:00
|
|
|
topic.Link = buildTopicURL(nameToSlug(topic.Title), id)
|
|
|
|
_ = sts.Set(topic)
|
2017-06-13 07:12:58 +00:00
|
|
|
} else {
|
2017-09-03 04:50:31 +00:00
|
|
|
_ = sts.Remove(id)
|
2017-06-13 07:12:58 +00:00
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2017-06-15 11:40:35 +00:00
|
|
|
func (sts *MemoryTopicStore) Set(item *Topic) error {
|
2017-06-13 07:12:58 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2017-06-15 11:40:35 +00:00
|
|
|
func (sts *MemoryTopicStore) Add(item *Topic) error {
|
2017-06-13 07:12:58 +00:00
|
|
|
if sts.length >= sts.capacity {
|
|
|
|
return ErrStoreCapacityOverflow
|
|
|
|
}
|
|
|
|
sts.Lock()
|
|
|
|
sts.items[item.ID] = item
|
|
|
|
sts.Unlock()
|
|
|
|
sts.length++
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-15 11:40:35 +00:00
|
|
|
func (sts *MemoryTopicStore) AddUnsafe(item *Topic) error {
|
2017-06-13 07:12:58 +00:00
|
|
|
if sts.length >= sts.capacity {
|
|
|
|
return ErrStoreCapacityOverflow
|
|
|
|
}
|
|
|
|
sts.items[item.ID] = item
|
|
|
|
sts.length++
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-15 11:40:35 +00:00
|
|
|
func (sts *MemoryTopicStore) Remove(id int) error {
|
2017-06-13 07:12:58 +00:00
|
|
|
sts.Lock()
|
2017-09-03 04:50:31 +00:00
|
|
|
delete(sts.items, id)
|
2017-06-13 07:12:58 +00:00
|
|
|
sts.Unlock()
|
|
|
|
sts.length--
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-15 11:40:35 +00:00
|
|
|
func (sts *MemoryTopicStore) RemoveUnsafe(id int) error {
|
2017-09-03 04:50:31 +00:00
|
|
|
delete(sts.items, id)
|
2017-06-13 07:12:58 +00:00
|
|
|
sts.length--
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-15 11:40:35 +00:00
|
|
|
func (sts *MemoryTopicStore) AddLastTopic(item *Topic, fid int) error {
|
2017-06-13 07:12:58 +00:00
|
|
|
// Coming Soon...
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-06-15 11:40:35 +00:00
|
|
|
func (sts *MemoryTopicStore) GetLength() int {
|
2017-06-13 07:12:58 +00:00
|
|
|
return sts.length
|
|
|
|
}
|
|
|
|
|
2017-06-15 11:40:35 +00:00
|
|
|
func (sts *MemoryTopicStore) SetCapacity(capacity int) {
|
2017-06-13 07:12:58 +00:00
|
|
|
sts.capacity = capacity
|
|
|
|
}
|
|
|
|
|
2017-06-15 11:40:35 +00:00
|
|
|
func (sts *MemoryTopicStore) GetCapacity() int {
|
2017-06-13 07:12:58 +00:00
|
|
|
return sts.capacity
|
|
|
|
}
|
|
|
|
|
2017-09-10 16:57:22 +00:00
|
|
|
type SQLTopicStore struct {
|
2017-09-03 04:50:31 +00:00
|
|
|
get *sql.Stmt
|
2017-06-13 07:12:58 +00:00
|
|
|
}
|
|
|
|
|
2017-09-10 16:57:22 +00:00
|
|
|
func NewSQLTopicStore() *SQLTopicStore {
|
2017-09-03 04:50:31 +00:00
|
|
|
stmt, err := qgen.Builder.SimpleSelect("topics", "title, content, createdBy, createdAt, is_closed, sticky, parentID, ipaddress, postCount, likeCount, data", "tid = ?", "", "")
|
2017-06-13 08:56:48 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2017-09-10 16:57:22 +00:00
|
|
|
return &SQLTopicStore{stmt}
|
2017-06-13 07:12:58 +00:00
|
|
|
}
|
|
|
|
|
2017-09-10 16:57:22 +00:00
|
|
|
func (sts *SQLTopicStore) Get(id int) (*Topic, error) {
|
2017-09-03 04:50:31 +00:00
|
|
|
topic := Topic{ID: id}
|
|
|
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
|
|
|
topic.Link = buildTopicURL(nameToSlug(topic.Title), id)
|
2017-06-13 07:12:58 +00:00
|
|
|
return &topic, err
|
|
|
|
}
|
|
|
|
|
2017-09-10 16:57:22 +00:00
|
|
|
func (sts *SQLTopicStore) GetUnsafe(id int) (*Topic, error) {
|
2017-09-03 04:50:31 +00:00
|
|
|
topic := Topic{ID: id}
|
|
|
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
|
|
|
topic.Link = buildTopicURL(nameToSlug(topic.Title), id)
|
2017-06-13 07:12:58 +00:00
|
|
|
return &topic, err
|
|
|
|
}
|
|
|
|
|
2017-09-10 16:57:22 +00:00
|
|
|
func (sts *SQLTopicStore) CascadeGet(id int) (*Topic, error) {
|
2017-09-03 04:50:31 +00:00
|
|
|
topic := Topic{ID: id}
|
|
|
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
|
|
|
topic.Link = buildTopicURL(nameToSlug(topic.Title), id)
|
2017-06-13 07:12:58 +00:00
|
|
|
return &topic, err
|
|
|
|
}
|
|
|
|
|
2017-09-10 16:57:22 +00:00
|
|
|
func (sts *SQLTopicStore) BypassGet(id int) (*Topic, error) {
|
2017-09-03 04:50:31 +00:00
|
|
|
topic := &Topic{ID: id}
|
|
|
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
|
|
|
topic.Link = buildTopicURL(nameToSlug(topic.Title), id)
|
2017-06-13 07:12:58 +00:00
|
|
|
return topic, err
|
|
|
|
}
|
|
|
|
|
2017-09-10 16:57:22 +00:00
|
|
|
func (sts *SQLTopicStore) Load(id int) error {
|
2017-09-03 04:50:31 +00:00
|
|
|
topic := Topic{ID: id}
|
|
|
|
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
|
|
|
|
topic.Link = buildTopicURL(nameToSlug(topic.Title), id)
|
2017-06-13 07:12:58 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Placeholder methods, the actual queries are done elsewhere
|
2017-09-10 16:57:22 +00:00
|
|
|
func (sts *SQLTopicStore) Set(item *Topic) error {
|
2017-06-13 07:12:58 +00:00
|
|
|
return nil
|
|
|
|
}
|
2017-09-10 16:57:22 +00:00
|
|
|
func (sts *SQLTopicStore) Add(item *Topic) error {
|
2017-06-13 07:12:58 +00:00
|
|
|
return nil
|
|
|
|
}
|
2017-09-10 16:57:22 +00:00
|
|
|
func (sts *SQLTopicStore) AddUnsafe(item *Topic) error {
|
2017-06-13 07:12:58 +00:00
|
|
|
return nil
|
|
|
|
}
|
2017-09-10 16:57:22 +00:00
|
|
|
func (sts *SQLTopicStore) Remove(id int) error {
|
2017-06-13 07:12:58 +00:00
|
|
|
return nil
|
|
|
|
}
|
2017-09-10 16:57:22 +00:00
|
|
|
func (sts *SQLTopicStore) RemoveUnsafe(id int) error {
|
2017-06-13 07:12:58 +00:00
|
|
|
return nil
|
|
|
|
}
|
2017-09-10 16:57:22 +00:00
|
|
|
func (sts *SQLTopicStore) AddLastTopic(item *Topic, fid int) error {
|
2017-06-13 07:12:58 +00:00
|
|
|
// Coming Soon...
|
|
|
|
return nil
|
|
|
|
}
|
2017-09-10 16:57:22 +00:00
|
|
|
func (sts *SQLTopicStore) GetCapacity() int {
|
2017-06-13 07:12:58 +00:00
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2017-09-10 16:57:22 +00:00
|
|
|
func (sts *SQLTopicStore) GetLength() int {
|
2017-06-13 07:12:58 +00:00
|
|
|
return 0 // Return the total number of topics on the forums?
|
|
|
|
}
|