hancock

Check-in [2009980ac3]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:store: introduce Iterable interface Allow processing of every testimony in local store.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 2009980ac346b3e9b5bf58a6a06fc6d24639b64a9b3e872aacd74999c3a9f8f9
User & Date: dnc 2020-01-03 17:20:21
Context
2020-01-03
17:24
cmd/hancock: publish from local to remote store refactor testimony and publish operations, testimony to local (or remote) store, later publish from local to remote check-in: 88140a8c62 user: dnc tags: trunk
17:20
store: introduce Iterable interface Allow processing of every testimony in local store. check-in: 2009980ac3 user: dnc tags: trunk
02:45
cmd/hancock: close store after use check-in: 3ef6a50ce4 user: dnc tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to store/boltstore/boltstore.go.

68
69
70
71
72
73
74


















		} else {
			err = store.NotFound
		}
		return
	})
	return
}

























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
		} else {
			err = store.NotFound
		}
		return
	})
	return
}

func (this *boltStore) ForEach(fn func(model.TestimonyKey, model.Testimony) error) error {
	err := this.DB.View(func(tx *bolt.Tx) error {
		b := tx.Bucket(this.bucket)
		err := b.ForEach(func(k, v []byte) error {
			testimony := new(model.Testimony)
			err := model.Decode(testimony, v)
			if err != nil {
				return err
			}
			key := testimony.Key()
			err = fn(*key, *testimony)
			return err
		})
		return err
	})
	return err
}

Changes to store/store.go.

21
22
23
24
25
26
27


28
29
30
31
32
33
34
35




36
37
38
39
40
41
42
..
63
64
65
66
67
68
69





70
71
72
73
74
75
76
..
80
81
82
83
84
85
86


























	"io/ioutil"
	"os"
	"path/filepath"

	"src.d10.dev/hancock/model"
)



type Store interface {
	PutTestimony(model.Testimony) (*model.TestimonyKey, error)
	GetTestimony(model.TestimonyKey) (*model.Testimony, error)

	Close() error
}

var NotFound error = errors.New("testimony not found")





type fileStore struct {
	directory string
}

func NewFileStore(directory string) fileStore {
	return fileStore{directory: directory}
................................................................................

	return tkey, nil
}

func (this fileStore) GetTestimony(key model.TestimonyKey) (*model.Testimony, error) {

	path := filepath.Join(this.directory, filepath.Join(key.Split()...))





	encoded, err := ioutil.ReadFile(path)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, NotFound
		} else {
			return nil, err
		}
................................................................................
	err = model.Decode(testimony, encoded)
	if err != nil {
		return nil, err
	}

	return testimony, nil
}

































>
>







|
>
>
>
>







 







>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
..
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
..
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
	"io/ioutil"
	"os"
	"path/filepath"

	"src.d10.dev/hancock/model"
)

var NotFound error = errors.New("testimony not found")

type Store interface {
	PutTestimony(model.Testimony) (*model.TestimonyKey, error)
	GetTestimony(model.TestimonyKey) (*model.Testimony, error)

	Close() error
}

// Some stores can produce every key in the store.
type Iterable interface {
	Store
	ForEach(func(model.TestimonyKey, model.Testimony) error) error
}

type fileStore struct {
	directory string
}

func NewFileStore(directory string) fileStore {
	return fileStore{directory: directory}
................................................................................

	return tkey, nil
}

func (this fileStore) GetTestimony(key model.TestimonyKey) (*model.Testimony, error) {

	path := filepath.Join(this.directory, filepath.Join(key.Split()...))
	return decodeTestimonyFile(path)

}

func decodeTestimonyFile(path string) (*model.Testimony, error) {
	encoded, err := ioutil.ReadFile(path)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, NotFound
		} else {
			return nil, err
		}
................................................................................
	err = model.Decode(testimony, encoded)
	if err != nil {
		return nil, err
	}

	return testimony, nil
}

func (this fileStore) ForEach(fn func(model.TestimonyKey, model.Testimony) error) error {
	err := filepath.Walk(this.directory, func(filepath string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() {
			return nil // descend into subdir
		}

		testimony, err := decodeTestimonyFile(filepath)
		if err != nil {
			return err
		}

		key := testimony.Key()
		err = fn(*key, *testimony)
		if err != nil {
			return err
		}

		return nil
	})

	return err
}

Changes to store/store_test.go.

2
3
4
5
6
7
8

9
10
11
12
13
14
15
..
41
42
43
44
45
46
47
48













import (
	"io/ioutil"
	"os"
	"reflect"
	"testing"


	"src.d10.dev/hancock/model/modeltest"
)

func TestFileStore(t *testing.T) {
	testimony, err := modeltest.NewTestTestimony("hello world")
	if err != nil {
		t.Error(err)
................................................................................
	if !reflect.DeepEqual(test, testimony) {
		t.Errorf("got %v, wanted %v; files in %q", test, testimony, dir)
	} else {
		// passed test, clean up
		t.Logf("put, then got, testimony (%v)", k)
		defer os.RemoveAll(dir)
	}
}



















>







 







|
>
>
>
>
>
>
>
>
>
>
>
>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

import (
	"io/ioutil"
	"os"
	"reflect"
	"testing"

	"src.d10.dev/hancock/model"
	"src.d10.dev/hancock/model/modeltest"
)

func TestFileStore(t *testing.T) {
	testimony, err := modeltest.NewTestTestimony("hello world")
	if err != nil {
		t.Error(err)
................................................................................
	if !reflect.DeepEqual(test, testimony) {
		t.Errorf("got %v, wanted %v; files in %q", test, testimony, dir)
	} else {
		// passed test, clean up
		t.Logf("put, then got, testimony (%v)", k)
		defer os.RemoveAll(dir)
	}

	switch s := store.(type) {
	case Iterable:
		s.ForEach(func(key model.TestimonyKey, testimony model.Testimony) error {
			t.Log("iterator got: ", key)

			return nil
		})
	default:
		t.Errorf("FileStore (%T) does not implement store.Iterable", s) // sanity
	}

}