Skip to content

Commit

Permalink
[FAB-13089] fetch attachments in CouchDB range queries
Browse files Browse the repository at this point in the history
Using, attachments=true, fetch all attachments in a CouchDB range
queries instead of first obtaining metadata and fetching each attachment
in a separate call.

Change-Id: Ibe51e621d9c49116ebd9fbd866f939eecff326a4
Signed-off-by: ChanderG <mail@chandergovind.org>
  • Loading branch information
ChanderG committed Dec 9, 2018
1 parent f4dad27 commit 8f8d8dc
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 11 deletions.
27 changes: 16 additions & 11 deletions core/ledger/util/couchdb/couchdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,12 @@ type QueryResponse struct {
}

// DocMetadata is used for capturing CouchDB document header info,
// used to capture id, version, rev and determine if attachments are returned in the query from CouchDB
// used to capture id, version, rev and attachments returned in the query from CouchDB
type DocMetadata struct {
ID string `json:"_id"`
Rev string `json:"_rev"`
Version string `json:"~version"`
AttachmentsInfo json.RawMessage `json:"_attachments"`
ID string `json:"_id"`
Rev string `json:"_rev"`
Version string `json:"~version"`
AttachmentsInfo map[string]*AttachmentInfo `json:"_attachments"`
}

//DocID is a minimal structure for capturing the ID from a query result
Expand Down Expand Up @@ -159,9 +159,9 @@ type CreateIndexResponse struct {
//AttachmentInfo contains the definition for an attached file for couchdb
type AttachmentInfo struct {
Name string
ContentType string
ContentType string `json:"content_type"`
Length uint64
AttachmentBytes []byte
AttachmentBytes []byte `json:"data"`
}

//FileDetails defines the structure needed to send an attachment to couchdb
Expand Down Expand Up @@ -881,6 +881,7 @@ func (dbclient *CouchDatabase) ReadDocRange(startKey, endKey string, limit int32
queryParms.Set("limit", strconv.FormatInt(int64(limit+1), 10))
queryParms.Add("include_docs", "true")
queryParms.Add("inclusive_end", "false") // endkey should be exclusive to be consistent with goleveldb
queryParms.Add("attachments", "true") // get the attachments as well

//Append the startKey if provided
if startKey != "" {
Expand Down Expand Up @@ -958,12 +959,14 @@ func (dbclient *CouchDatabase) ReadDocRange(startKey, endKey string, limit int32

logger.Debugf("[%s] Adding JSON document and attachments for id: %s", dbclient.DBName, docMetadata.ID)

couchDoc, _, err := dbclient.ReadDoc(docMetadata.ID)
if err != nil {
return nil, "", err
attachments := []*AttachmentInfo{}
for attachmentName, attachment := range docMetadata.AttachmentsInfo {
attachment.Name = attachmentName

attachments = append(attachments, attachment)
}

var addDocument = &QueryResult{docMetadata.ID, couchDoc.JSONValue, couchDoc.Attachments}
var addDocument = &QueryResult{docMetadata.ID, row.Doc, attachments}
results = append(results, addDocument)

} else {
Expand Down Expand Up @@ -1075,6 +1078,8 @@ func (dbclient *CouchDatabase) QueryDocuments(query string) ([]*QueryResult, str
return nil, "", errors.Wrap(err3, "error unmarshalling json data")
}

// JSON Query results never have attachments
// The If block below will never be executed
if docMetadata.AttachmentsInfo != nil {

logger.Debugf("[%s] Adding JSON docment and attachments for id: %s", dbclient.DBName, docMetadata.ID)
Expand Down
6 changes: 6 additions & 0 deletions core/ledger/util/couchdb/couchdb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,12 @@ func TestRichQuery(t *testing.T) {
//There should be 4 results
assert.Equal(t, 4, len(queryResult))

//Attachments retrieved should be correct
assert.Equal(t, attachment2.AttachmentBytes, queryResult[0].Attachments[0].AttachmentBytes)
assert.Equal(t, attachment3.AttachmentBytes, queryResult[1].Attachments[0].AttachmentBytes)
assert.Equal(t, attachment4.AttachmentBytes, queryResult[2].Attachments[0].AttachmentBytes)
assert.Equal(t, attachment5.AttachmentBytes, queryResult[3].Attachments[0].AttachmentBytes)

//Test query with for tom -------------------------------------------------------------------
queryString = `{"selector":{"owner":{"$eq":"tom"}}}`

Expand Down

0 comments on commit 8f8d8dc

Please sign in to comment.