events.go (4044B)
1 package events 2 3 import ( 4 "errors" 5 "fmt" 6 "log" 7 "sermoni/internal/database" 8 9 "go.etcd.io/bbolt" 10 ) 11 12 var ( 13 keyEventID = []byte("id") 14 keyEventService = []byte("service") 15 keyEventTimestamp = []byte("timestamp") 16 keyEventStatus = []byte("status") 17 keyEventTitle = []byte("title") 18 keyEventDetails = []byte("details") 19 ) 20 21 // Event contains data sent to sermoni from a service 22 type Event struct { 23 ID uint64 `json:"id"` 24 Service uint64 `json:"serviceid"` 25 Timestamp uint64 `json:"timestamp"` 26 Status string `json:"status"` 27 Title string `json:"title"` 28 Details string `json:"details"` 29 ServiceName string `json:"service"` // Name of service - not persisted to DB 30 } 31 32 // GetAll returns all events in the database 33 func GetAll() []*Event { 34 events := []*Event{} 35 db := database.GetDB() 36 err := db.View(func(tx *bbolt.Tx) error { 37 b := tx.Bucket(database.BucketKeyEvents) 38 if b == nil { 39 log.Panic("The events bucket does not exist") 40 } 41 // ForEach doesn't return buckets (nil instead), so only the key is useful 42 return b.ForEach(func(id, _ []byte) error { 43 eb := b.Bucket(id) 44 event := new(Event) 45 if err := event.FromBucket(eb); err != nil { 46 return err 47 } 48 events = append(events, event) 49 return nil 50 }) 51 }) 52 if err != nil { 53 fmt.Println(err) 54 } 55 return events 56 } 57 58 // Delete event with the given ID. 59 // Returns error if no such event can be found 60 func Delete(idInt uint64) error { 61 db := database.GetDB() 62 id := database.Uint64ToBytes(idInt) 63 return db.Update(func(tx *bbolt.Tx) error { 64 b := tx.Bucket(database.BucketKeyEvents) 65 if b == nil { 66 log.Panic("The events bucket does not exist") 67 } 68 return b.DeleteBucket(id) 69 }) 70 } 71 72 // Add persists a new event to database after generating an ID for it 73 func Add(event *Event) error { 74 db := database.GetDB() 75 return db.Update(func(tx *bbolt.Tx) error { 76 b := tx.Bucket(database.BucketKeyEvents) 77 if b == nil { 78 log.Panic("The events bucket does not exist") 79 } 80 81 // Create a new event ID 82 idInt, err := b.NextSequence() 83 if err != nil { 84 return err 85 } 86 id := database.Uint64ToBytes(idInt) 87 event.ID = idInt 88 89 // Create the event bucket and fill it with data from event 90 eb, err := b.CreateBucket(id) 91 if err != nil { 92 return err 93 } 94 return event.toBucket(eb) 95 }) 96 } 97 98 // Writes the event data to the given bucket 99 func (event *Event) toBucket(eb *bbolt.Bucket) error { 100 var err error 101 id := database.Uint64ToBytes(event.ID) 102 serviceID := database.Uint64ToBytes(event.Service) 103 timestamp := database.Uint64ToBytes(event.Timestamp) 104 if err = eb.Put(keyEventID, id); err != nil { 105 return err 106 } 107 if eb.Put(keyEventService, serviceID); err != nil { 108 return err 109 } 110 if eb.Put(keyEventTimestamp, timestamp); err != nil { 111 return err 112 } 113 if eb.Put(keyEventStatus, []byte(event.Status)); err != nil { 114 return err 115 } 116 if eb.Put(keyEventTitle, []byte(event.Title)); err != nil { 117 return err 118 } 119 if eb.Put(keyEventDetails, []byte(event.Details)); err != nil { 120 return err 121 } 122 return nil 123 } 124 125 // Reads data from the given bucket into the fields of event 126 // Returns error if any of the fields cannot be found 127 func (event *Event) FromBucket(eb *bbolt.Bucket) error { 128 var id, service, timestamp []byte 129 var status, title, details []byte 130 err := errors.New("missing field from database") 131 132 // Get data from database 133 if id = eb.Get(keyEventID); id == nil { 134 return err 135 } 136 if service = eb.Get(keyEventService); service == nil { 137 return err 138 } 139 if timestamp = eb.Get(keyEventTimestamp); timestamp == nil { 140 return err 141 } 142 if status = eb.Get(keyEventStatus); status == nil { 143 return err 144 } 145 if title = eb.Get(keyEventTitle); title == nil { 146 return err 147 } 148 if details = eb.Get(keyEventDetails); details == nil { 149 return err 150 } 151 152 // Format data and set fields of event 153 event.ID = database.BytesToUint64(id) 154 event.Service = database.BytesToUint64(service) 155 event.Timestamp = database.BytesToUint64(timestamp) 156 event.Status = string(status) 157 event.Title = string(title) 158 event.Details = string(details) 159 160 return nil 161 }