{-# LANGUAGE FlexibleContexts #-}

module Eventium.Store.Memory
  ( tvarEventStoreReader,
    tvarEventStoreWriter,
    tvarGlobalEventStoreReader,
    stateEventStoreReader,
    stateEventStoreWriter,
    stateGlobalEventStoreReader,
    embeddedStateEventStoreReader,
    embeddedStateEventStoreWriter,
    embeddedStateGlobalEventStoreReader,
    EventMap,
    emptyEventMap,
    eventMapTVar,
    module Eventium.Store.Class,
  )
where

import Control.Concurrent.STM
import Control.Monad.State.Class
import Data.Foldable (toList)
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe)
import Data.Sequence (Seq, (><))
import qualified Data.Sequence as Seq
import Eventium.Store.Class
import Eventium.UUID

-- | Internal data structure used for the in-memory event stores.
data EventMap event
  = EventMap
  { forall event.
EventMap event -> Map UUID (Seq (VersionedStreamEvent event))
_eventMapUuidMap :: Map UUID (Seq (VersionedStreamEvent event)),
    forall event. EventMap event -> Seq (VersionedStreamEvent event)
_eventMapGlobalEvents :: Seq (VersionedStreamEvent event)
  }
  deriving (Int -> EventMap event -> ShowS
[EventMap event] -> ShowS
EventMap event -> String
(Int -> EventMap event -> ShowS)
-> (EventMap event -> String)
-> ([EventMap event] -> ShowS)
-> Show (EventMap event)
forall event. Show event => Int -> EventMap event -> ShowS
forall event. Show event => [EventMap event] -> ShowS
forall event. Show event => EventMap event -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall event. Show event => Int -> EventMap event -> ShowS
showsPrec :: Int -> EventMap event -> ShowS
$cshow :: forall event. Show event => EventMap event -> String
show :: EventMap event -> String
$cshowList :: forall event. Show event => [EventMap event] -> ShowS
showList :: [EventMap event] -> ShowS
Show)

-- | What it says on the tin, an initialized empty 'EventMap'
emptyEventMap :: EventMap event
emptyEventMap :: forall event. EventMap event
emptyEventMap = Map UUID (Seq (VersionedStreamEvent event))
-> Seq (VersionedStreamEvent event) -> EventMap event
forall event.
Map UUID (Seq (VersionedStreamEvent event))
-> Seq (VersionedStreamEvent event) -> EventMap event
EventMap Map UUID (Seq (VersionedStreamEvent event))
forall k a. Map k a
Map.empty Seq (VersionedStreamEvent event)
forall a. Seq a
Seq.empty

-- | Initialize an 'EventMap' in a 'TVar'
eventMapTVar :: IO (TVar (EventMap event))
eventMapTVar :: forall event. IO (TVar (EventMap event))
eventMapTVar = EventMap event -> IO (TVar (EventMap event))
forall a. a -> IO (TVar a)
newTVarIO EventMap event
forall event. EventMap event
emptyEventMap

-- | An 'EventStoreReader' that stores events in a 'TVar' and runs in 'STM'.
-- This functions initializes the store by creating the 'TVar' and hooking up
-- the event store API to that 'TVar'.
tvarEventStoreReader :: TVar (EventMap event) -> VersionedEventStoreReader STM event
tvarEventStoreReader :: forall event.
TVar (EventMap event) -> VersionedEventStoreReader STM event
tvarEventStoreReader TVar (EventMap event)
tvar = (QueryRange UUID EventVersion -> STM [VersionedStreamEvent event])
-> EventStoreReader
     UUID EventVersion STM (VersionedStreamEvent event)
forall key position (m :: * -> *) event.
(QueryRange key position -> m [event])
-> EventStoreReader key position m event
EventStoreReader ((QueryRange UUID EventVersion -> STM [VersionedStreamEvent event])
 -> EventStoreReader
      UUID EventVersion STM (VersionedStreamEvent event))
-> (QueryRange UUID EventVersion
    -> STM [VersionedStreamEvent event])
-> EventStoreReader
     UUID EventVersion STM (VersionedStreamEvent event)
