diff --git a/db_internal_test.go b/db_internal_test.go index 6b8f748..4d217ed 100644 --- a/db_internal_test.go +++ b/db_internal_test.go @@ -136,21 +136,25 @@ func TestReadAndWriteStatuses(t *testing.T) { ID: -1, Name: "Backlog", CardIds: []int{1, 14, 9, 10}, + Order: 1, }, { ID: -1, Name: "Next", CardIds: []int{2, 5, 12}, + Order: 2, }, { ID: -1, Name: "In progress", CardIds: []int{3}, + Order: 3, }, { ID: -1, Name: "Finished!", CardIds: []int{4, 6, 7, 8, 11, 13}, + Order: 4, }, } @@ -172,6 +176,7 @@ func TestReadAndWriteStatuses(t *testing.T) { ID: -1, Name: "Archived", CardIds: []int{34, 51, 894}, + Order: 5, } modifiedStatusList = append(modifiedStatusList, archiveStatus) @@ -186,26 +191,31 @@ func TestReadAndWriteStatuses(t *testing.T) { ID: 1, Name: "Backlog", CardIds: []int{1, 14, 9, 10}, + Order: 1, }, { ID: 2, Name: "Next", CardIds: []int{2, 5, 12}, + Order: 2, }, { ID: 3, Name: "In progress", CardIds: []int{3, 14}, + Order: 3, }, { ID: 4, Name: "Finished!", CardIds: []int{4, 6, 7, 8, 11, 13}, + Order: 4, }, { ID: 5, Name: "Archived", CardIds: []int{34, 51, 894}, + Order: 5, }, } diff --git a/kanban.go b/kanban.go index ece220b..37ccb8e 100644 --- a/kanban.go +++ b/kanban.go @@ -1,11 +1,11 @@ package main -// Status represents the status of the Kanban board. -type Status struct { - ID int - Name string - CardIds []int -} +import ( + "fmt" + "sort" + + bolt "go.etcd.io/bbolt" +) // Card represents a card on a Kanban board. type Card struct { @@ -13,3 +13,68 @@ type Card struct { Title string Content string } + +// Status represents the status of the Kanban board. +type Status struct { + ID int + Name string + CardIds []int + Order int +} + +// ByStatusOrder implements sort.Interface for []Status based on the Order field. +type ByStatusOrder []Status + +func (s ByStatusOrder) Len() int { + return len(s) +} + +func (s ByStatusOrder) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s ByStatusOrder) Less(i, j int) bool { + return s[i].Order < s[j].Order +} + +// readStatuses reads all statuses from the database. If there are no statuses in the database then the default +// status list is created and stored in the database. Before returning the status list, the list is ordered based +// on the status' 'Order' field. +// TODO: function needs to be unit tested. +func readStatuses(db *bolt.DB) ([]Status, error) { + statuses, err := loadAllStatuses(db) + if err != nil { + return statuses, fmt.Errorf("unable to read statuses, %w", err) + } + + if len(statuses) == 0 { + if err := createDefaultStatusList(db); err != nil { + return statuses, fmt.Errorf("unable to create the default statuses, %w", err) + } + readStatuses(db) + } + + sort.Sort(ByStatusOrder(statuses)) + + return statuses, nil +} + +// createDefaultStatusList creates the default list of statuses and saves the statuses to the database. +func createDefaultStatusList(db *bolt.DB) error { + s := []Status{ + { + Name: "To Do", + Order: 1, + }, + { + Name: "Doing", + Order: 2, + }, + { + Name: "Done", + Order: 3, + }, + } + + return saveStatuses(db, s) +}