194 lines
4.4 KiB
Go
194 lines
4.4 KiB
Go
package storage
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"os"
|
|
|
|
"git.skdevstudios.com/SK-Development-Studios/go-cal-tui/calendar"
|
|
"git.skdevstudios.com/SK-Development-Studios/go-cal-tui/internal/logger"
|
|
|
|
"github.com/dgraph-io/badger/v4"
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
type EventInput struct {
|
|
Title string
|
|
Description string
|
|
Year int32
|
|
Month int32
|
|
Day int32
|
|
StartHour int32
|
|
EndHour int32
|
|
Color string
|
|
}
|
|
|
|
var db *badger.DB
|
|
|
|
func InitDB(path string) error {
|
|
if err := os.MkdirAll(path, 0755); err != nil {
|
|
logStr := fmt.Errorf("Error creating data directory: %w", err)
|
|
logger.Log.Error(logStr)
|
|
}
|
|
var err error
|
|
db, err = badger.Open(badger.DefaultOptions(filepath.Join(path,"events_db")).WithLogger(nil))
|
|
if err != nil {
|
|
logStr := fmt.Errorf("Failed to open database: %w", err)
|
|
logger.Log.Error(logStr)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func CloseDB() {
|
|
if db != nil {
|
|
db.Close()
|
|
}
|
|
}
|
|
|
|
func SaveEvent(input EventInput) error {
|
|
if db == nil {
|
|
logger.Log.Error("Badger DB is not initialized")
|
|
}
|
|
|
|
event := &calendar.Event{
|
|
Title: input.Title,
|
|
Description: input.Description,
|
|
Year: input.Year,
|
|
Month: input.Month,
|
|
Day: input.Day,
|
|
StartHour: input.StartHour,
|
|
EndHour: input.EndHour,
|
|
Color: input.Color,
|
|
}
|
|
|
|
data,err := proto.Marshal(event)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var key []byte
|
|
key = fmt.Appendf(key, "events/%04d-%02d-%02d/%02d", event.Year, event.Month, event.Day, event.StartHour)
|
|
|
|
return db.Update(func(txn *badger.Txn) error {
|
|
return txn.Set(key, data)
|
|
})
|
|
}
|
|
|
|
func GetEvent(year,month,day,hour int32) (*calendar.Event,error) {
|
|
var evt calendar.Event
|
|
var key []byte
|
|
key = fmt.Appendf(key, "events/%04d-%02d-%02d/%02d", year, month, day, hour)
|
|
|
|
err := db.View(func(txn *badger.Txn) error {
|
|
item,err := txn.Get(key)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return item.Value(func(val []byte) error {
|
|
return proto.Unmarshal(val, &evt)
|
|
})
|
|
})
|
|
return &evt,err
|
|
}
|
|
|
|
func GetEventsForDay(year,month,day int32) ([]*calendar.Event,error) {
|
|
var prefix []byte
|
|
|
|
prefix = fmt.Appendf(prefix, "events/%04d-%02d-%02d/", year,month,day)
|
|
|
|
var events []*calendar.Event
|
|
|
|
err := db.View(func(txn *badger.Txn) error {
|
|
it := txn.NewIterator(badger.DefaultIteratorOptions)
|
|
defer it.Close()
|
|
|
|
for it.Seek(prefix); it.ValidForPrefix(prefix); it.Next(){
|
|
item := it.Item()
|
|
err := item.Value(func(val []byte) error {
|
|
var e calendar.Event
|
|
if err := proto.Unmarshal(val, &e); err != nil{
|
|
return err
|
|
}
|
|
events = append(events,&e)
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
return events,err
|
|
}
|
|
|
|
func EditEvent(originalYear, originalMonth, originalDay, originalStartHour int32, updated EventInput) error {
|
|
if db == nil {
|
|
err := fmt.Errorf("badger DB is not initialized")
|
|
logger.Log.Error(err)
|
|
return err
|
|
}
|
|
|
|
// Reject changes to key-defining fields
|
|
if updated.Year != originalYear ||
|
|
updated.Month != originalMonth ||
|
|
updated.Day != originalDay ||
|
|
updated.StartHour != originalStartHour {
|
|
|
|
err := fmt.Errorf("editing key-defining fields (year, month, day, startHour) is not allowed; delete and recreate instead")
|
|
logger.Log.Error(err)
|
|
return err
|
|
}
|
|
|
|
key := fmt.Appendf(nil, "events/%04d-%02d-%02d/%02d", originalYear, originalMonth, originalDay, originalStartHour)
|
|
|
|
event := &calendar.Event{
|
|
Title: updated.Title,
|
|
Description: updated.Description,
|
|
Year: originalYear,
|
|
Month: originalMonth,
|
|
Day: originalDay,
|
|
StartHour: originalStartHour,
|
|
EndHour: updated.EndHour,
|
|
Color: updated.Color,
|
|
}
|
|
|
|
data, err := proto.Marshal(event)
|
|
if err != nil {
|
|
err = fmt.Errorf("failed to marshal updated event: %w", err)
|
|
logger.Log.Error(err)
|
|
return err
|
|
}
|
|
|
|
err = db.Update(func(txn *badger.Txn) error {
|
|
return txn.Set(key, data)
|
|
})
|
|
|
|
if err != nil {
|
|
err = fmt.Errorf("failed to update event in DB: %w", err)
|
|
logger.Log.Error(err)
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func DeleteEvent(year, month, day, startHour int32) error {
|
|
if db == nil {
|
|
err := fmt.Errorf("badger DB is not initialized")
|
|
logger.Log.Error(err)
|
|
return err
|
|
}
|
|
|
|
key := fmt.Appendf(nil, "events/%04d-%02d-%02d/%02d", year, month, day, startHour)
|
|
|
|
err := db.Update(func(txn *badger.Txn) error {
|
|
return txn.Delete(key)
|
|
})
|
|
if err != nil {
|
|
err = fmt.Errorf("failed to delete event from DB: %w", err)
|
|
logger.Log.Error(err)
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|