forall a b. (a -> b) -> a -> b
$ \QueryRange UUID EventVersion
range -> QueryRange UUID EventVersion
-> EventMap event -> [VersionedStreamEvent event]
forall event.
QueryRange UUID EventVersion
-> EventMap event -> [VersionedStreamEvent event]
lookupEventsInRange QueryRange UUID EventVersion
range (EventMap event -> [VersionedStreamEvent event])
-> STM (EventMap event) -> STM [VersionedStreamEvent event]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TVar (EventMap event) -> STM (EventMap event)
forall a. TVar a -> STM a
readTVar TVar (EventMap event)
tvar

tvarEventStoreWriter :: TVar (EventMap event) -> VersionedEventStoreWriter STM event
tvarEventStoreWriter :: forall event.
TVar (EventMap event) -> VersionedEventStoreWriter STM event
tvarEventStoreWriter TVar (EventMap event)
tvar = (UUID
 -> ExpectedPosition EventVersion
 -> [event]
 -> STM (Either (EventWriteError EventVersion) EventVersion))
-> EventStoreWriter UUID EventVersion STM event
forall key position (m :: * -> *) event.
(key
 -> ExpectedPosition position
 -> [event]
 -> m (Either (EventWriteError position) EventVersion))
-> EventStoreWriter key position m event
EventStoreWriter ((UUID
  -> ExpectedPosition EventVersion
  -> [event]
  -> STM (Either (EventWriteError EventVersion) EventVersion))
 -> EventStoreWriter UUID EventVersion STM event)
-> (UUID
    -> ExpectedPosition EventVersion
    -> [event]
    -> STM (Either (EventWriteError EventVersion) EventVersion))
-> EventStoreWriter UUID EventVersion STM event
forall a b. (a -> b) -> a -> b
$ (UUID -> STM EventVersion)
-> (UUID -> [event] -> STM EventVersion)
-> UUID
-> ExpectedPosition EventVersion
-> [event]
-> STM (Either (EventWriteError EventVersion) EventVersion)
forall (m :: * -> *) position key event.
(Monad m, Ord position, Num position) =>
(key -> m position)
-> (key -> [event] -> m EventVersion)
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
transactionalExpectedWriteHelper UUID -> STM EventVersion
getLatestVersion UUID -> [event] -> STM EventVersion
storeEvents'
  where
    getLatestVersion :: UUID -> STM EventVersion
getLatestVersion UUID
uuid = (EventMap event -> UUID -> EventVersion)
-> UUID -> EventMap event -> EventVersion
forall a b c. (a -> b -> c) -> b -> a -> c
flip EventMap event -> UUID -> EventVersion
forall event. EventMap event -> UUID -> EventVersion
latestEventVersion UUID
uuid (EventMap event -> EventVersion)
-> STM (EventMap event) -> STM EventVersion
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TVar (EventMap event) -> STM (EventMap event)
forall a. TVar a -> STM a
readTVar TVar (EventMap event)
tvar
    storeEvents' :: UUID -> [event] -> STM EventVersion
storeEvents' UUID
uuid [event]
events = do
      EventMap event
store <- TVar (EventMap event) -> STM (EventMap event)
forall a. TVar a -> STM a
readTVar TVar (EventMap event)
tvar
      let (EventMap event
store', EventVersion
vers) = EventMap event -> UUID -> [event] -> (EventMap event, EventVersion)
forall event.
EventMap event -> UUID -> [event] -> (EventMap event, EventVersion)
storeEventMap EventMap event
store UUID
uuid [event]
events
      TVar (EventMap event) -> EventMap event -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar (EventMap event)
tvar EventMap event
store'
      EventVersion -> STM EventVersion
forall a. a -> STM a
forall (m :: * -> *) a. Monad m => a -> m a
return EventVersion
vers

-- | Analog of 'tvarEventStoreReader' for a 'GlobalEventStoreReader'
tvarGlobalEventStoreReader :: TVar (EventMap event) -> GlobalEventStoreReader STM event
tvarGlobalEventStoreReader :: forall event.
TVar (EventMap event) -> GlobalEventStoreReader STM event
tvarGlobalEventStoreReader TVar (EventMap event)
tvar = (QueryRange () SequenceNumber -> STM [GlobalStreamEvent event])
-> EventStoreReader () SequenceNumber STM (GlobalStreamEvent event)
forall key position (m :: * -> *) event.
(QueryRange key position -> m [event])
-> EventStoreReader key position m event
EventStoreReader ((QueryRange () SequenceNumber -> STM [GlobalStreamEvent event])
 -> EventStoreReader
      () SequenceNumber STM (GlobalStreamEvent event))
