105 lines
2.6 KiB
Go
105 lines
2.6 KiB
Go
|
package gime
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"strconv"
|
||
|
"time"
|
||
|
|
||
|
"github.com/br0xen/boltease"
|
||
|
)
|
||
|
|
||
|
// SaveTimeEntry creates a time entry in the database
|
||
|
// If TimeEntry.end is zero, then it puts it in TypeCurrent
|
||
|
func (gdb *GimeDB) SaveTimeEntry(te *TimeEntry) error {
|
||
|
var err error
|
||
|
var useDb *boltease.DB
|
||
|
tp := TypeRecent
|
||
|
if te.end.IsZero() {
|
||
|
// Currently running
|
||
|
tp = TypeCurrent
|
||
|
useDb, err = gdb.openDBType(tp)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
} else {
|
||
|
// We have an end time. Does this entry go in 'recent' or 'archive'
|
||
|
// We shove times that happened 30 days ago into 'archive'
|
||
|
if time.Since(te.end) > (time.Hour * 24 * 30) {
|
||
|
tp = TypeArchive
|
||
|
}
|
||
|
}
|
||
|
tePath := []string{tp, te.uuid}
|
||
|
if err = useDb.SetTimestamp(tePath, "start", te.start); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if err = useDb.SetTimestamp(tePath, "end", te.end); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
for i := range te.tags {
|
||
|
err = useDb.SetValue(append(tePath, "tags"), strconv.Itoa(i), te.tags[i])
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// dbGetAllTimeEntries gets all time entries of a specific type
|
||
|
// tp can be:
|
||
|
// TypeCurrent = "current"
|
||
|
// TypeRecent = "recent"
|
||
|
// TypeArchive = "archive"
|
||
|
// Getting all archived time entries has the potential to be a lot of data
|
||
|
func (gdb *GimeDB) dbGetAllTimeEntries(tp string) []TimeEntry {
|
||
|
var ret []TimeEntry
|
||
|
var useDb *boltease.DB
|
||
|
var err error
|
||
|
if useDb, err = gdb.openDBType(tp); err != nil {
|
||
|
return ret
|
||
|
}
|
||
|
defer gdb.closeDBType(tp)
|
||
|
|
||
|
var uuids []string
|
||
|
if uuids, err = useDb.GetBucketList([]string{tp}); err != nil {
|
||
|
return ret
|
||
|
}
|
||
|
for _, v := range uuids {
|
||
|
if te, _ := gdb.dbGetTimeEntry(tp, v); te != nil {
|
||
|
ret = append(ret, *te)
|
||
|
}
|
||
|
}
|
||
|
return ret
|
||
|
}
|
||
|
|
||
|
// dbGetTimeEntry pulls a time entry of type tp with the given id
|
||
|
// from the db and returns it.
|
||
|
func (gdb *GimeDB) dbGetTimeEntry(tp, id string) (*TimeEntry, error) {
|
||
|
var ret *TimeEntry
|
||
|
var err error
|
||
|
var useDb *boltease.DB
|
||
|
|
||
|
if useDb, err = gdb.openDBType(tp); err != nil {
|
||
|
return ret, err
|
||
|
}
|
||
|
defer gdb.closeDBType(tp)
|
||
|
|
||
|
entryPath := []string{tp, id}
|
||
|
ret = new(TimeEntry)
|
||
|
ret.uuid = id
|
||
|
if ret.start, err = useDb.GetTimestamp(entryPath, "start"); err != nil {
|
||
|
return nil, errors.New("Unable to read entry start time")
|
||
|
}
|
||
|
if ret.end, err = useDb.GetTimestamp(entryPath, "end"); err != nil {
|
||
|
return nil, errors.New("Unable to read entry end time")
|
||
|
}
|
||
|
var keys []string
|
||
|
entryTagsPath := append(entryPath, "tags")
|
||
|
if keys, err = useDb.GetKeyList(entryTagsPath); err != nil {
|
||
|
keys = []string{}
|
||
|
}
|
||
|
for i := range keys {
|
||
|
var val string
|
||
|
if val, err = useDb.GetValue(entryTagsPath, keys[i]); err != nil {
|
||
|
ret.tags = append(ret.tags, val)
|
||
|
}
|
||
|
}
|
||
|
return ret, nil
|
||
|
}
|