Skip to content

Commit

Permalink
Append and assets added.
Browse files Browse the repository at this point in the history
  • Loading branch information
cinar committed Dec 22, 2023
1 parent d35ad22 commit b7b5232
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 11 deletions.
37 changes: 32 additions & 5 deletions asset/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,16 @@ The information provided on this project is strictly for informational purposes

- [type FileSystemRepository](<#FileSystemRepository>)
- [func NewFileSystemRepository\(base string\) \*FileSystemRepository](<#NewFileSystemRepository>)
- [func \(r \*FileSystemRepository\) Append\(name string, snapshots \<\-chan \*Snapshot\) error](<#FileSystemRepository.Append>)
- [func \(r \*FileSystemRepository\) Assets\(\) \(\[\]string, error\)](<#FileSystemRepository.Assets>)
- [func \(r \*FileSystemRepository\) Get\(name string\) \(\<\-chan \*Snapshot, error\)](<#FileSystemRepository.Get>)
- [func \(r \*FileSystemRepository\) LastDate\(name string\) \(time.Time, error\)](<#FileSystemRepository.LastDate>)
- [type Repository](<#Repository>)
- [type Snapshot](<#Snapshot>)


<a name="FileSystemRepository"></a>
## type [FileSystemRepository](<https://github.com/cinar/indicator/blob/v2/asset/file_system_repository.go#L18-L23>)
## type [FileSystemRepository](<https://github.com/cinar/indicator/blob/v2/asset/file_system_repository.go#L20-L25>)

FileSystemRepository stores and retrieves asset snapshots using the local file system.

Expand All @@ -45,16 +47,34 @@ type FileSystemRepository struct {
```

<a name="NewFileSystemRepository"></a>
### func [NewFileSystemRepository](<https://github.com/cinar/indicator/blob/v2/asset/file_system_repository.go#L27>)
### func [NewFileSystemRepository](<https://github.com/cinar/indicator/blob/v2/asset/file_system_repository.go#L29>)

```go
func NewFileSystemRepository(base string) *FileSystemRepository
```

NewFileSystemRepository initializes a file system repository with the given base directory.

<a name="FileSystemRepository.Append"></a>
### func \(\*FileSystemRepository\) [Append](<https://github.com/cinar/indicator/blob/v2/asset/file_system_repository.go#L79>)

```go
func (r *FileSystemRepository) Append(name string, snapshots <-chan *Snapshot) error
```

Append adds the given snapshows to the asset with the given name.

<a name="FileSystemRepository.Assets"></a>
### func \(\*FileSystemRepository\) [Assets](<https://github.com/cinar/indicator/blob/v2/asset/file_system_repository.go#L36>)

```go
func (r *FileSystemRepository) Assets() ([]string, error)
```

Assets returns the names of all assets in the repository.

<a name="FileSystemRepository.Get"></a>
### func \(\*FileSystemRepository\) [Get](<https://github.com/cinar/indicator/blob/v2/asset/file_system_repository.go#L34>)
### func \(\*FileSystemRepository\) [Get](<https://github.com/cinar/indicator/blob/v2/asset/file_system_repository.go#L57>)

```go
func (r *FileSystemRepository) Get(name string) (<-chan *Snapshot, error)
Expand All @@ -63,7 +83,7 @@ func (r *FileSystemRepository) Get(name string) (<-chan *Snapshot, error)
Get attempts to return a channel of snapshots fo the asset with the given name.

<a name="FileSystemRepository.LastDate"></a>
### func \(\*FileSystemRepository\) [LastDate](<https://github.com/cinar/indicator/blob/v2/asset/file_system_repository.go#L40>)
### func \(\*FileSystemRepository\) [LastDate](<https://github.com/cinar/indicator/blob/v2/asset/file_system_repository.go#L62>)

```go
func (r *FileSystemRepository) LastDate(name string) (time.Time, error)
Expand All @@ -72,19 +92,26 @@ func (r *FileSystemRepository) LastDate(name string) (time.Time, error)
LastDate returns the date of the last snapshot for the asset with the given name.

<a name="Repository"></a>
## type [Repository](<https://github.com/cinar/indicator/blob/v2/asset/repository.go#L11-L19>)
## type [Repository](<https://github.com/cinar/indicator/blob/v2/asset/repository.go#L11-L26>)

Repository serves as a centralized storage and retrieval location for asset snapshots.

```go
type Repository interface {
// Assets returns the names of all assets in the repository.
Assets() ([]string, error)

// Get attempts to return a channel of snapshots for
// the asset with the given name.
Get(name string) (<-chan *Snapshot, error)

// LastDate returns the date of the last snapshot for
// the asset with the given name.
LastDate(name string) (time.Time, error)

// Append adds the given snapshows to the asset with the
// given name.
Append(name string, snapshots <-chan *Snapshot) error
}
```

Expand Down
43 changes: 37 additions & 6 deletions asset/file_system_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ package asset
import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"time"

"github.com/cinar/indicator/helper"
Expand All @@ -30,10 +32,30 @@ func NewFileSystemRepository(base string) *FileSystemRepository {
}
}

// Assets returns the names of all assets in the repository.
func (r *FileSystemRepository) Assets() ([]string, error) {
files, err := os.ReadDir(r.base)
if err != nil {
return nil, err
}

var assets []string
suffix := ".csv"

for _, file := range files {
name := file.Name()

if strings.HasSuffix(name, suffix) {
assets = append(assets, strings.TrimSuffix(name, suffix))
}
}

return assets, nil
}

// Get attempts to return a channel of snapshots fo the asset with the given name.
func (r *FileSystemRepository) Get(name string) (<-chan *Snapshot, error) {
file := filepath.Join(r.base, fmt.Sprintf("%s.csv", name))
return helper.ReadFromCsvFile[Snapshot](file, true)
return helper.ReadFromCsvFile[Snapshot](r.getCsvFileName(name), true)
}

// LastDate returns the date of the last snapshot for the asset with the given name.
Expand All @@ -45,11 +67,20 @@ func (r *FileSystemRepository) LastDate(name string) (time.Time, error) {
return last, err
}

snapshot := helper.ChanToSlice(helper.Last(snapshots, 1))

if len(snapshot) != 1 {
snapshot, ok := <-helper.Last(snapshots, 1)
if !ok {
return last, errors.New("empty asset")
}

return snapshot[0].Date, nil
return snapshot.Date, nil
}

// Append adds the given snapshows to the asset with the given name.
func (r *FileSystemRepository) Append(name string, snapshots <-chan *Snapshot) error {
return helper.AppendOrWriteToCsvFile(r.getCsvFileName(name), true, snapshots)
}

// getCsvFileName gets the CSV file name for the given asset name.
func (r *FileSystemRepository) getCsvFileName(name string) string {
return filepath.Join(r.base, fmt.Sprintf("%s.csv", name))
}
58 changes: 58 additions & 0 deletions asset/file_system_repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,39 @@
package asset_test

import (
"fmt"
"os"
"reflect"
"testing"
"time"

"github.com/cinar/indicator/asset"
"github.com/cinar/indicator/helper"
)

func TestFileSystemRepositoryAssets(t *testing.T) {
repository := asset.NewFileSystemRepository("testdata")
expected := []string{"brk-b", "empty"}

actual, err := repository.Assets()
if err != nil {
t.Fatal(err)
}

if !reflect.DeepEqual(actual, expected) {
t.Fatalf("actual %v expected %v", actual, expected)
}
}

func TestFileSystemRepositoryAssetsNonExisting(t *testing.T) {
repository := asset.NewFileSystemRepository("testdata/non_existing")

_, err := repository.Assets()
if err == nil {
t.Fatal("expected error")
}
}

func TestFileSystemRepositoryGet(t *testing.T) {
repository := asset.NewFileSystemRepository("testdata")

Expand Down Expand Up @@ -64,3 +90,35 @@ func TestFileSystemRepositoryLastDateEmpty(t *testing.T) {
t.Fatal("expected error")
}
}

func TestFileSystemRepositoryAppend(t *testing.T) {
repository := asset.NewFileSystemRepository("testdata")

expected, err := repository.Get("brk-b")
if err != nil {
t.Fatal(err)
}

name := "test_file_system_repository_append"
defer os.Remove(fmt.Sprintf("testdata/%s.csv", name))

err = repository.Append(name, expected)
if err != nil {
t.Fatal(err)
}

expected, err = repository.Get("brk-b")
if err != nil {
t.Fatal(err)
}

actual, err := repository.Get(name)
if err != nil {
t.Fatal(err)
}

err = helper.CheckEquals(actual, expected)
if err != nil {
t.Fatal(err)
}
}
7 changes: 7 additions & 0 deletions asset/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,18 @@ import "time"
// Repository serves as a centralized storage and retrieval
// location for asset snapshots.
type Repository interface {
// Assets returns the names of all assets in the repository.
Assets() ([]string, error)

// Get attempts to return a channel of snapshots for
// the asset with the given name.
Get(name string) (<-chan *Snapshot, error)

// LastDate returns the date of the last snapshot for
// the asset with the given name.
LastDate(name string) (time.Time, error)

// Append adds the given snapshows to the asset with the
// given name.
Append(name string, snapshots <-chan *Snapshot) error
}

0 comments on commit b7b5232

Please sign in to comment.