-> (QueryRange () SequenceNumber -> STM [GlobalStreamEvent event])
-> EventStoreReader () SequenceNumber STM (GlobalStreamEvent event)
forall a b. (a -> b) -> a -> b
$ \QueryRange () SequenceNumber
range -> QueryRange () SequenceNumber
-> EventMap event -> [GlobalStreamEvent event]
forall event.
QueryRange () SequenceNumber
-> EventMap event -> [GlobalStreamEvent event]
lookupGlobalEvents QueryRange () SequenceNumber
range (EventMap event -> [GlobalStreamEvent event])
-> STM (EventMap event) -> STM [GlobalStreamEvent event]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TVar (EventMap event) -> STM (EventMap event)
forall a. TVar a -> STM a
readTVar TVar (EventMap event)
tvar

-- | Specialized version of 'embeddedStateEventStoreReader' that only contains an
-- 'EventMap' in the state.
stateEventStoreReader ::
  (MonadState (EventMap event) m) =>
  VersionedEventStoreReader m event
stateEventStoreReader :: forall event (m :: * -> *).
MonadState (EventMap event) m =>
VersionedEventStoreReader m event
stateEventStoreReader = (EventMap event -> EventMap event)
-> VersionedEventStoreReader m event
forall s (m :: * -> *) event.
MonadState s m =>
(s -> EventMap event) -> VersionedEventStoreReader m event
embeddedStateEventStoreReader EventMap event -> EventMap event
forall a. a -> a
id

stateGlobalEventStoreReader ::
  (MonadState (EventMap event) m) =>
  GlobalEventStoreReader m event
stateGlobalEventStoreReader :: forall event (m :: * -> *).
MonadState (EventMap event) m =>
GlobalEventStoreReader m event
stateGlobalEventStoreReader = (EventMap event -> EventMap event)
-> GlobalEventStoreReader m event
forall s (m :: * -> *) event.
MonadState s m =>
(s -> EventMap event) -> GlobalEventStoreReader m event
embeddedStateGlobalEventStoreReader EventMap event -> EventMap event
forall a. a -> a
id

-- | Specialized version of 'embeddedStateEventStoreWriter' that only contains an
-- 'EventMap' in the state.
stateEventStoreWriter ::
  (MonadState (EventMap event) m) =>
  VersionedEventStoreWriter m event
stateEventStoreWriter :: forall event (m :: * -> *).
MonadState (EventMap event) m =>
VersionedEventStoreWriter m event
stateEventStoreWriter = (EventMap event -> EventMap event)
-> (EventMap event -> EventMap event -> EventMap event)
-> VersionedEventStoreWriter m event
forall s (m :: * -> *) event.
MonadState s m =>
(s -> EventMap event)
-> (s -> EventMap event -> s) -> VersionedEventStoreWriter m event
embeddedStateEventStoreWriter EventMap event -> EventMap event
forall a. a -> a
id ((EventMap event -> EventMap event)
-> EventMap event -> EventMap event -> EventMap event
forall a b. a -> b -> a
const EventMap event -> EventMap event
forall a. a -> a
id)

-- | An 'EventStore' that runs on some 'MonadState' that contains an
-- 'EventMap'. This is useful if you want to include other state in your
-- 'MonadState'.
embeddedStateEventStoreReader ::
  (MonadState s m) =>
  (s -> EventMap event) ->
  VersionedEventStoreReader m event
embeddedStateEventStoreReader :: forall s (m :: * -> *) event.
MonadState s m =>
(s -> EventMap event) -> VersionedEventStoreReader m event
embeddedStateEventStoreReader s -> EventMap event
getMap = (QueryRange UUID EventVersion -> m [VersionedStreamEvent event])
-> EventStoreReader
     UUID EventVersion m (VersionedStreamEvent event)
forall key position (m :: * -> *) event.
(QueryRange key position -> m [event])
-> EventStoreReader key position m event
EventStoreReader ((QueryRange UUID EventVersion -> m [VersionedStreamEvent event])
 -> EventStoreReader
      UUID EventVersion m (VersionedStreamEvent event))
