{-# LANGUAGE UndecidableInstances #-}
module Tendermint.SDK.BaseApp.Query.Store
( StoreLeaf
, storeQueryHandler
) where
import Data.ByteArray.Base64String (fromBytes)
import Data.Proxy
import Data.Word (Word64)
import Polysemy (Member, Members, Sem)
import Polysemy.Error (throw)
import Polysemy.Tagged (Tagged)
import Servant.API ((:>))
import Tendermint.SDK.BaseApp.Errors (makeAppError)
import Tendermint.SDK.BaseApp.Query.Effect (QueryEffs)
import Tendermint.SDK.BaseApp.Query.Router (HasQueryRouter (..))
import Tendermint.SDK.BaseApp.Query.Types (Leaf, QA, QueryArgs (..),
QueryData,
QueryResult (..))
import Tendermint.SDK.BaseApp.Router (RouterError (..))
import Tendermint.SDK.BaseApp.Store (RawKey (..), ReadStore,
Scope (..), makeKeyBytes)
import qualified Tendermint.SDK.BaseApp.Store.Array as A
import qualified Tendermint.SDK.BaseApp.Store.List as L
import qualified Tendermint.SDK.BaseApp.Store.Map as M
import qualified Tendermint.SDK.BaseApp.Store.Var as V
import Tendermint.SDK.Codec (HasCodec)
data StoreLeaf a
instance (QueryData k, HasCodec v, Member (Tagged 'QueryAndMempool ReadStore) r) => HasQueryRouter (StoreLeaf (M.Map k v)) r where
type RouteQ (StoreLeaf (M.Map k v)) r = RouteQ (QA k :> Leaf v) r
routeQ :: Proxy (StoreLeaf (Map k v))
-> Proxy r
-> Delayed
(Sem r)
env
QueryRequest
(RouteQ (StoreLeaf (Map k v)) (QueryEffs :& r))
-> Router env r QueryRequest Query
routeQ _ = Proxy (QA k :> Leaf v)
-> Proxy r
-> Delayed
(Sem r) env QueryRequest (RouteQ (QA k :> Leaf v) (QueryEffs :& r))
-> Router env r QueryRequest Query
forall k (layout :: k) (r :: EffectRow) env.
HasQueryRouter layout r =>
Proxy layout
-> Proxy r
-> Delayed
(Sem r) env QueryRequest (RouteQ layout (QueryEffs :& r))
-> Router env r QueryRequest Query
routeQ (Proxy (QA k :> Leaf v)
forall k (t :: k). Proxy t
Proxy @(QA k :> Leaf v))
hoistQueryRouter :: Proxy (StoreLeaf (Map k v))
-> Proxy r
-> (forall a. Sem s a -> Sem s' a)
-> RouteQ (StoreLeaf (Map k v)) s
-> RouteQ (StoreLeaf (Map k v)) s'
hoistQueryRouter _ pr :: Proxy r
pr nat :: forall a. Sem s a -> Sem s' a
nat f :: RouteQ (StoreLeaf (Map k v)) s
f = Proxy (QA k :> Leaf v)
-> Proxy r
-> (forall a. Sem s a -> Sem s' a)
-> RouteQ (QA k :> Leaf v) s
-> RouteQ (QA k :> Leaf v) s'
forall k (layout :: k) (r :: EffectRow) (s :: EffectRow)
(s' :: EffectRow).
HasQueryRouter layout r =>
Proxy layout
-> Proxy r
-> (forall a. Sem s a -> Sem s' a)
-> RouteQ layout s
-> RouteQ layout s'
hoistQueryRouter (Proxy (QA k :> Leaf v)
forall k (t :: k). Proxy t
Proxy @(QA k :> Leaf v)) Proxy r
pr forall a. Sem s a -> Sem s' a
nat RouteQ (QA k :> Leaf v) s
RouteQ (StoreLeaf (Map k v)) s
f
instance (HasCodec a, Member (Tagged 'QueryAndMempool ReadStore) r) => HasQueryRouter (StoreLeaf (V.Var a)) r where
type RouteQ (StoreLeaf (V.Var a)) r = RouteQ (QA () :> Leaf a) r
routeQ :: Proxy (StoreLeaf (Var a))
-> Proxy r
-> Delayed
(Sem r)
env
QueryRequest
(RouteQ (StoreLeaf (Var a)) (QueryEffs :& r))
-> Router env r QueryRequest Query
routeQ _ = Proxy (QA () :> Leaf a)
-> Proxy r
-> Delayed
(Sem r)
env
QueryRequest
(RouteQ (QA () :> Leaf a) (QueryEffs :& r))
-> Router env r QueryRequest Query
forall k (layout :: k) (r :: EffectRow) env.
HasQueryRouter layout r =>
Proxy layout
-> Proxy r
-> Delayed
(Sem r) env QueryRequest (RouteQ layout (QueryEffs :& r))
-> Router env r QueryRequest Query
routeQ (Proxy (QA () :> Leaf a)
forall k (t :: k). Proxy t
Proxy @(QA () :> Leaf a))
hoistQueryRouter :: Proxy (StoreLeaf (Var a))
-> Proxy r
-> (forall a. Sem s a -> Sem s' a)
-> RouteQ (StoreLeaf (Var a)) s
-> RouteQ (StoreLeaf (Var a)) s'
hoistQueryRouter _ pr :: Proxy r
pr nat :: forall a. Sem s a -> Sem s' a
nat f :: RouteQ (StoreLeaf (Var a)) s
f = Proxy (QA () :> Leaf a)
-> Proxy r
-> (forall a. Sem s a -> Sem s' a)
-> RouteQ (QA () :> Leaf a) s
-> RouteQ (QA () :> Leaf a) s'
forall k (layout :: k) (r :: EffectRow) (s :: EffectRow)
(s' :: EffectRow).
HasQueryRouter layout r =>
Proxy layout
-> Proxy r
-> (forall a. Sem s a -> Sem s' a)
-> RouteQ layout s
-> RouteQ layout s'
hoistQueryRouter (Proxy (QA () :> Leaf a)
forall k (t :: k). Proxy t
Proxy @(QA () :> Leaf a)) Proxy r
pr forall a. Sem s a -> Sem s' a
nat RouteQ (QA () :> Leaf a) s
RouteQ (StoreLeaf (Var a)) s
f
instance (HasCodec a, Member (Tagged 'QueryAndMempool ReadStore) r) => HasQueryRouter (StoreLeaf (A.Array a)) r where
type RouteQ (StoreLeaf (A.Array a)) r = RouteQ (QA Word64 :> Leaf a) r
routeQ :: Proxy (StoreLeaf (Array a))
-> Proxy r
-> Delayed
(Sem r)
env
QueryRequest
(RouteQ (StoreLeaf (Array a)) (QueryEffs :& r))
-> Router env r QueryRequest Query
routeQ _ = Proxy (QA Word64 :> Leaf a)
-> Proxy r
-> Delayed
(Sem r)
env
QueryRequest
(RouteQ (QA Word64 :> Leaf a) (QueryEffs :& r))
-> Router env r QueryRequest Query
forall k (layout :: k) (r :: EffectRow) env.
HasQueryRouter layout r =>
Proxy layout
-> Proxy r
-> Delayed
(Sem r) env QueryRequest (RouteQ layout (QueryEffs :& r))
-> Router env r QueryRequest Query
routeQ (Proxy (QA Word64 :> Leaf a)
forall k (t :: k). Proxy t
Proxy @(QA Word64 :> Leaf a))
hoistQueryRouter :: Proxy (StoreLeaf (Array a))
-> Proxy r
-> (forall a. Sem s a -> Sem s' a)
-> RouteQ (StoreLeaf (Array a)) s
-> RouteQ (StoreLeaf (Array a)) s'
hoistQueryRouter _ pr :: Proxy r
pr nat :: forall a. Sem s a -> Sem s' a
nat f :: RouteQ (StoreLeaf (Array a)) s
f = Proxy (QA Word64 :> Leaf a)
-> Proxy r
-> (forall a. Sem s a -> Sem s' a)
-> RouteQ (QA Word64 :> Leaf a) s
-> RouteQ (QA Word64 :> Leaf a) s'
forall k (layout :: k) (r :: EffectRow) (s :: EffectRow)
(s' :: EffectRow).
HasQueryRouter layout r =>
Proxy layout
-> Proxy r
-> (forall a. Sem s a -> Sem s' a)
-> RouteQ layout s
-> RouteQ layout s'
hoistQueryRouter (Proxy (QA Word64 :> Leaf a)
forall k (t :: k). Proxy t
Proxy @(QA Word64 :> Leaf a)) Proxy r
pr forall a. Sem s a -> Sem s' a
nat RouteQ (QA Word64 :> Leaf a) s
RouteQ (StoreLeaf (Array a)) s
f
class StoreQueryHandler ns h where
storeQueryHandler :: ns -> h
instance
( RawKey k
, HasCodec v
, Members QueryEffs r
)
=> StoreQueryHandler (M.Map k v) (QueryArgs k -> Sem r (QueryResult v)) where
storeQueryHandler :: Map k v -> QueryArgs k -> Sem r (QueryResult v)
storeQueryHandler m :: Map k v
m QueryArgs{..} = do
let key :: k
key = k
queryArgsData
Maybe v
mRes <- k -> Map k v -> Sem r (Maybe v)
forall (r :: EffectRow) k v.
(Members '[Error AppError, ReadStore] r, RawKey k, HasCodec v) =>
k -> Map k v -> Sem r (Maybe v)
M.lookup k
key Map k v
m
case Maybe v
mRes of
Nothing -> AppError -> Sem r (QueryResult v)
forall e (r :: EffectRow) a.
MemberWithError (Error e) r =>
e -> Sem r a
throw (AppError -> Sem r (QueryResult v))
-> (RouterError -> AppError)
-> RouterError
-> Sem r (QueryResult v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RouterError -> AppError
forall e. IsAppError e => e -> AppError
makeAppError (RouterError -> Sem r (QueryResult v))
-> RouterError -> Sem r (QueryResult v)
forall a b. (a -> b) -> a -> b
$ RouterError
ResourceNotFound
Just (v
res :: v) -> QueryResult v -> Sem r (QueryResult v)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (QueryResult v -> Sem r (QueryResult v))
-> QueryResult v -> Sem r (QueryResult v)
forall a b. (a -> b) -> a -> b
$ QueryResult :: forall a.
a -> Int64 -> Base64String -> Maybe Proof -> Int64 -> QueryResult a
QueryResult
{ queryResultData :: v
queryResultData = v
res
, queryResultIndex :: Int64
queryResultIndex = 0
, queryResultKey :: Base64String
queryResultKey = ByteString -> Base64String
forall ba. ByteArrayAccess ba => ba -> Base64String
fromBytes (ByteString -> Base64String)
-> (k -> ByteString) -> k -> Base64String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StoreKey -> ByteString
makeKeyBytes (StoreKey -> ByteString) -> (k -> StoreKey) -> k -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map k v -> k -> StoreKey
forall k v. RawKey k => Map k v -> k -> StoreKey
M.makeFullStoreKey Map k v
m (k -> Base64String) -> k -> Base64String
forall a b. (a -> b) -> a -> b
$ k
key
, queryResultProof :: Maybe Proof
queryResultProof = Maybe Proof
forall a. Maybe a
Nothing
, queryResultHeight :: Int64
queryResultHeight = 0
}
instance
( HasCodec a
, Members QueryEffs r
)
=> StoreQueryHandler (A.Array a) (QueryArgs Word64 -> Sem r (QueryResult a)) where
storeQueryHandler :: Array a -> QueryArgs Word64 -> Sem r (QueryResult a)
storeQueryHandler as :: Array a
as QueryArgs{..} = do
let i :: Word64
i = Word64
queryArgsData
Maybe a
mRes <- Array a
as Array a -> Word64 -> Sem r (Maybe a)
forall (r :: EffectRow) a.
(Members '[Error AppError, ReadStore] r, HasCodec a) =>
Array a -> Word64 -> Sem r (Maybe a)
A.!! Word64
i
case Maybe a
mRes of
Nothing -> AppError -> Sem r (QueryResult a)
forall e (r :: EffectRow) a.
MemberWithError (Error e) r =>
e -> Sem r a
throw (AppError -> Sem r (QueryResult a))
-> (RouterError -> AppError)
-> RouterError
-> Sem r (QueryResult a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RouterError -> AppError
forall e. IsAppError e => e -> AppError
makeAppError (RouterError -> Sem r (QueryResult a))
-> RouterError -> Sem r (QueryResult a)
forall a b. (a -> b) -> a -> b
$ RouterError
ResourceNotFound
Just (a
res :: a) -> QueryResult a -> Sem r (QueryResult a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (QueryResult a -> Sem r (QueryResult a))
-> QueryResult a -> Sem r (QueryResult a)
forall a b. (a -> b) -> a -> b
$ QueryResult :: forall a.
a -> Int64 -> Base64String -> Maybe Proof -> Int64 -> QueryResult a
QueryResult
{ queryResultData :: a
queryResultData = a
res
, queryResultIndex :: Int64
queryResultIndex = 0
, queryResultKey :: Base64String
queryResultKey = ByteString -> Base64String
forall ba. ByteArrayAccess ba => ba -> Base64String
fromBytes (ByteString -> Base64String)
-> (Word64 -> ByteString) -> Word64 -> Base64String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StoreKey -> ByteString
makeKeyBytes (StoreKey -> ByteString)
-> (Word64 -> StoreKey) -> Word64 -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array a -> Word64 -> StoreKey
forall a. Array a -> Word64 -> StoreKey
A.makeFullStoreKey Array a
as (Word64 -> Base64String) -> Word64 -> Base64String
forall a b. (a -> b) -> a -> b
$ Word64
i
, queryResultProof :: Maybe Proof
queryResultProof = Maybe Proof
forall a. Maybe a
Nothing
, queryResultHeight :: Int64
queryResultHeight = 0
}
instance
( HasCodec a
, Members QueryEffs r
)
=> StoreQueryHandler (L.List a) (QueryArgs Word64 -> Sem r (QueryResult a)) where
storeQueryHandler :: List a -> QueryArgs Word64 -> Sem r (QueryResult a)
storeQueryHandler as :: List a
as QueryArgs{..} = do
let i :: Word64
i = Word64
queryArgsData
Maybe a
mRes <- List a
as List a -> Word64 -> Sem r (Maybe a)
forall (r :: EffectRow) a.
(Members '[Error AppError, ReadStore] r, HasCodec a) =>
List a -> Word64 -> Sem r (Maybe a)
L.!! Word64
i
case Maybe a
mRes of
Nothing -> AppError -> Sem r (QueryResult a)
forall e (r :: EffectRow) a.
MemberWithError (Error e) r =>
e -> Sem r a
throw (AppError -> Sem r (QueryResult a))
-> (RouterError -> AppError)
-> RouterError
-> Sem r (QueryResult a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RouterError -> AppError
forall e. IsAppError e => e -> AppError
makeAppError (RouterError -> Sem r (QueryResult a))
-> RouterError -> Sem r (QueryResult a)
forall a b. (a -> b) -> a -> b
$ RouterError
ResourceNotFound
Just (a
res :: a) -> QueryResult a -> Sem r (QueryResult a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (QueryResult a -> Sem r (QueryResult a))
-> QueryResult a -> Sem r (QueryResult a)
forall a b. (a -> b) -> a -> b
$ QueryResult :: forall a.
a -> Int64 -> Base64String -> Maybe Proof -> Int64 -> QueryResult a
QueryResult
{ queryResultData :: a
queryResultData = a
res
, queryResultIndex :: Int64
queryResultIndex = 0
, queryResultKey :: Base64String
queryResultKey = ByteString -> Base64String
forall ba. ByteArrayAccess ba => ba -> Base64String
fromBytes (ByteString -> Base64String)
-> (Word64 -> ByteString) -> Word64 -> Base64String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StoreKey -> ByteString
makeKeyBytes (StoreKey -> ByteString)
-> (Word64 -> StoreKey) -> Word64 -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. List a -> Word64 -> StoreKey
forall a. List a -> Word64 -> StoreKey
L.makeFullStoreKey List a
as (Word64 -> Base64String) -> Word64 -> Base64String
forall a b. (a -> b) -> a -> b
$ Word64
i
, queryResultProof :: Maybe Proof
queryResultProof = Maybe Proof
forall a. Maybe a
Nothing
, queryResultHeight :: Int64
queryResultHeight = 0
}
instance
( HasCodec a
, Members QueryEffs r
)
=> StoreQueryHandler (V.Var a) (QueryArgs () -> Sem r (QueryResult a)) where
storeQueryHandler :: Var a -> QueryArgs () -> Sem r (QueryResult a)
storeQueryHandler var :: Var a
var QueryArgs{..} = do
Maybe a
mRes <- Var a -> Sem r (Maybe a)
forall (r :: EffectRow) a.
(Members QueryEffs r, HasCodec a) =>
Var a -> Sem r (Maybe a)
V.takeVar Var a
var
case Maybe a
mRes of
Nothing -> AppError -> Sem r (QueryResult a)
forall e (r :: EffectRow) a.
MemberWithError (Error e) r =>
e -> Sem r a
throw (AppError -> Sem r (QueryResult a))
-> (RouterError -> AppError)
-> RouterError
-> Sem r (QueryResult a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RouterError -> AppError
forall e. IsAppError e => e -> AppError
makeAppError (RouterError -> Sem r (QueryResult a))
-> RouterError -> Sem r (QueryResult a)
forall a b. (a -> b) -> a -> b
$ RouterError
ResourceNotFound
Just (a
res :: a) -> QueryResult a -> Sem r (QueryResult a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (QueryResult a -> Sem r (QueryResult a))
-> QueryResult a -> Sem r (QueryResult a)
forall a b. (a -> b) -> a -> b
$ QueryResult :: forall a.
a -> Int64 -> Base64String -> Maybe Proof -> Int64 -> QueryResult a
QueryResult
{ queryResultData :: a
queryResultData = a
res
, queryResultIndex :: Int64
queryResultIndex = 0
, queryResultKey :: Base64String
queryResultKey = ByteString -> Base64String
forall ba. ByteArrayAccess ba => ba -> Base64String
fromBytes (ByteString -> Base64String)
-> (Var a -> ByteString) -> Var a -> Base64String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StoreKey -> ByteString
makeKeyBytes (StoreKey -> ByteString)
-> (Var a -> StoreKey) -> Var a -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Var a -> StoreKey
forall a. Var a -> StoreKey
V.makeFullStoreKey (Var a -> Base64String) -> Var a -> Base64String
forall a b. (a -> b) -> a -> b
$ Var a
var
, queryResultProof :: Maybe Proof
queryResultProof = Maybe Proof
forall a. Maybe a
Nothing
, queryResultHeight :: Int64
queryResultHeight = 0
}