3
3
4
4
module Fabcar where
5
5
6
- import Data.Aeson ( FromJSON
7
- , ToJSON
8
- , decode
9
- , defaultOptions
10
- , encode
11
- , genericToEncoding
12
- , toEncoding
13
- )
14
- import qualified Data.ByteString as BS
15
- import qualified Data.ByteString.Lazy as LBS
16
- import qualified Data.ByteString.UTF8 as BSU
17
- import Data.Text ( Text )
18
-
19
- import Debug.Trace
6
+ import Control.Monad.Except ( ExceptT (.. ), runExceptT , throwError )
7
+
8
+ import Data.Aeson ( FromJSON
9
+ , ToJSON
10
+ , decode
11
+ , defaultOptions
12
+ , encode
13
+ , genericToEncoding
14
+ , toEncoding
15
+ )
16
+ import qualified Data.ByteString as BS
17
+ import qualified Data.ByteString.Lazy as LBS
18
+ import qualified Data.ByteString.UTF8 as BSU
19
+ import Data.Text ( Text , append , pack )
20
+ import qualified Data.Text.Encoding as TSE
21
+ import qualified Data.Text.Lazy as TL
20
22
21
23
import GHC.Generics
22
24
23
- import Peer.ProposalResponse as Pb
25
+ import Ledger.Queryresult.KvQueryResult as Pb
24
26
25
- import Shim ( ChaincodeStub (.. )
26
- , ChaincodeStubInterface (.. )
27
- , DefaultChaincodeStub
28
- , errorPayload
29
- , start
30
- , successPayload
31
- )
27
+ import Peer.ProposalResponse as Pb
28
+
29
+ import Shim ( ChaincodeStub (.. )
30
+ , ChaincodeStubInterface (.. )
31
+ , DefaultChaincodeStub
32
+ , Error (.. )
33
+ , StateQueryIterator (.. )
34
+ , StateQueryIteratorInterface (.. )
35
+ , errorPayload
36
+ , start
37
+ , successPayload
38
+ )
32
39
33
40
main :: IO ()
34
41
main = Shim. start chaincodeStub
@@ -128,13 +135,11 @@ createCars :: DefaultChaincodeStub -> [Text] -> [Car] -> IO Pb.Response
128
135
createCars s keys cars =
129
136
if length cars == 0
130
137
then pure $ successPayload Nothing
131
- else let response = putState s (head keys) (LBS. toStrict $ encode $ head cars)
132
- in
133
- do
134
- e <- response
135
- case e of
136
- Left _ -> pure $ errorPayload " Failed to set asset"
137
- Right _ -> createCars s (tail keys) (tail cars)
138
+ else do
139
+ eitherErrBS <- runExceptT (putState s (head keys) (LBS. toStrict $ encode $ head cars))
140
+ case eitherErrBS of
141
+ Left e -> pure $ errorPayload $ pack $ show e
142
+ Right _ -> createCars s (tail keys) (tail cars)
138
143
139
144
createCar :: DefaultChaincodeStub -> [Text ] -> IO Pb. Response
140
145
createCar s params =
@@ -144,66 +149,44 @@ createCar s params =
144
149
, colour = params !! 3
145
150
, owner = params !! 4
146
151
}
147
- response = putState s (head params) (LBS. toStrict $ encode car)
148
152
in
149
- do
150
- e <- response
151
- case e of
152
- Left _ -> pure $ errorPayload " Failed to set asset"
153
- Right _ -> pure $ successPayload Nothing
153
+ eitherToPbResponse <$> runExceptT (putState s (head params) (LBS. toStrict $ encode car))
154
154
else pure $ errorPayload " Incorrect number of arguments. Expecting 5"
155
155
156
156
queryCar :: DefaultChaincodeStub -> [Text ] -> IO Pb. Response
157
- queryCar s params =
158
- if Prelude. length params == 1
159
- then let response = getState s (head params)
160
- in
161
- do
162
- e <- response
163
- case e of
164
- Left _ -> pure $ errorPayload " Failed to get asset"
165
- Right carBytes -> trace (BSU. toString carBytes) (pure $ successPayload $ Just carBytes)
166
- else pure $ errorPayload " Incorrect number of arguments. Expecting 1"
167
-
168
- -- TODO: requires the getStateByRange stub function
157
+ queryCar s params = if Prelude. length params == 1
158
+ then eitherToPbResponse <$> runExceptT (getState s (head params))
159
+ else pure $ errorPayload " Incorrect number of arguments. Expecting 1"
160
+
169
161
queryAllCars :: DefaultChaincodeStub -> [Text ] -> IO Pb. Response
170
- queryAllCars _ _ = pure $ errorPayload " Not yet implemented"
171
-
172
- -- let
173
- -- startKey = "CAR0"
174
- -- endKey = "CAR999"
175
- -- response = getStateByRange s startKey endKey
176
- -- in do
177
- -- e <- response
178
- -- case e of
179
- -- Left _ -> pure $ errorPayload "Failed to get assets"
180
- -- Right carsBytes -> trace (BSU.toString carsBytes) (pure $ successPayload $ Just carsBytes)
162
+ queryAllCars s params =
163
+ if Prelude. length params == 0
164
+ then eitherToPbResponse <$> (runExceptT $ do
165
+ sqi <- getStateByRange s " " " "
166
+ resultBytes <- generateResultBytes sqi " "
167
+ pure $ successPayload (Just resultBytes))
168
+ else pure $ errorPayload " Incorrect number of arguments. Should be no arguments"
169
+
181
170
changeCarOwner :: DefaultChaincodeStub -> [Text ] -> IO Pb. Response
182
171
changeCarOwner s params =
183
172
if Prelude. length params == 2
184
- then do
185
- -- Check that the car already exists
186
- e <- getState s (head params)
187
- case e of
188
- Left _ -> pure $ errorPayload " Failed to get car"
189
- Right response ->
190
- if BS. length response == 0
191
- then pure $ errorPayload " Car not found"
192
- else
193
- -- Unmarshal the car
194
- let maybeCar = decode (LBS. fromStrict response) :: Maybe Car
195
- newOwner = params !! 1
196
- in
197
- case maybeCar of
198
- Nothing -> pure $ errorPayload " Error decoding car"
199
- Just oldCar -> let newCar = carWithNewOwner oldCar newOwner
200
- carJson = LBS. toStrict $ encode newCar
201
- in
202
- do
203
- ee <- putState s (head params) carJson
204
- case ee of
205
- Left _ -> pure $ errorPayload " Failed to create car"
206
- Right _ -> pure $ successPayload Nothing
173
+ then eitherToPbResponse
174
+ <$> (runExceptT $ do
175
+ -- Check that the car already exists
176
+ response <- getState s (head params)
177
+ if BS. length response == 0
178
+ then throwError $ Error " Car not found"
179
+ else
180
+ -- Unmarshal the car
181
+ let maybeCar = decode (LBS. fromStrict response) :: Maybe Car
182
+ newOwner = params !! 1
183
+ in
184
+ case maybeCar of
185
+ Nothing -> throwError $ Error " Error decoding car"
186
+ Just oldCar -> let newCar = carWithNewOwner oldCar newOwner
187
+ carJson = LBS. toStrict $ encode newCar
188
+ in
189
+ putState s (head params) carJson)
207
190
else pure $ errorPayload " Incorrect arguments. Need a car name and new owner"
208
191
209
192
carWithNewOwner :: Car -> Text -> Car
@@ -213,3 +196,22 @@ carWithNewOwner oldCar newOwner =
213
196
, colour = colour oldCar
214
197
, owner = newOwner
215
198
}
199
+
200
+ eitherToPbResponse :: Show a => Either Error a -> Pb. Response
201
+ eitherToPbResponse (Right a) = successPayload $ Just $ BSU. fromString $ show a
202
+ eitherToPbResponse (Left err) = errorPayload $ pack $ show err
203
+
204
+ generateResultBytes :: StateQueryIterator -> Text -> ExceptT Error IO BSU. ByteString
205
+ generateResultBytes sqi text = ExceptT $ do
206
+ hasNextBool <- hasNext sqi
207
+ if hasNextBool
208
+ then do
209
+ eeKv <- runExceptT $ next sqi
210
+ case eeKv of
211
+ Left e -> pure $ Left e
212
+ Right kv -> let makeKVString :: Pb. KV -> Text
213
+ makeKVString kv_ = pack " Key: " <> TL. toStrict (Pb. kvKey kv_) <> pack " , Value: "
214
+ <> TSE. decodeUtf8 (kvValue kv_)
215
+ in
216
+ runExceptT $ generateResultBytes sqi (append text (makeKVString kv))
217
+ else pure $ Right $ TSE. encodeUtf8 text
0 commit comments