-> (QueryRange UUID EventVersion -> m [VersionedStreamEvent event])
-> EventStoreReader
     UUID EventVersion m (VersionedStreamEvent event)
forall a b. (a -> b) -> a -> b
$ \QueryRange UUID EventVersion
range -> QueryRange UUID EventVersion
-> EventMap event -> [VersionedStreamEvent event]
forall event.
QueryRange UUID EventVersion
-> EventMap event -> [VersionedStreamEvent event]
lookupEventsInRange QueryRange UUID EventVersion
range (EventMap event -> [VersionedStreamEvent event])
-> m (EventMap event) -> m [VersionedStreamEvent event]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (s -> EventMap event) -> m (EventMap event)
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets s -> EventMap event
getMap

embeddedStateEventStoreWriter ::
  (MonadState s m) =>
  (s -> EventMap event) ->
  (s -> EventMap event -> s) ->
  VersionedEventStoreWriter m event
embeddedStateEventStoreWriter :: forall s (m :: * -> *) event.
MonadState s m =>
(s -> EventMap event)
-> (s -> EventMap event -> s) -> VersionedEventStoreWriter m event
embeddedStateEventStoreWriter s -> EventMap event
getMap s -> EventMap event -> s
setMap = (UUID
 -> ExpectedPosition EventVersion
 -> [event]
 -> m (Either (EventWriteError EventVersion) EventVersion))
-> EventStoreWriter UUID EventVersion m event
forall key position (m :: * -> *) event.
(key
 -> ExpectedPosition position
 -> [event]
 -> m (Either (EventWriteError position) EventVersion))
-> EventStoreWriter key position m event
EventStoreWriter ((UUID
  -> ExpectedPosition EventVersion
  -> [event]
  -> m (Either (EventWriteError EventVersion) EventVersion))
 -> EventStoreWriter UUID EventVersion m event)
-> (UUID
    -> ExpectedPosition EventVersion
    -> [event]
    -> m (Either (EventWriteError EventVersion) EventVersion))
-> EventStoreWriter UUID EventVersion m event
forall a b. (a -> b) -> a -> b
$ (UUID -> m EventVersion)
-> (UUID -> [event] -> m EventVersion)
-> UUID
-> ExpectedPosition EventVersion
-> [event]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall (m :: * -> *) position key event.
(Monad m, Ord position, Num position) =>
(key -> m position)
-> (key -> [event] -> m EventVersion)
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
transactionalExpectedWriteHelper UUID -> m EventVersion
forall {f :: * -> *}. MonadState s f => UUID -> f EventVersion
getLatestVersion UUID -> [event] -> m EventVersion
forall {m :: * -> *}.
MonadState s m =>
UUID -> [event] -> m EventVersion
storeEvents'
  where
    getLatestVersion :: UUID -> f EventVersion
getLatestVersion UUID
uuid = (EventMap event -> UUID -> EventVersion)
-> UUID -> EventMap event -> EventVersion
forall a b c. (a -> b -> c) -> b -> a -> c
flip EventMap event -> UUID -> EventVersion
forall event. EventMap event -> UUID -> EventVersion
latestEventVersion UUID
uuid (EventMap event -> EventVersion)
-> f (EventMap event) -> f EventVersion
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (s -> EventMap event) -> f (EventMap event)
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets s -> EventMap event
getMap
    storeEvents' :: UUID -> [event] -> m EventVersion
storeEvents' UUID
uuid [event]
events = do
      s
state' <- m s
forall s (m :: * -> *). MonadState s m => m s
get
      let store :: EventMap event
store = s -> EventMap event
getMap s
state'
      let (EventMap event
store', EventVersion
vers) = EventMap event -> UUID -> [event] -> (EventMap event, EventVersion)
forall event.
EventMap event -> UUID -> [event] -> (EventMap event, EventVersion)
storeEventMap EventMap event
store UUID
uuid [event]
events
      s -> m ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (s -> m ()) -> s -> m ()
forall a b. (a -> b) -> a -> b
$ s -> EventMap event -> s
setMap s
state' EventMap event
store'
      EventVersion -> m EventVersion
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return EventVersion
vers

-- | Analogous to 'embeddedStateEventStore' for a 'GlobalStreamEventStore'.
embeddedStateGlobalEventStoreReader ::
  (MonadState s m) =>
  (s -> EventMap event) ->
  GlobalEventStoreReader m event
