module Data.CQRS.Test.Internal.ArchiveStoreUtils
( readAllEventsFromArchiveStore
) where
import Control.Monad.IO.Class (liftIO)
import Data.IORef (newIORef, atomicModifyIORef', readIORef)
import Data.CQRS.Types.ArchiveMetadata (ArchiveMetadata(..))
import Data.CQRS.Types.ArchiveRef (ArchiveRef(..))
import Data.CQRS.Types.ArchiveStore (ArchiveStore(..), enumerateAllEvents)
import Data.CQRS.Types.PersistedEvent (PersistedEvent)
import Data.CQRS.Test.Internal.Scope (ScopeM, ask)
import Data.UUID.Types (UUID)
import qualified System.IO.Streams.List as SL
import Test.Hspec (shouldBe)
readAllEventsFromArchiveStore :: (s -> ArchiveStore e) -> ScopeM s (Int, [(UUID, PersistedEvent e)])
readAllEventsFromArchiveStore f = do
archiveStore <- fmap f ask
archiveCount <- liftIO $ assertConsistentArchiveMetadata archiveStore
events <- liftIO $ readAllEvents' archiveStore
return (archiveCount, events)
readAllEvents' :: ArchiveStore e -> IO [(UUID, PersistedEvent e)]
readAllEvents' archiveStore = do
eventsRef <- newIORef [ ]
enumerateAllEvents archiveStore $ \inputStream -> do
events <- SL.toList inputStream
atomicModifyIORef' eventsRef (\events' -> (events' ++ events, ()))
readIORef eventsRef
assertConsistentArchiveMetadata :: ArchiveStore e -> IO Int
assertConsistentArchiveMetadata archiveStore = do
maybeLatestArchiveMetadata <- asReadLatestArchiveMetadata archiveStore
case maybeLatestArchiveMetadata of
Nothing ->
return 0
Just archiveMetadata ->
walk CurrentArchive archiveMetadata 0
where
walk previousArchiveRef archiveMetadata count = do
previousArchiveRef `shouldBe` amNextArchiveId archiveMetadata
case amPreviousArchiveId archiveMetadata of
Nothing -> do
return $ count + 1
Just previousArchiveId -> do
maybePreviousArchiveMetadata <- (asReadArchiveMetadata archiveStore) previousArchiveId
case maybePreviousArchiveMetadata of
Nothing ->
error "No metadata for previous archive?"
Just previousArchiveMetadata -> do
let archiveRef = NamedArchive $ amArchiveId archiveMetadata
archiveRef `shouldBe` (amNextArchiveId previousArchiveMetadata)
walk archiveRef previousArchiveMetadata $ count + 1