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) }) }