embeddedStateGlobalEventStoreReader :: forall s (m :: * -> *) event.
MonadState s m =>
(s -> EventMap event) -> GlobalEventStoreReader m event
embeddedStateGlobalEventStoreReader s -> EventMap event
getMap = (QueryRange () SequenceNumber -> m [GlobalStreamEvent event])
-> EventStoreReader () SequenceNumber m (GlobalStreamEvent event)
forall key position (m :: * -> *) event.
(QueryRange key position -> m [event])
-> EventStoreReader key position m event
EventStoreReader ((QueryRange () SequenceNumber -> m [GlobalStreamEvent event])
 -> EventStoreReader () SequenceNumber m (GlobalStreamEvent event))
-> (QueryRange () SequenceNumber -> m [GlobalStreamEvent event])
-> EventStoreReader () SequenceNumber m (GlobalStreamEvent event)
forall a b. (a -> b) -> a -> b
$ \QueryRange () SequenceNumber
range -> QueryRange () SequenceNumber
-> EventMap event -> [GlobalStreamEvent event]
forall event.
QueryRange () SequenceNumber
-> EventMap event -> [GlobalStreamEvent event]
lookupGlobalEvents QueryRange () SequenceNumber
range (EventMap event -> [GlobalStreamEvent event])
-> m (EventMap event) -> m [GlobalStreamEvent event]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (s -> EventMap event) -> m (EventMap event)
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets s -> EventMap event
getMap

lookupEventMapRaw :: EventMap event -> UUID -> Seq (VersionedStreamEvent event)
lookupEventMapRaw :: forall event.
EventMap event -> UUID -> Seq (VersionedStreamEvent event)
lookupEventMapRaw (EventMap Map UUID (Seq (VersionedStreamEvent event))
uuidMap Seq (VersionedStreamEvent event)
_) UUID
uuid = Seq (VersionedStreamEvent event)
-> Maybe (Seq (VersionedStreamEvent event))
-> Seq (VersionedStreamEvent event)
forall a. a -> Maybe a -> a
fromMaybe Seq (VersionedStreamEvent event)
forall a. Seq a
Seq.empty (Maybe (Seq (VersionedStreamEvent event))
 -> Seq (VersionedStreamEvent event))
-> Maybe (Seq (VersionedStreamEvent event))
-> Seq (VersionedStreamEvent event)
forall a b. (a -> b) -> a -> b
$ UUID
-> Map UUID (Seq (VersionedStreamEvent event))
-> Maybe (Seq (VersionedStreamEvent event))
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup UUID
uuid Map UUID (Seq (VersionedStreamEvent event))
uuidMap

lookupEventsInRange :: QueryRange UUID EventVersion -> EventMap event -> [VersionedStreamEvent event]
lookupEventsInRange :: forall event.
QueryRange UUID EventVersion
-> EventMap event -> [VersionedStreamEvent event]
lookupEventsInRange (QueryRange UUID
uuid QueryStart EventVersion
start QueryLimit EventVersion
limit) EventMap event
store = Seq (VersionedStreamEvent event) -> [VersionedStreamEvent event]
forall a. Seq a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (Seq (VersionedStreamEvent event) -> [VersionedStreamEvent event])
-> Seq (VersionedStreamEvent event) -> [VersionedStreamEvent event]
forall a b. (a -> b) -> a -> b
$ QueryStart Int
-> QueryLimit Int
-> Int
-> Seq (VersionedStreamEvent event)
-> Seq (VersionedStreamEvent event)
forall event.
QueryStart Int -> QueryLimit Int -> Int -> Seq event -> Seq event
filterEventsByRange QueryStart Int
start' QueryLimit Int
limit' Int
0 Seq (VersionedStreamEvent event)
rawEvents
  where
    start' :: QueryStart Int
start' = EventVersion -> Int
unEventVersion (EventVersion -> Int) -> QueryStart EventVersion -> QueryStart Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueryStart EventVersion
start
    limit' :: QueryLimit Int
limit' = EventVersion -> Int
unEventVersion (EventVersion -> Int) -> QueryLimit EventVersion -> QueryLimit Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueryLimit EventVersion
limit
    rawEvents :: Seq (VersionedStreamEvent event)
