diff --git a/db.go b/db.go new file mode 100644 index 0000000..c816432 --- /dev/null +++ b/db.go @@ -0,0 +1,112 @@ +package main + +import ( + "bytes" + "encoding/binary" + "encoding/json" + "time" + + "github.com/boltdb/bolt" +) + +type LogLine struct { + Nick string + Message string + Time time.Time + ID uint64 +} + +type history struct { + db *bolt.DB +} + +// Open creates a new db or open existing +func Open(path string) (*history, error) { + db, err := bolt.Open(path, 0600, nil) + if err != nil { + return nil, err + } + + err = db.Update(func(tx *bolt.Tx) error { + if _, err := tx.CreateBucketIfNotExists([]byte("history")); err != nil { + return err + } + + return nil + }) + + return &history{db}, err +} + +func (h *history) WriteLog(l *LogLine) error { + err := h.db.Update(func(tx *bolt.Tx) error { + b, err := tx.CreateBucketIfNotExists([]byte("history")) + if err != nil { + return err + } + + id, err := b.NextSequence() + if err != nil { + return err + } + + l.ID = id + + data, err := json.Marshal(l) + if err != nil { + return err + } + + b.Put([]byte(l.Time.Format("2006-01-02T15:04:05")), data) + + return nil + }) + return err +} + +func (h *history) GetAllLog() ([]LogLine, error) { + var logs []LogLine + + err := h.db.View(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte("history")) + + c := b.Cursor() + + for k, v := c.First(); k != nil; k, v = c.Next() { + var l LogLine + if err := json.Unmarshal(v, &l); err != nil { + return err + } + logs = append(logs, l) + } + return nil + }) + + return logs, err +} + +func (h *history) GetRangedLogs(from, to string) ([]LogLine, error) { + var logs []LogLine + + err := h.db.View(func(tx *bolt.Tx) error { + c := tx.Bucket([]byte("history")).Cursor() + + for k, v := c.Seek([]byte(from)); k != nil && bytes.Compare(k, []byte(to)) <= 0; k, v = c.Next() { + var l LogLine + if err := json.Unmarshal(v, &l); err != nil { + return err + } + logs = append(logs, l) + } + + return nil + }) + return logs, err +} + +// itob returns an 8-byte big endian representation of v. +func itob(v uint64) []byte { + b := make([]byte, 8) + binary.BigEndian.PutUint64(b, v) + return b +}