package main import ( "errors" "time" ) type Database interface { GetTracking() (*Entry, error) GetEntries() ([]*Entry, error) QueryEntry(id *int, date *Date) ([]*Entry, error) StartNewEntry(now time.Time, task *Entry) (*Entry, error) StopEntry(now time.Time) error SaveEntry(task *Entry) (*Entry, error) GetTasks() ([]*Task, error) QueryTask(id *int, group *string, ident *string) ([]*Task, error) SaveTask(task *Task) (*Task, error) } type InMemDb struct { entries []*Entry current *Entry tasks []*Task } var ( ErrNotFound = errors.New("Not found") ErrNotRunning = errors.New("Not running") ) func NewInMemDb() Database { return &InMemDb{ entries: []*Entry{}, current: nil, } } func (db *InMemDb) GetTracking() (*Entry, error) { return db.current, nil } func (db *InMemDb) GetEntries() ([]*Entry, error) { res := make([]*Entry, 0, len(db.entries)) for _, task := range db.entries { res = append(res, task) } return res, nil } func (db *InMemDb) QueryEntry(id *int, date *Date) ([]*Entry, error) { res := make([]*Entry, 0, 1) for _, entry := range db.entries { if id != nil && entry.Id != *id { continue } if date != nil && entry.Date != *date { continue } res = append(res, entry) } return res, nil } func (db *InMemDb) StartNewEntry(now time.Time, task *Entry) (*Entry, error) { newTask := &Entry{ Id: len(db.entries), From: task.From, To: nil, Date: DateFromStd(now), Tag: task.Tag, Comment: task.Comment, } if newTask.From == nil { from := TimeFromStd(now) newTask.From = &from } db.entries = append(db.entries, 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(entry *Entry) (*Entry, error) { if entry.Id < 0 || entry.Id >= len(db.entries) { copyTask := *entry copyTask.Id = len(db.entries) db.entries = append(db.entries, ©Task) return ©Task, nil } existent := db.entries[entry.Id] existent.Comment = entry.Comment existent.Tag = entry.Tag existent.From = entry.From existent.To = entry.To existent.Date = entry.Date return existent, 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, group *string, ident *string) ([]*Task, error) { res := make([]*Task, 0, 1) for _, task := range db.tasks { if id != nil && task.Id != *id { continue } if group != nil && task.Group != group { continue } if ident != nil && task.Ident != ident { continue } res = append(res, task) } return res, nil } func (db *InMemDb) SaveTask(task *Task) (newTask *Task, err error) { var tasks []*Task tasks, err = db.QueryTask(&task.Id, nil, nil) if err != nil { return } if len(tasks) > 0 { newTask = tasks[0] newTask.Text = task.Text newTask.Group = task.Group newTask.Ident = task.Ident } else { taskCopy := *task taskCopy.Id = len(db.tasks) db.tasks = append(db.tasks, &taskCopy) newTask = &taskCopy } return }