Skip to content
This repository was archived by the owner on Apr 13, 2022. It is now read-only.

Commit b82ba64

Browse files
author
Nick Waywood
authored
Merge pull request #29 from nwaywood/iterator-methods
Iterator methods
2 parents e26efca + 1e57b16 commit b82ba64

File tree

2 files changed

+33
-18
lines changed

2 files changed

+33
-18
lines changed

examples/marbles/Marbles.hs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import Data.Aeson ( FromJSON
1616
import qualified Data.ByteString as BS
1717
import qualified Data.ByteString.Lazy as LBS
1818
import qualified Data.ByteString.UTF8 as BSU
19+
import Data.Char ( chr )
1920
import Data.Text ( Text, append, pack, unpack )
2021
import qualified Data.Text.Encoding as TSE
2122
import qualified Data.Text.Lazy as TL
@@ -92,7 +93,6 @@ invokeFunc s =
9293
-- queryMarblesWithPagination s parameters
9394
Right (fn, _) -> pure $ errorPayload (pack ("Invoke did not find function: " ++ unpack fn))
9495

95-
-- TODO: implement CreateCompositeKey to index the marble by color
9696
initMarble :: DefaultChaincodeStub -> [Text] -> IO Pb.Response
9797
initMarble s params =
9898
if Prelude.length params == 4
@@ -101,12 +101,19 @@ initMarble s params =
101101
response <- getState s (head params)
102102
-- Check if marble already exists
103103
if BS.length response /= 0
104-
then throwError $ Error $ "This marble already exists: " ++ (unpack $ head params)
105-
else
106-
-- marshal marble to JSON
107-
let marbleJSON = LBS.toStrict $ encode (parseMarble params)
108-
in
109-
putState s (head params) marbleJSON)
104+
then throwError $ Error $ "This marble already exists: " ++ unpack (head params)
105+
else let
106+
-- marshal marble to JSON
107+
marbleJSON = LBS.toStrict $ encode (parseMarble params)
108+
indexName = "color~name"
109+
nullCharByteString = BSU.fromString [ chr 0 ]
110+
in
111+
do
112+
-- we don't care about the response of putState in the success case
113+
_ <- putState s (head params) marbleJSON
114+
colorNameIndexKey
115+
<- ExceptT $ pure $ createCompositeKey s indexName [ params !! 1, params !! 0 ]
116+
putState s colorNameIndexKey nullCharByteString)
110117
else pure $ errorPayload "Incorrect arguments. Need a marble name, color, size and owner"
111118

112119
transferMarble :: DefaultChaincodeStub -> [Text] -> IO Pb.Response

src/Stub.hs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ import qualified Common.Common as Pb
88

99
import Control.Monad.Except ( ExceptT(..), runExceptT, throwError )
1010

11-
-- import Data.Int (fromIntegral)
1211
import Data.Bifunctor
1312
import Data.ByteString as BS
1413
import qualified Data.ByteString.Lazy as LBS
14+
import Data.Char ( chr )
1515
import Data.IORef ( modifyIORef, newIORef, readIORef, writeIORef )
16-
import Data.Text
16+
import Data.Text as TS
1717
import Data.Text.Encoding
1818
import Data.Text.Lazy as TL
1919
import Data.Vector as Vector ( (!), Vector, empty, foldr, length, toList )
@@ -167,26 +167,34 @@ instance ChaincodeStubInterface DefaultChaincodeStub where
167167
runExceptT $ ExceptT (listenForResponse (recvStream ccs)) >>= (bsToSqiAndMeta ccs)
168168

169169
-- TODO: This is the next TODO! Implement these 7 function because they are needed in marbles.hs
170-
-- getStateByPartialCompositeKey :: ccs -> String -> [String] -> Either Error StateQueryIterator
170+
-- getStateByPartialCompositeKey :: ccs -> Text -> [Text] -> Either Error StateQueryIterator
171171
getStateByPartialCompositeKey ccs objectType keys = throwError $ Error "not implemented"
172172

173-
--getStateByPartialCompositeKeyWithPagination :: ccs -> String -> [String] -> Int32 -> String -> Either Error (StateQueryIterator, Pb.QueryResponseMetadata)
173+
--getStateByPartialCompositeKeyWithPagination :: ccs -> Text -> [Text] -> Int32 -> Text -> Either Error (StateQueryIterator, Pb.QueryResponseMetadata)
174174
getStateByPartialCompositeKeyWithPagination ccs objectType keys pageSize bookmark =
175175
throwError $ Error "not implemented"
176176

177-
--createCompositeKey :: ccs -> String -> [String] -> Either Error String
178-
createCompositeKey ccs objectType keys = throwError $ Error "not implemented"
177+
--createCompositeKey :: ccs -> Text -> [Text] -> Either Error Text
178+
createCompositeKey ccs objectType keys =
179+
let keysString = Prelude.foldr (\key acc -> acc ++ TS.unpack key ++ nullCodepoint) "" keys
180+
nullCodepoint = [ chr 0 ]
181+
in
182+
-- TODO: Check that objectTypes and keys are all valid utf8 strings
183+
Right $ TS.pack $ "\x00" ++ TS.unpack objectType ++ nullCodepoint ++ keysString
179184

180-
--splitCompositeKey :: ccs -> String -> Either Error (String, [String])
181-
splitCompositeKey ccs key = throwError $ Error "not implemented"
185+
--splitCompositeKey :: ccs -> Text -> Either Error (Text, [Text])
186+
splitCompositeKey ccs key =
187+
-- key has the form \x00objectTypeU+0000keyU+0000key etc so we use `tail key` to ignore the \x00 char
188+
-- and then split on the unicode codepoint U+0000 to extract the objectType and keys
189+
let keys = TS.splitOn (TS.singleton $ chr 0) (TS.tail key) in Right (Prelude.head keys, Prelude.tail keys)
182190

183-
--getQueryResult :: ccs -> String -> Either Error StateQueryIterator
191+
--getQueryResult :: ccs -> Text -> Either Error StateQueryIterator
184192
getQueryResult ccs query = throwError $ Error "not implemented"
185193

186-
--getQueryResultWithPagination :: ccs -> String -> Int32 -> String -> Either Error (StateQueryIterator, Pb.QueryResponseMetadata)
194+
--getQueryResultWithPagination :: ccs -> Text -> Int32 -> Text -> Either Error (StateQueryIterator, Pb.QueryResponseMetadata)
187195
getQueryResultWithPagination ccs key pageSize bookmark = throwError $ Error "not implemented"
188196

189-
--getHistoryForKey :: ccs -> String -> Either Error HistoryQueryIterator
197+
--getHistoryForKey :: ccs -> Text -> Either Error HistoryQueryIterator
190198
getHistoryForKey ccs key = throwError $ Error "not implemented"
191199

192200
instance StateQueryIteratorInterface StateQueryIterator where

0 commit comments

Comments
 (0)