{-# 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 { forall st. AcidState st -> MethodMap st
localMethods :: MethodMap st
, forall st. AcidState st -> st
localState :: st
}
update :: UpdateEvent event => AcidState (EventState event) -> event -> ( AcidState (EventState event)
, EventResult event)
update :: forall event.
UpdateEvent event =>
AcidState (EventState event)
-> event -> (AcidState (EventState event), EventResult event)
update AcidState (EventState event)
acidState event
event
= case forall s a. State s a -> s -> (a, s)
runState State (EventState event) (EventResult event)
hotMethod (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 = forall method.
Method method =>
MethodMap (MethodState method)
-> method -> State (MethodState method) (MethodResult method)
lookupHotMethod (forall st. AcidState st -> MethodMap st
localMethods AcidState (EventState event)
acidState) event
event
update_ :: UpdateEvent event => AcidState (EventState event) -> event -> AcidState (EventState event)
update_ :: forall event.
UpdateEvent event =>
AcidState (EventState event)
-> event -> AcidState (EventState event)
update_ AcidState (EventState event)
acidState event
event
= forall a b. (a, b) -> a
fst (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 :: forall event.
QueryEvent event =>
AcidState (EventState event) -> event -> EventResult event
query AcidState (EventState event)
acidState event
event
= case forall s a. State s a -> s -> (a, s)
runState State (EventState event) (EventResult event)
hotMethod (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 = forall method.
Method method =>
MethodMap (MethodState method)
-> method -> State (MethodState method) (MethodResult method)
lookupHotMethod (forall st. AcidState st -> MethodMap st
localMethods AcidState (EventState event)
acidState) event
event
openAcidState :: IsAcidic st
=> st
-> AcidState st
openAcidState :: forall st. IsAcidic st => st -> AcidState st
openAcidState st
initialState
= AcidState { localMethods :: MethodMap st
localMethods = forall st. [MethodContainer st] -> MethodMap st
mkMethodMap (forall st. [Event st] -> [MethodContainer st]
eventsToMethods forall st. IsAcidic st => [Event st]
acidEvents)
, localState :: st
localState = st
initialState }
runUpdate :: Update s r -> s -> (r, s)
runUpdate :: forall s r. Update s r -> s -> (r, s)
runUpdate Update s r
update = forall s a. State s a -> s -> (a, s)
runState forall a b. (a -> b) -> a -> b
$ forall st a. Update st a -> State st a
unUpdate Update s r
update
runQuery :: Query s r -> s -> r
runQuery :: forall s r. Query s r -> s -> r
runQuery Query s r
query = forall r a. Reader r a -> r -> a
runReader forall a b. (a -> b) -> a -> b
$ forall st a. Query st a -> Reader st a
unQuery Query s r
query