Skip to content

Commit

Permalink
Merge "Fix composite key range queries on CouchDB"
Browse files Browse the repository at this point in the history
  • Loading branch information
Srinivasan Muralidharan authored and Gerrit Code Review committed Jan 30, 2017
2 parents decb6d3 + e5bd121 commit 886f6bc
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 20 deletions.
34 changes: 17 additions & 17 deletions core/chaincode/shim/chaincode.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,20 @@ limitations under the License.
package shim

import (
"bytes"
"errors"
"flag"
"fmt"
"io"
"os"
"regexp"
"strconv"
"strings"

"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes/timestamp"
"github.com/hyperledger/fabric/common/util"
"github.com/hyperledger/fabric/core/comm"
coder "github.com/hyperledger/fabric/core/ledger/util"
pb "github.com/hyperledger/fabric/protos/peer"
"github.com/op/go-logging"
"github.com/spf13/viper"
Expand Down Expand Up @@ -356,14 +358,14 @@ func (stub *ChaincodeStub) CreateCompositeKey(objectType string, attributes []st
}

func createCompositeKey(stub ChaincodeStubInterface, objectType string, attributes []string) (string, error) {
var compositeKey []byte
compositeKey = append(compositeKey, coder.EncodeOrderPreservingVarUint64(uint64(len(objectType)))...)
compositeKey = append(compositeKey, []byte(objectType)...)
var compositeKey bytes.Buffer
replacer := strings.NewReplacer("\x1E", "\x1E\x1E", "\x1F", "\x1E\x1F")
compositeKey.WriteString(replacer.Replace(objectType))
for _, attribute := range attributes {
compositeKey = append(compositeKey, coder.EncodeOrderPreservingVarUint64(uint64(len(attribute)))...)
compositeKey = append(compositeKey, []byte(attribute)...)
compositeKey.WriteString("\x1F" + strconv.Itoa(len(attribute)) + "\x1F")
compositeKey.WriteString(replacer.Replace(attribute))
}
return string(compositeKey), nil
return compositeKey.String(), nil
}

//Given a composite key, SplitCompositeKey function splits the key into attributes
Expand All @@ -373,17 +375,15 @@ func (stub *ChaincodeStub) SplitCompositeKey(compositeKey string) (string, []str
}

func splitCompositeKey(stub ChaincodeStubInterface, compositeKey string) (string, []string, error) {
startIndex := 0
cKey := []byte(compositeKey)
attributes := []string{}
for startIndex < len(compositeKey) {
len, bytesConsumed := coder.DecodeOrderPreservingVarUint64(cKey[startIndex:])
attrBeginIndex := startIndex + int(bytesConsumed)
attrEndIndex := attrBeginIndex + int(len)
attributes = append(attributes, compositeKey[attrBeginIndex:attrEndIndex])
startIndex = attrEndIndex
re := regexp.MustCompile("\x1F[0-9]+\x1F")
splittedKey := re.Split(compositeKey, -1)
attributes := make([]string, 0)
replacer := strings.NewReplacer("\x1E\x1F", "\x1F", "\x1E\x1E", "\x1E")
objectType := replacer.Replace(splittedKey[0])
for _, attr := range splittedKey[1:] {
attributes = append(attributes, replacer.Replace(attr))
}
return attributes[0], attributes[1:], nil
return objectType, attributes, nil
}

//PartialCompositeKeyQuery function can be invoked by a chaincode to query the
Expand Down
16 changes: 13 additions & 3 deletions core/ledger/util/couchdb/couchdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -645,15 +645,25 @@ func (dbclient *CouchDatabase) ReadDocRange(startKey, endKey string, limit, skip
//Append the startKey if provided
if startKey != "" {
startKey = strconv.QuoteToGraphic(startKey)
startKey = strings.Replace(startKey, "\\x00", "\\u0000", 1)
startKey = strings.Replace(startKey, "\\x00", "\\u0000", -1)
startKey = strings.Replace(startKey, "\\x1e", "\\u001e", -1)
startKey = strings.Replace(startKey, "\\x1f", "\\u001f", -1)
startKey = strings.Replace(startKey, "\\xff", "\\u00ff", -1)
//TODO add general unicode support instead of special cases

queryParms.Add("startkey", startKey)
}

//Append the endKey if provided
if endKey != "" {
endKey = strconv.QuoteToGraphic(endKey)
endKey = strings.Replace(endKey, "\\x00", "\\u0000", 1)
endKey = strings.Replace(endKey, "\\x01", "\\u0001", 1) //TODO add general unicode support instead of special cases
endKey = strings.Replace(endKey, "\\x00", "\\u0000", -1)
endKey = strings.Replace(endKey, "\\x01", "\\u0001", -1)
endKey = strings.Replace(endKey, "\\x1e", "\\u001e", -1)
endKey = strings.Replace(endKey, "\\x1f", "\\u001f", -1)
endKey = strings.Replace(endKey, "\\xff", "\\u00ff", -1)
//TODO add general unicode support instead of special cases

queryParms.Add("endkey", endKey)
}

Expand Down

0 comments on commit 886f6bc

Please sign in to comment.