project list

This commit is contained in:
Erik Winter 2025-01-05 12:17:57 +01:00
parent 190299f272
commit 14b14578bd
6 changed files with 89 additions and 3 deletions

BIN
dist/plan vendored

Binary file not shown.

View File

@ -48,7 +48,7 @@ func NewCLI(deps Dependencies) *CLI {
return &CLI{ return &CLI{
deps: deps, deps: deps,
cmdArgs: []CommandArgs{ cmdArgs: []CommandArgs{
NewShowArgs(), NewShowArgs(), NewProjectsArgs(),
NewAddArgs(), NewDeleteArgs(), NewListArgs(), NewAddArgs(), NewDeleteArgs(), NewListArgs(),
NewSyncArgs(), NewUpdateArgs(), NewSyncArgs(), NewUpdateArgs(),
}, },

53
plan/command/projects.go Normal file
View File

@ -0,0 +1,53 @@
package command
import (
"fmt"
"sort"
"go-mod.ewintr.nl/planner/plan/format"
)
type ProjectsArgs struct{}
func NewProjectsArgs() ProjectsArgs {
return ProjectsArgs{}
}
func (pa ProjectsArgs) Parse(main []string, fields map[string]string) (Command, error) {
if len(main) != 1 || main[0] != "projects" {
return nil, ErrWrongCommand
}
return Projects{}, nil
}
type Projects struct{}
func (ps Projects) Do(deps Dependencies) (CommandResult, error) {
projects, err := deps.TaskRepo.Projects()
if err != nil {
return nil, fmt.Errorf("could not find projects: %v", err)
}
return ProjectsResult{
Projects: projects,
}, nil
}
type ProjectsResult struct {
Projects map[string]int
}
func (psr ProjectsResult) Render() string {
projects := make([]string, 0, len(psr.Projects))
for pr := range psr.Projects {
projects = append(projects, pr)
}
sort.Strings(projects)
data := [][]string{{"projects", "count"}}
for _, p := range projects {
data = append(data, []string{p, fmt.Sprintf("%d", psr.Projects[p])})
}
return fmt.Sprintf("\n%s\n", format.Table(data))
}

View File

@ -67,3 +67,15 @@ func (t *Task) Delete(id string) error {
return nil return nil
} }
func (t *Task) Projects() (map[string]int, error) {
projects := make(map[string]int)
for _, tsk := range t.tasks {
if _, ok := projects[tsk.Project]; !ok {
projects[tsk.Project] = 0
}
projects[tsk.Project]++
}
return projects, nil
}

View File

@ -125,8 +125,8 @@ func (t *SqliteTask) FindMany(params storage.TaskListParams) ([]item.Task, error
return tasks, nil return tasks, nil
} }
func (s *SqliteTask) Delete(id string) error { func (t *SqliteTask) Delete(id string) error {
result, err := s.db.Exec(` result, err := t.db.Exec(`
DELETE FROM tasks DELETE FROM tasks
WHERE id = ?`, id) WHERE id = ?`, id)
if err != nil { if err != nil {
@ -144,3 +144,23 @@ WHERE id = ?`, id)
return nil return nil
} }
func (t *SqliteTask) Projects() (map[string]int, error) {
rows, err := t.db.Query(`SELECT project, count(*) FROM tasks GROUP BY project`)
if err != nil {
return nil, fmt.Errorf("%w: %v", ErrSqliteFailure, err)
}
result := make(map[string]int)
defer rows.Close()
for rows.Next() {
var pr string
var count int
if err := rows.Scan(&pr, &count); err != nil {
return nil, fmt.Errorf("%w: %v", ErrSqliteFailure, err)
}
result[pr] = count
}
return result, nil
}

View File

@ -41,6 +41,7 @@ type Task interface {
FindOne(id string) (item.Task, error) FindOne(id string) (item.Task, error)
FindMany(params TaskListParams) ([]item.Task, error) FindMany(params TaskListParams) ([]item.Task, error)
Delete(id string) error Delete(id string) error
Projects() (map[string]int, error)
} }
func Match(tsk item.Task, params TaskListParams) bool { func Match(tsk item.Task, params TaskListParams) bool {