module Data.CQRS.Internal.AggregateRef
( AggregateRef
, arGUID
, arStartVersion
, mkAggregateRef
, publishEvent
, readEvents
, readValue
) where
import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.CQRS.GUID (GUID)
import Data.CQRS.Event (Event(..))
import Data.IORef (IORef, modifyIORef, newIORef, readIORef)
import Data.Typeable (Typeable)
data AggregateRef a e =
AggregateRef { arValue :: IORef a
, arEvents :: IORef [e]
, arGUID :: GUID a
, arStartVersion :: Int
}
deriving (Typeable)
mkAggregateRef :: (MonadIO m) => a -> GUID a -> Int -> m (AggregateRef a e)
mkAggregateRef a guid originatingVersion = do
a' <- liftIO $ newIORef a
e' <- liftIO $ newIORef []
return $ AggregateRef a' e' guid originatingVersion
publishEvent :: (MonadIO m, Event e a) => AggregateRef a e -> e -> m ()
publishEvent aggregateRef event = liftIO $ do
modifyIORef (arValue aggregateRef) $ applyEvent event
modifyIORef (arEvents aggregateRef) $ \es -> event:es
readEvents :: (MonadIO m) => AggregateRef a e -> m [e]
readEvents = liftIO . readIORef . arEvents
readValue :: (MonadIO m) => AggregateRef a e -> m a
readValue = liftIO . readIORef . arValue