rawEvents = EventMap event -> UUID -> Seq (VersionedStreamEvent event)
forall event.
EventMap event -> UUID -> Seq (VersionedStreamEvent event)
lookupEventMapRaw EventMap event
store UUID
uuid

filterEventsByRange :: QueryStart Int -> QueryLimit Int -> Int -> Seq event -> Seq event
filterEventsByRange :: forall event.
QueryStart Int -> QueryLimit Int -> Int -> Seq event -> Seq event
filterEventsByRange QueryStart Int
queryStart QueryLimit Int
queryLimit Int
defaultStart Seq event
events =
  let (Int
start', Seq event
events') =
        case QueryStart Int
queryStart of
          QueryStart Int
StartFromBeginning -> (Int
defaultStart, Seq event
events)
          StartQueryAt Int
start -> (Int
start, Int -> Seq event -> Seq event
forall a. Int -> Seq a -> Seq a
Seq.drop (Int
start Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
defaultStart) Seq event
events)
      events'' :: Seq event
events'' =
        case QueryLimit Int
queryLimit of
          QueryLimit Int
NoQueryLimit -> Seq event
events'
          MaxNumberOfEvents Int
num -> Int -> Seq event -> Seq event
forall a. Int -> Seq a -> Seq a
Seq.take Int
num Seq event
events'
          StopQueryAt Int
stop -> Int -> Seq event -> Seq event
forall a. Int -> Seq a -> Seq a
Seq.take (Int
stop Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
start' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Seq event
events'
   in Seq event
events''

latestEventVersion :: EventMap event -> UUID -> EventVersion
latestEventVersion :: forall event. EventMap event -> UUID -> EventVersion
latestEventVersion EventMap event
store UUID
uuid = Int -> EventVersion
EventVersion (Int -> EventVersion) -> Int -> EventVersion
forall a b. (a -> b) -> a -> b
$ Seq (VersionedStreamEvent event) -> Int
forall a. Seq a -> Int
Seq.length (EventMap event -> UUID -> Seq (VersionedStreamEvent event)
forall event.
EventMap event -> UUID -> Seq (VersionedStreamEvent event)
lookupEventMapRaw EventMap event
store UUID
uuid) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1

lookupGlobalEvents :: QueryRange () SequenceNumber -> EventMap event -> [GlobalStreamEvent event]
lookupGlobalEvents :: forall event.
QueryRange () SequenceNumber
-> EventMap event -> [GlobalStreamEvent event]
lookupGlobalEvents (QueryRange () QueryStart SequenceNumber
start QueryLimit SequenceNumber
limit) (EventMap Map UUID (Seq (VersionedStreamEvent event))
_ Seq (VersionedStreamEvent event)
globalEvents) = [StreamEvent () SequenceNumber (VersionedStreamEvent event)]
events'
  where
    start' :: QueryStart Int
start' = SequenceNumber -> Int
unSequenceNumber (SequenceNumber -> Int)
-> QueryStart SequenceNumber -> QueryStart Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueryStart SequenceNumber
start
    limit' :: QueryLimit Int
limit' = SequenceNumber -> Int
unSequenceNumber (SequenceNumber -> Int)
-> QueryLimit SequenceNumber -> QueryLimit Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueryLimit SequenceNumber
limit
    events :: [VersionedStreamEvent event]
events = Seq (VersionedStreamEvent event) -> [VersionedStreamEvent event]
forall a. Seq a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (Seq (VersionedStreamEvent event) -> [VersionedStreamEvent event])
-> Seq (VersionedStreamEvent event) -> [VersionedStreamEvent event]
forall a b. (a -> b) -> a -> b
$ QueryStart Int
-> QueryLimit Int
-> Int
-> Seq (VersionedStreamEvent event)
-> Seq (VersionedStreamEvent event)
forall event.
QueryStart Int -> QueryLimit Int -> Int -> Seq event -> Seq event
filterEventsByRange QueryStart Int
start' QueryLimit Int
limit' Int
1 Seq (VersionedStreamEvent event)
globalEvents
    events' :: [StreamEvent () SequenceNumber (VersionedStreamEvent event)]
events' = (SequenceNumber
 -> VersionedStreamEvent event
 -> StreamEvent () SequenceNumber (VersionedStreamEvent event))
-> [SequenceNumber]
-> [VersionedStreamEvent event]
-> [StreamEvent () SequenceNumber (VersionedStreamEvent event)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (()
-> SequenceNumber
-> VersionedStreamEvent event
-> StreamEvent () SequenceNumber (VersionedStreamEvent event)
forall key position event.
key -> position -> event -> StreamEvent key position event
StreamEvent ()) [SequenceNumber
startingSeqNum ..] [VersionedStreamEvent event]
events
    startingSeqNum :: SequenceNumber
startingSeqNum =
      case QueryStart SequenceNumber
start of
        QueryStart SequenceNumber
StartFromBeginning -> SequenceNumber
1
        (StartQueryAt SequenceNumber
startSeq) -> SequenceNumber
startSeq

storeEventMap ::
  EventMap event -> UUID -> [event] -> (EventMap event, EventVersion)
storeEventMap :: forall event.
EventMap event -> UUID -> [event] -> (EventMap event, EventVersion)
storeEventMap store :: EventMap event
store@(EventMap Map UUID (Seq (VersionedStreamEvent event))
uuidMap Seq (VersionedStreamEvent event)
globalEvents) UUID
uuid [event]
events =
  let versStart :: EventVersion
versStart = EventMap event -> UUID -> EventVersion
forall event. EventMap event -> UUID -> EventVersion
latestEventVersion EventMap event
store UUID
uuid
      streamEvents :: [VersionedStreamEvent event]
streamEvents = (EventVersion -> event -> VersionedStreamEvent event)
-> [EventVersion] -> [event] -> [VersionedStreamEvent event]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (UUID -> EventVersion -> event -> VersionedStreamEvent event
forall key position event.
key -> position -> event -> StreamEvent key position event
StreamEvent UUID
uuid) [EventVersion
versStart EventVersion -> EventVersion -> EventVersion
forall a. Num a => a -> a -> a
+ EventVersion
1 ..] [event]
events
      newMap :: Map UUID (Seq (VersionedStreamEvent event))
newMap = (Seq (VersionedStreamEvent event)
 -> Seq (VersionedStreamEvent event)
 -> Seq (VersionedStreamEvent event))
-> UUID
-> Seq (VersionedStreamEvent event)
-> Map UUID (Seq (VersionedStreamEvent event))
-> Map UUID (Seq (VersionedStreamEvent event))
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith ((Seq (VersionedStreamEvent event)
 -> Seq (VersionedStreamEvent event)
 -> Seq (VersionedStreamEvent event))
-> Seq (VersionedStreamEvent event)
-> Seq (VersionedStreamEvent event)
-> Seq (VersionedStreamEvent event)
forall a b c. (a -> b -> c) -> b -> a -> c
flip Seq (VersionedStreamEvent event)
-> Seq (VersionedStreamEvent event)
-> Seq (VersionedStreamEvent event)
forall a. Seq a -> Seq a -> Seq a
(><)) UUID
uuid ([VersionedStreamEvent event] -> Seq (VersionedStreamEvent event)
forall a. [a] -> Seq a
Seq.fromList [VersionedStreamEvent event]
streamEvents) Map UUID (Seq (VersionedStreamEvent event))
uuidMap
      globalEvents' :: Seq (VersionedStreamEvent event)
globalEvents' = Seq (VersionedStreamEvent event)
globalEvents Seq (VersionedStreamEvent event)
-> Seq (VersionedStreamEvent event)
-> Seq (VersionedStreamEvent event)
forall a. Seq a -> Seq a -> Seq a
>< [VersionedStreamEvent event] -> Seq (VersionedStreamEvent event)
forall a. [a] -> Seq a
Seq.fromList [VersionedStreamEvent event]
streamEvents
   in (Map UUID (Seq (VersionedStreamEvent event))
-> Seq (VersionedStreamEvent event) -> EventMap event
forall event.
Map UUID (Seq (VersionedStreamEvent event))
-> Seq (VersionedStreamEvent event) -> EventMap event
EventMap Map UUID (Seq (VersionedStreamEvent event))
newMap Seq (VersionedStreamEvent event)
globalEvents', EventVersion
versStart EventVersion -> EventVersion -> EventVersion
forall a. Num a => a -> a -> a
+ Int -> EventVersion
EventVersion ([event] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [event]
events))