pelican/internal/board/board.go
Dan Anglin cf7c61637f
chore: update project
- update dependencies.
- a little bit of project restructuring.
- update test to make sure they pass.
- move magefile.go to magefiles directory.
2023-04-22 06:19:50 +01:00

218 lines
4.7 KiB
Go

package board
import (
"bytes"
"encoding/gob"
"fmt"
"sort"
"codeflow.dananglin.me.uk/apollo/canal/internal/database"
bolt "go.etcd.io/bbolt"
)
// OpenProject reads the project from the database. If no board exists then a new one will be created.
func OpenProject(path string) (*bolt.DB, error) {
db, err := database.OpenDatabase(path)
if err != nil {
return nil, fmt.Errorf("unable to open the database, %w", err)
}
statusList, err := ReadStatusList(db)
if err != nil {
return nil, err
}
if len(statusList) == 0 {
newStatusList := defaultStatusList()
boltItems := make([]database.BoltItem, len(newStatusList))
for i := range newStatusList {
boltItems[i] = &newStatusList[i]
}
if _, err := database.WriteMany(db, database.StatusBucket, boltItems); err != nil {
return nil, fmt.Errorf("unable to save the default status list to the database, %w", err)
}
}
return db, nil
}
// ReadStatusList returns the ordered list of statuses from the database.
func ReadStatusList(db *bolt.DB) ([]Status, error) {
data, err := database.ReadAll(db, database.StatusBucket)
if err != nil {
return []Status{}, fmt.Errorf("unable to read the status list, %w", err)
}
statuses := make([]Status, len(data))
for i, d := range data {
buf := bytes.NewBuffer(d)
decoder := gob.NewDecoder(buf)
var s Status
if err := decoder.Decode(&s); err != nil {
return []Status{}, fmt.Errorf("unable to decode data, %w", err)
}
statuses[i] = s
}
sort.Sort(ByStatusOrder(statuses))
return statuses, nil
}
// TODO: Finish implementation.
func ReadStatus(db *bolt.DB) (Status, error) {
return Status{}, nil
}
// TODO: Finish implementation.
func CreateStatus(db *bolt.DB) error {
return nil
}
// TODO: Finish implementation.
func UpdateStatus(db *bolt.DB) error {
return nil
}
// TODO: Finish implementation.
func DeleteStatus(db *bolt.DB) error {
return nil
}
type CardArgs struct {
NewTitle string
NewContent string
}
// CreateCard creates a card in the database.
func CreateCard(db *bolt.DB, args CardArgs) error {
statusList, err := ReadStatusList(db)
if err != nil {
return fmt.Errorf("unable to read the status list, %w", err)
}
if len(statusList) == 0 {
return statusListEmptyError{}
}
card := Card{
ID: -1,
Title: args.NewTitle,
Content: args.NewContent,
}
cardID, err := database.Write(db, database.CardBucket, &card)
if err != nil {
return fmt.Errorf("unable to write card to the database, %w", err)
}
initialStatus := statusList[0]
initialStatus.AddCardID(cardID)
if _, err := database.Write(db, database.StatusBucket, &initialStatus); err != nil {
return fmt.Errorf("unable to write the %s status to the database, %w", initialStatus.Name, err)
}
return nil
}
// ReadCard returns a Card value from the database.
func ReadCard(db *bolt.DB, id int) (Card, error) {
data, err := database.Read(db, database.CardBucket, id)
if err != nil {
return Card{}, fmt.Errorf("unable to read card [%d] from the database, %w", id, err)
}
var card Card
buf := bytes.NewBuffer(data)
decoder := gob.NewDecoder(buf)
if err := decoder.Decode(&card); err != nil {
return Card{}, fmt.Errorf("unable to decode data, %w", err)
}
return card, nil
}
// ReadCardList returns a list of Card values from the database.
// TODO: function needs testing.
func ReadCardList(db *bolt.DB, ids []int) ([]Card, error) {
data, err := database.ReadMany(db, database.CardBucket, ids)
if err != nil {
return nil, fmt.Errorf("unable to read card list from the database, %w", err)
}
cards := make([]Card, len(data))
for i, d := range data {
buf := bytes.NewBuffer(d)
decoder := gob.NewDecoder(buf)
var c Card
if err := decoder.Decode(&c); err != nil {
return nil, fmt.Errorf("unable to decode data, %w", err)
}
cards[i] = c
}
return cards, nil
}
type UpdateCardArgs struct {
CardID int
CardArgs
}
// UpdateCard modifies an existing card in the database.
func UpdateCard(db *bolt.DB, args UpdateCardArgs) error {
card, err := ReadCard(db, args.CardID)
if err != nil {
return err
}
if len(args.NewTitle) > 0 {
card.Title = args.NewTitle
}
if len(args.NewContent) > 0 {
card.Content = args.NewContent
}
if _, err := database.Write(db, database.CardBucket, &card); err != nil {
return fmt.Errorf("unable to write card to the database, %w", err)
}
return nil
}
type UpdateCardStatusArgs struct {
CardID int
OldStatusID int
NewStatusID int
}
// UpdateCardStatus moves a card between statuses.
// TODO: finish implementation.
func UpdateCardStatus(db *bolt.DB, args UpdateCardStatusArgs) error {
return nil
}
// DeleteCard deletes a card from the database.
// TODO: finish implementation.
func DeleteCard(db *bolt.DB, id int) error {
return nil
}