package main import ( "errors" "time" ) type Database interface { GetTracking() (*Entry, error) GetTasks() ([]*Entry, error) QueryTask(id *int) (*Entry, error) StartNewEntry(now time.Time, task *Entry) (*Entry, error) StopEntry(now time.Time) error SaveEntry(task *Entry) (*Entry, error) } type InMemDb struct { tasks []*Entry current *Entry } var ( ErrNotFound = errors.New("Not found") ErrNotRunning = errors.New("Not running") ) func NewInMemDb() Database { return &InMemDb { tasks: []*Entry{}, current: nil, } } func (db *InMemDb) GetTracking() (*Entry, error) { return db.current, nil } func (db *InMemDb) GetTasks() ([]*Entry, error) { res := make([]*Entry, 0, len(db.tasks)) for _, task := range db.tasks { res = append(res, task) } return res, nil } func (db *InMemDb) QueryTask(id *int) (*Entry, error) { if id != nil && *id >= 0 || *id < len(db.tasks) { return db.tasks[*id], nil } return nil, ErrNotFound } func (db *InMemDb) StartNewEntry(now time.Time, task *Entry) (*Entry, error) { newTask := &Entry { Id: len(db.tasks), From: task.From, To: nil, Tag: task.Tag, Comment: task.Comment, } if newTask.From == nil { from := TimeFromStd(now) newTask.From = &from } db.tasks = append(db.tasks, newTask) db.StopEntry(now) db.current = newTask return newTask, nil } func (db *InMemDb) StopEntry(now time.Time) error { if db.current != nil { to := TimeFromStd(now) db.current.To = &to db.current = nil } else { return ErrNotRunning } return nil } func (db *InMemDb) SaveEntry(task *Entry) (*Entry, error) { if task.Id < 0 || task.Id >= len(db.tasks) { copyTask := *task copyTask.Id = len(db.tasks) db.tasks = append(db.tasks, ©Task) return ©Task, nil } existent := db.tasks[task.Id] existent.Comment = task.Comment existent.Tag = task.Tag existent.From = task.From existent.To = task.To return existent, nil }