{-# LANGUAGE DeriveDataTypeable, BangPatterns #-}
module Data.Acid.Memory.Pure
( IsAcidic(..)
, AcidState
, Event(..)
, EventResult
, EventState
, UpdateEvent
, QueryEvent
, Update
, Query
, openAcidState
, update
, update_
, query
, liftQuery
, runUpdate
, runQuery
) where
import Data.Acid.Core
import Data.Acid.Common
import Control.Monad.State
import Control.Monad.Reader
data AcidState st
= AcidState { AcidState st -> MethodMap st
localMethods :: MethodMap st
, AcidState st -> st
localState :: st
}
update :: UpdateEvent event => AcidState (EventState event) -> event -> ( AcidState (EventState event)
, EventResult event)
update :: AcidState (EventState event)
-> event -> (AcidState (EventState event), EventResult event)
update AcidState (EventState event)
acidState event
event
= case State (EventState event) (EventResult event)
-> EventState event -> (EventResult event, EventState event)
forall s a. State s a -> s -> (a, s)
runState State (EventState event) (EventResult event)
hotMethod (AcidState (EventState event) -> EventState event
forall st. AcidState st -> st
localState AcidState (EventState event)
acidState) of
!(EventResult event
result, !EventState event
newState) -> ( AcidState (EventState event)
acidState { localState :: EventState event
localState = EventState event
newState }
, EventResult event
result )
where hotMethod :: State (EventState event) (EventResult event)
hotMethod = MethodMap (EventState event)
-> event -> State (EventState event) (EventResult event)
forall method.
Method method =>
MethodMap (MethodState method)
-> method -> State (MethodState method) (MethodResult method)
lookupHotMethod (AcidState (EventState event) -> MethodMap (EventState event)
forall st. AcidState st -> MethodMap st
localMethods AcidState (EventState event)
acidState) event
event
update_ :: UpdateEvent event => AcidState (EventState event) -> event -> AcidState (EventState event)
update_ :: AcidState (EventState event)
-> event -> AcidState (EventState event)
update_ AcidState (EventState event)
acidState event
event
= (AcidState (EventState event), MethodResult event)
-> AcidState (EventState event)
forall a b. (a, b) -> a
fst (AcidState (EventState event)
-> event -> (AcidState (EventState event), MethodResult event)
forall event.
UpdateEvent event =>
AcidState (EventState event)
-> event -> (AcidState (EventState event), EventResult event)
update AcidState (EventState event)
acidState event
event)
query :: QueryEvent event => AcidState (EventState event) -> event -> EventResult event
query :: AcidState (EventState event) -> event -> EventResult event
query AcidState (EventState event)
acidState event
event
= case State (EventState event) (EventResult event)
-> EventState event -> (EventResult event, EventState event)
forall s a. State s a -> s -> (a, s)
runState State (EventState event) (EventResult event)
hotMethod (AcidState (EventState event) -> EventState event
forall st. AcidState st -> st
localState AcidState (EventState event)
acidState) of
!(EventResult event
result, !EventState event
_st) -> EventResult event
result
where hotMethod :: State (EventState event) (EventResult event)
hotMethod = MethodMap (EventState event)
-> event -> State (EventState event) (EventResult event)
forall method.
Method method =>
MethodMap (MethodState method)
-> method -> State (MethodState method) (MethodResult method)
lookupHotMethod (AcidState (EventState event) -> MethodMap (EventState event)
forall st. AcidState st -> MethodMap st
localMethods AcidState (EventState event)
acidState) event
event
openAcidState :: IsAcidic st
=> st
-> AcidState st
openAcidState :: st -> AcidState st
openAcidState st
initialState
= AcidState :: forall st. MethodMap st -> st -> AcidState st
AcidState { localMethods :: MethodMap st
localMethods = [MethodContainer st] -> MethodMap st
forall st. [MethodContainer st] -> MethodMap st
mkMethodMap ([Event st] -> [MethodContainer st]
forall st. [Event st] -> [MethodContainer st]
eventsToMethods [Event st]
forall st. IsAcidic st => [Event st]
acidEvents)
, localState :: st
localState = st
initialState }
runUpdate :: Update s r -> s -> (r, s)
runUpdate :: Update s r -> s -> (r, s)
runUpdate Update s r
update = State s r -> s -> (r, s)
forall s a. State s a -> s -> (a, s)
runState (State s r -> s -> (r, s)) -> State s r -> s -> (r, s)
forall a b. (a -> b) -> a -> b
$ Update s r -> State s r
forall st a. Update st a -> State st a
unUpdate Update s r
update
runQuery :: Query s r -> s -> r
runQuery :: Query s r -> s -> r
runQuery Query s r
query = Reader s r -> s -> r
forall r a. Reader r a -> r -> a
runReader (Reader s r -> s -> r) -> Reader s r -> s -> r
forall a b. (a -> b) -> a -> b
$ Query s r -> Reader s r
forall st a. Query st a -> Reader st a
unQuery Query s r
query