package repository
import (
"encoding/json"
"fmt"
"strconv"
"time"
"gitrepo.ru/neonxp/gorum/models"
"go.etcd.io/bbolt"
)
type Topic struct {
db *bbolt.DB
}
func NewTopic(db *bbolt.DB) *Topic {
return &Topic{
db: db,
}
}
func (t *Topic) Init() error {
return t.db.Update(func(tx *bbolt.Tx) error {
_, err := tx.CreateBucketIfNotExists([]byte("topics"))
return err
})
}
func (t *Topic) Create(title, text, authorID string, parentID uint64) (*models.Topic, error) {
topic := &models.Topic{
Topic: title,
Text: text,
AuthorID: authorID,
ParentID: parentID,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
return topic, t.db.Update(func(tx *bbolt.Tx) error {
bucket, err := tx.CreateBucketIfNotExists([]byte("topics"))
if err != nil {
return err
}
id, err := bucket.NextSequence()
if err != nil {
return err
}
topic.ID = id
tb, err := json.Marshal(topic)
if err != nil {
return err
}
if _, err := tx.CreateBucketIfNotExists([]byte(fmt.Sprintf("posts_%d", topic.ID))); err != nil {
return err
}
return bucket.Put([]byte(strconv.Itoa(int(topic.ID))), tb)
})
}
func (t *Topic) List(parentID uint64) ([]*models.Topic, error) {
topics := make([]*models.Topic, 0)
return topics, t.db.View(func(tx *bbolt.Tx) error {
bucket := tx.Bucket([]byte("topics"))
if bucket == nil {
return models.ErrDBNotInitialized
}
return bucket.ForEach(func(k, v []byte) error {
t := new(models.Topic)
if err := json.Unmarshal(v, t); err != nil {
return err
}
if t.ParentID == parentID {
topics = append(topics, t)
}
return nil
})
})
}
func (t *Topic) Get(topicID uint64) (*models.Topic, error) {
topic := new(models.Topic)
return topic, t.db.View(func(tx *bbolt.Tx) error {
bucket := tx.Bucket([]byte("topics"))
if bucket == nil {
return models.ErrDBNotInitialized
}
tb := bucket.Get([]byte(strconv.Itoa(int(topicID))))
if tb == nil {
return models.ErrTopicNotFound
}
return json.Unmarshal(tb, topic)
})
}