-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7dd7a33
commit fd24e5e
Showing
7 changed files
with
115 additions
and
176 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package pkg | ||
|
||
// EndDateable is a simple interface that requires a method to determine if something is end-dated | ||
type EndDateable interface { | ||
EndDated() bool | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,82 +1,32 @@ | ||
package storage | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/calvinmclean/automated-garden/garden-app/pkg" | ||
"github.com/madflojo/hord" | ||
"github.com/rs/xid" | ||
) | ||
|
||
const gardenPrefix = "Garden_" | ||
|
||
func gardenKey(id xid.ID) string { | ||
return gardenPrefix + id.String() | ||
} | ||
|
||
// GetGarden ... | ||
func (c *Client) GetGarden(id xid.ID) (*pkg.Garden, error) { | ||
return c.getGarden(gardenPrefix + id.String()) | ||
return getOne[pkg.Garden](c, gardenKey(id)) | ||
} | ||
|
||
// GetGardens ... | ||
func (c *Client) GetGardens(getEndDated bool) ([]*pkg.Garden, error) { | ||
keys, err := c.db.Keys() | ||
if err != nil { | ||
return nil, fmt.Errorf("error getting keys: %w", err) | ||
} | ||
|
||
results := []*pkg.Garden{} | ||
for _, key := range keys { | ||
if !strings.HasPrefix(key, gardenPrefix) { | ||
continue | ||
} | ||
|
||
result, err := c.getGarden(key) | ||
if err != nil { | ||
return nil, fmt.Errorf("error getting Garden: %w", err) | ||
} | ||
|
||
if getEndDated || !result.EndDated() { | ||
results = append(results, result) | ||
} | ||
} | ||
|
||
return results, nil | ||
return getMultiple[*pkg.Garden](c, getEndDated, gardenPrefix) | ||
} | ||
|
||
// SaveGarden ... | ||
func (c *Client) SaveGarden(g *pkg.Garden) error { | ||
asBytes, err := c.marshal(g) | ||
if err != nil { | ||
return fmt.Errorf("error marshalling Garden: %w", err) | ||
} | ||
|
||
err = c.db.Set(gardenPrefix+g.ID.String(), asBytes) | ||
if err != nil { | ||
return fmt.Errorf("error writing Garden to database: %w", err) | ||
} | ||
|
||
return nil | ||
return save[*pkg.Garden](c, g, gardenKey(g.ID)) | ||
} | ||
|
||
// DeleteGarden ... | ||
func (c *Client) DeleteGarden(id xid.ID) error { | ||
return c.db.Delete(gardenPrefix + id.String()) | ||
} | ||
|
||
func (c *Client) getGarden(key string) (*pkg.Garden, error) { | ||
dataBytes, err := c.db.Get(key) | ||
if err != nil { | ||
if errors.Is(hord.ErrNil, err) { | ||
return nil, nil | ||
} | ||
return nil, fmt.Errorf("error getting Garden: %w", err) | ||
} | ||
|
||
var result pkg.Garden | ||
err = c.unmarshal(dataBytes, &result) | ||
if err != nil { | ||
return nil, fmt.Errorf("error parsing Garden data: %w", err) | ||
} | ||
|
||
return &result, nil | ||
return c.db.Delete(gardenKey(id)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package storage | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/calvinmclean/automated-garden/garden-app/pkg" | ||
"github.com/madflojo/hord" | ||
) | ||
|
||
// getOne will use the provided key to read data from the data source. Then, it will Unmarshal | ||
// into the generic type | ||
func getOne[T any](c *Client, key string) (*T, error) { | ||
dataBytes, err := c.db.Get(key) | ||
if err != nil { | ||
if errors.Is(hord.ErrNil, err) { | ||
return nil, nil | ||
} | ||
return nil, fmt.Errorf("error getting data: %w", err) | ||
} | ||
|
||
var result T | ||
err = c.unmarshal(dataBytes, &result) | ||
if err != nil { | ||
return nil, fmt.Errorf("error parsing data: %w", err) | ||
} | ||
|
||
return &result, nil | ||
} | ||
|
||
// getMultiple will use the provided prefix to read data from the data source. Then, it will use getOne | ||
// to read each element into the correct type. These types must support `pkg.EndDateable` to allow | ||
// excluding end-dated resources | ||
func getMultiple[T pkg.EndDateable](c *Client, getEndDated bool, prefix string) ([]T, error) { | ||
keys, err := c.db.Keys() | ||
if err != nil { | ||
return nil, fmt.Errorf("error getting keys: %w", err) | ||
} | ||
|
||
results := []T{} | ||
for _, key := range keys { | ||
if !strings.HasPrefix(key, prefix) { | ||
continue | ||
} | ||
|
||
result, err := getOne[T](c, key) | ||
if err != nil { | ||
return nil, fmt.Errorf("error getting Garden: %w", err) | ||
} | ||
if result == nil { | ||
continue | ||
} | ||
|
||
if getEndDated || !(*result).EndDated() { | ||
results = append(results, *result) | ||
} | ||
} | ||
|
||
return results, nil | ||
} | ||
|
||
// save marshals the provided item and writes it to the database | ||
func save[T any](c *Client, item T, key string) error { | ||
asBytes, err := c.marshal(item) | ||
if err != nil { | ||
return fmt.Errorf("error marshalling data: %w", err) | ||
} | ||
|
||
err = c.db.Set(key, asBytes) | ||
if err != nil { | ||
return fmt.Errorf("error writing data to database: %w", err) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.