Skip to content

Commit

Permalink
Add history
Browse files Browse the repository at this point in the history
  • Loading branch information
gjhenrique committed Jan 15, 2023
1 parent 1bdfbce commit fb0c6d5
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 0 deletions.
100 changes: 100 additions & 0 deletions store/history.go
Original file line number Diff line number Diff line change
@@ -1 +1,101 @@
package store

import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sort"
"strconv"
)

type HistoryStore struct {
Dir string
}

func formatEntry(entryKey []byte, n int) []byte {
e := append(entryKey, "\t"...)
return append(e, strconv.Itoa(n)...)

}

func (h *HistoryStore) fileName(modeKey string) string {
return filepath.Join(h.Dir, fmt.Sprintf("%s_history", modeKey))
}

func (h *HistoryStore) ListEntries(modeKey string) ([][]byte, error) {
fileContent, err := ioutil.ReadFile(h.fileName(modeKey))
fields := bytes.Split(fileContent, []byte("\n"))
s := make([][]byte, 0)

if err != nil {
if errors.Is(err, os.ErrNotExist) {
return s, nil
} else {
return nil, err
}
}

for _, field := range fields {
arr := bytes.Split(field, []byte("\t"))
first := arr[0]
if len(first) > 0 {
s = append(s, first)
}
}

return s, nil
}

func (h *HistoryStore) IncrementEntry(modeKey string, entryKey []byte) error {
fileContent, err := ioutil.ReadFile(h.fileName(modeKey))

if err != nil {
if errors.Is(err, os.ErrNotExist) {
fileContent = make([]byte, 0)
} else {
return err
}
}

fields := bytes.Split(fileContent, []byte("\n"))
var found bool

for i, field := range fields {
arr := bytes.Split(field, []byte("\t"))
first := arr[0]
if bytes.Compare(first, []byte(entryKey)) == 0 {
found = true

last := arr[len(arr)-1]
n, err := strconv.Atoi(string(last))

if err != nil {
n = 0
}

fields[i] = formatEntry(entryKey, n+1)
}
}

if !found {
entry := formatEntry(entryKey, 1)
fields = append(fields, entry)
}

sort.SliceStable(fields, func(i, j int) bool {
arr1 := bytes.Split(fields[i], []byte("\t"))
a, _ := strconv.Atoi(string(arr1[len(arr1)-1]))

arr2 := bytes.Split(fields[j], []byte("\t"))
b, _ := strconv.Atoi(string(arr2[len(arr2)-1]))

return a > b
})

finalFields := bytes.Join(fields, []byte("\n"))

return ioutil.WriteFile(h.fileName(modeKey), finalFields, 0644)
}
43 changes: 43 additions & 0 deletions store/history_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package store

import (
"testing"

"github.com/gjhenrique/yafl/internal/test"
"github.com/stretchr/testify/require"
)

func TestOrderIsMaintained(t *testing.T) {
workspace := test.SetupWorkspace(t)
defer workspace.RemoveWorkspace()

store := HistoryStore{Dir: workspace.CacheDir}

err := store.IncrementEntry("key", []byte("a"))
require.NoError(t, err)
err = store.IncrementEntry("key", []byte("b"))
require.NoError(t, err)
err = store.IncrementEntry("key", []byte("c"))
require.NoError(t, err)
err = store.IncrementEntry("key", []byte("b"))
require.NoError(t, err)

entries, err := store.ListEntries("key")
require.NoError(t, err)

require.Len(t, entries, 3)
require.Equal(t, string(entries[0]), "b")
require.Equal(t, string(entries[1]), "a")
require.Equal(t, string(entries[2]), "c")
}

func TestEmptyArrayWhenFileDoesNotExist(t *testing.T) {
workspace := test.SetupWorkspace(t)
defer workspace.RemoveWorkspace()

store := HistoryStore{Dir: workspace.CacheDir}

entries, err := store.ListEntries("key")
require.NoError(t, err)
require.Len(t, entries, 0)
}

0 comments on commit fb0c6d5

Please sign in to comment.