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