package localserver import ( "encoding/binary" "encoding/json" "path/filepath" "github.com/dgraph-io/badger/v3" ) type ChatFile struct { Path string `json:"path"` Name string `json:"name"` Size int `json:"size"` UploadTime string `json:"uploadTime` } type ChatMessage struct { ID uint64 `json:"id"` From string `json:"from"` ResponseOf *ChatMessage `json:"ResponseOf"` Tags []string `json:"tags"` Content string `json:"content"` Date string `json:"date"` File *ChatFile `json:"file"` } type ZoneChatDBHandler struct { ChatID string ZoneID string PreviousId uint64 db func(func(*badger.DB) (err error)) (err error) } func NewZoneChatDBHandler(zoneId string, chatID string) (zoneChatDBHandler *ZoneChatDBHandler, err error) { zoneChatDBHandler = &ZoneChatDBHandler{ db: func(f func(*badger.DB) (err error)) (err error) { db, err := badger.Open(badger.DefaultOptions(filepath.Join("data", "zones", zoneId, "chats", chatID)).WithLogger(dbLogger)) if err != nil { return } defer db.Close() err = f(db) return }, ChatID: chatID, ZoneID: zoneId, } err = zoneChatDBHandler.db(func(d *badger.DB) (err error) { err = d.View(func(txn *badger.Txn) error { opt := badger.DefaultIteratorOptions it := txn.NewIterator(opt) defer it.Close() counter := 0 for it.Rewind(); it.Valid(); it.Next() { counter++ } logger.Println(counter) zoneChatDBHandler.PreviousId = uint64(counter) return nil }) return }) return } func (zcdbh *ZoneChatDBHandler) updateDbCallbackFolder(newChatId string) { zcdbh.db = func(f func(*badger.DB) (err error)) (err error) { db, err := badger.Open(badger.DefaultOptions(filepath.Join("data", "zones", zcdbh.ZoneID, "chats", newChatId)).WithLogger(dbLogger)) if err != nil { return } defer db.Close() err = f(db) return } } func (zcdbh *ZoneChatDBHandler) AddNewChatMessage(chatMessage *ChatMessage) (err error) { b := make([]byte, 100) binary.LittleEndian.PutUint64(b, zcdbh.PreviousId+1) chatMessage.ID = zcdbh.PreviousId zcdbh.PreviousId++ bs, err := json.Marshal(chatMessage) if err != nil { return } if err = zcdbh.db(func(d *badger.DB) (err error) { err = d.Update(func(txn *badger.Txn) (err error) { if updateErr := txn.Set(b, bs); updateErr != nil { return updateErr } return nil }) return }); err != nil { return } return } func (zcdbh *ZoneChatDBHandler) DeleteChatMessage(key uint64) (err error) { return } func (zcdbh *ZoneChatDBHandler) ListChatMessages(lastIndex int, limit int) (chatMessages []*ChatMessage, l int, err error) { err = zcdbh.db(func(d *badger.DB) (err error) { err = d.View(func(txn *badger.Txn) (err error) { opt := badger.DefaultIteratorOptions opt.Reverse = true it := txn.NewIterator(opt) b := make([]byte, 100) if lastIndex <= 0 { binary.LittleEndian.PutUint64(b, uint64(zcdbh.PreviousId)) } else { binary.LittleEndian.PutUint64(b, uint64(lastIndex)) } x := 0 defer it.Close() defer func() { if lastIndex > limit { l = lastIndex - limit - 1 } else if lastIndex == 0 { if zcdbh.PreviousId > uint64(limit) { l = int(zcdbh.PreviousId) - limit - 1 } else { l = 0 } } else { l = 0 } }() chatMessages = make([]*ChatMessage, 0) for it.Seek(b); it.Valid(); it.Next() { if x >= limit { break } item := it.Item() if err = item.Value(func(val []byte) (err error) { var chatMessage *ChatMessage if err = json.Unmarshal(val, &chatMessage); err != nil { return err } chatMessages = append(chatMessages, chatMessage) return }); err != nil { return err } x++ } return }) return }) return } func (zcdbh *ZoneChatDBHandler) GetChatMessage(index uint64) (chatMessage *ChatMessage, err error) { err = zcdbh.db(func(d *badger.DB) (err error) { err = d.View(func(txn *badger.Txn) (err error) { b := make([]byte, 100) binary.LittleEndian.PutUint64(b, uint64(zcdbh.PreviousId)) item, err := txn.Get(b) if err != nil { return } err = item.Value(func(val []byte) error { return json.Unmarshal(val, &chatMessage) }) return }) return }) return } func (zcdbh *ZoneChatDBHandler) ModifyChatMessage(id string, chatMessage *ChatMessage) (err error) { return }