Skip to content

Commit

Permalink
Merge pull request #397 from go-kivik/rdstream
Browse files Browse the repository at this point in the history
Convert RevsDiff to a stream producer
  • Loading branch information
flimzy committed Jun 25, 2019
2 parents 17e1958 + 9eaf85b commit 192e688
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 22 deletions.
20 changes: 13 additions & 7 deletions db.go
Expand Up @@ -661,18 +661,24 @@ type Diffs map[string]RevDiff
// and is normally never needed otherwise. revMap must marshal to the expected
// format.
//
// Uses Rows.ScanValue to access each element in the returned list. The
// value will be of the JSON format:
//
// {
// "{doc_id}": {
// "missing": ["rev1",...],
// "possible_ancestors": ["revA",...]
// }
// }
//
// See http://docs.couchdb.org/en/stable/api/database/misc.html#db-revs-diff
func (db *DB) RevsDiff(ctx context.Context, revMap interface{}) (Diffs, error) {
func (db *DB) RevsDiff(ctx context.Context, revMap interface{}) (*Rows, error) {
if rd, ok := db.driverDB.(driver.RevsDiffer); ok {
result, err := rd.RevsDiff(ctx, revMap)
rowsi, err := rd.RevsDiff(ctx, revMap)
if err != nil {
return nil, err
}
diffs := make(Diffs, len(result))
for k, v := range result {
diffs[k] = RevDiff(v)
}
return diffs, nil
return newRows(ctx, rowsi), nil
}
return nil, &Error{HTTPStatus: http.StatusNotImplemented, Message: "kivik: _revs_diff not supported by driver"}
}
32 changes: 20 additions & 12 deletions db_test.go
Expand Up @@ -1964,10 +1964,11 @@ func TestClientClose(t *testing.T) {

func TestRevsDiff(t *testing.T) {
type tt struct {
db *DB
revMap interface{}
status int
err string
db *DB
revMap interface{}
status int
err string
expected interface{}
}
tests := testy.NewTable()
tests.Add("non-DBReplicator", tt{
Expand All @@ -1977,7 +1978,7 @@ func TestRevsDiff(t *testing.T) {
})
tests.Add("network error", tt{
db: &DB{driverDB: &mock.RevsDiffer{
RevsDiffFunc: func(_ context.Context, revMap interface{}) (map[string]driver.RevDiff, error) {
RevsDiffFunc: func(_ context.Context, revMap interface{}) (driver.Rows, error) {
return nil, errors.New("net error")
},
}},
Expand All @@ -1986,19 +1987,26 @@ func TestRevsDiff(t *testing.T) {
})
tests.Add("success", tt{
db: &DB{driverDB: &mock.RevsDiffer{
RevsDiffFunc: func(_ context.Context, revMap interface{}) (map[string]driver.RevDiff, error) {
return map[string]driver.RevDiff{
"foo": {Missing: []string{"1", "2"}},
"bar": {PossibleAncestors: []string{"3", "4"}},
}, nil
RevsDiffFunc: func(_ context.Context, revMap interface{}) (driver.Rows, error) {
return &mock.Rows{ID: "a"}, nil
},
}},
expected: &Rows{
iter: &iter{
feed: &rowsIterator{
Rows: &mock.Rows{ID: "a"},
},
curVal: &driver.Row{},
},
rowsi: &mock.Rows{ID: "a"},
},
})

tests.Run(t, func(t *testing.T, tt tt) {
result, err := tt.db.RevsDiff(context.Background(), tt.revMap)
rows, err := tt.db.RevsDiff(context.Background(), tt.revMap)
testy.StatusError(t, tt.err, tt.status, err)
if d := diff.AsJSON(&diff.File{Path: "testdata/" + testy.Stub(t)}, result); d != nil {
rows.cancel = nil // Determinism
if d := diff.Interface(tt.expected, rows); d != nil {
t.Error(d)
}
})
Expand Down
4 changes: 3 additions & 1 deletion driver/driver.go
Expand Up @@ -403,5 +403,7 @@ type RevDiff struct {

// RevsDiffer is an optional interface that may be implemented by a DB.
type RevsDiffer interface {
RevsDiff(ctx context.Context, revMap interface{}) (map[string]RevDiff, error)
// RevsDiff returns a Rows iterator, which should populate the Value
// field, and nothing else.
RevsDiff(ctx context.Context, revMap interface{}) (Rows, error)
}
4 changes: 2 additions & 2 deletions mock/db.go
Expand Up @@ -267,12 +267,12 @@ func (db *DBCloser) Close(ctx context.Context) error {
// RevsDiffer mocks a driver.DB and driver.RevsDiffer.
type RevsDiffer struct {
*BulkDocer
RevsDiffFunc func(context.Context, interface{}) (map[string]driver.RevDiff, error)
RevsDiffFunc func(context.Context, interface{}) (driver.Rows, error)
}

var _ driver.RevsDiffer = &RevsDiffer{}

// RevsDiff calls db.RevsDiffFunc
func (db *RevsDiffer) RevsDiff(ctx context.Context, revMap interface{}) (map[string]driver.RevDiff, error) {
func (db *RevsDiffer) RevsDiff(ctx context.Context, revMap interface{}) (driver.Rows, error) {
return db.RevsDiffFunc(ctx, revMap)
}

0 comments on commit 192e688

Please sign in to comment.