{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE RequiredTypeArguments #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE NoFieldSelectors #-}
module Hindsight.Store (
StreamId (..),
EventId (..),
CorrelationId (..),
StreamVersion (..),
EventStore (..),
BackendHandle,
Cursor,
StreamWrite (..),
Transaction (..),
InsertionResult (..),
InsertionSuccess (..),
singleEvent,
multiEvent,
appendAfterAny,
appendToOrCreateStream,
fromWrites,
ExpectedVersion (..),
EventStoreError (..),
ErrorInfo (..),
ConsistencyErrorInfo (..),
VersionMismatch (..),
HandlerException (..),
EventSelector (..),
StreamSelector (..),
StartupPosition (..),
SubscriptionHandle (..),
SubscriptionResult (..),
EventEnvelope (..),
EventHandler,
EventMatcher (..),
match,
)
where
import Control.Exception (Exception, SomeException, displayException)
import Data.Aeson (FromJSON, ToJSON)
import Data.Int (Int64)
import Data.Kind (Constraint, Type)
import Data.Map.Strict (Map)
import Data.Map.Strict qualified as Map
import Data.Proxy (Proxy (..))
import Data.Text (Text)
import Data.Text qualified as T
import Data.Time (UTCTime)
import Data.Typeable (Typeable)
import Data.UUID (UUID)
import GHC.Generics (Generic)
import GHC.TypeLits (Symbol)
import Hindsight.Events
newtype StreamId = StreamId {StreamId -> UUID
toUUID :: UUID}
deriving (StreamId -> StreamId -> Bool
(StreamId -> StreamId -> Bool)
-> (StreamId -> StreamId -> Bool) -> Eq StreamId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StreamId -> StreamId -> Bool
== :: StreamId -> StreamId -> Bool
$c/= :: StreamId -> StreamId -> Bool
/= :: StreamId -> StreamId -> Bool
Eq, Eq StreamId
Eq StreamId =>
(StreamId -> StreamId -> Ordering)
-> (StreamId -> StreamId -> Bool)
-> (StreamId -> StreamId -> Bool)
-> (StreamId -> StreamId -> Bool)
-> (StreamId -> StreamId -> Bool)
-> (StreamId -> StreamId -> StreamId)
-> (StreamId -> StreamId -> StreamId)
-> Ord StreamId
StreamId -> StreamId -> Bool
StreamId -> StreamId -> Ordering
StreamId -> StreamId -> StreamId
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: StreamId -> StreamId -> Ordering
compare :: StreamId -> StreamId -> Ordering
$c< :: StreamId -> StreamId -> Bool
< :: StreamId -> StreamId -> Bool
$c<= :: StreamId -> StreamId -> Bool
<= :: StreamId -> StreamId -> Bool
$c> :: StreamId -> StreamId -> Bool
> :: StreamId -> StreamId -> Bool
$c>= :: StreamId -> StreamId -> Bool
>= :: StreamId -> StreamId -> Bool
$cmax :: StreamId -> StreamId -> StreamId
max :: StreamId -> StreamId -> StreamId
$cmin :: StreamId -> StreamId -> StreamId
min :: StreamId -> StreamId -> StreamId
Ord, Int -> StreamId -> ShowS
[StreamId] -> ShowS
StreamId -> String
(Int -> StreamId -> ShowS)
-> (StreamId -> String) -> ([StreamId] -> ShowS) -> Show StreamId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> StreamId -> ShowS
showsPrec :: Int -> StreamId -> ShowS
$cshow :: StreamId -> String
show :: StreamId -> String
$cshowList :: [StreamId] -> ShowS
showList :: [StreamId] -> ShowS
Show, Maybe StreamId
Value -> Parser [StreamId]
Value -> Parser StreamId
(Value -> Parser StreamId)
-> (Value -> Parser [StreamId])
-> Maybe StreamId
-> FromJSON StreamId
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser StreamId
parseJSON :: Value -> Parser StreamId
$cparseJSONList :: Value -> Parser [StreamId]
parseJSONList :: Value -> Parser [StreamId]
$comittedField :: Maybe StreamId
omittedField :: Maybe StreamId
FromJSON, [StreamId] -> Value
[StreamId] -> Encoding
StreamId -> Bool
StreamId -> Value
StreamId -> Encoding
(StreamId -> Value)
-> (StreamId -> Encoding)
-> ([StreamId] -> Value)
-> ([StreamId] -> Encoding)
-> (StreamId -> Bool)
-> ToJSON StreamId
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: StreamId -> Value
toJSON :: StreamId -> Value
$ctoEncoding :: StreamId -> Encoding
toEncoding :: StreamId -> Encoding
$ctoJSONList :: [StreamId] -> Value
toJSONList :: [StreamId] -> Value
$ctoEncodingList :: [StreamId] -> Encoding
toEncodingList :: [StreamId] -> Encoding
$comitField :: StreamId -> Bool
omitField :: StreamId -> Bool
ToJSON)
newtype EventId = EventId {EventId -> UUID
toUUID :: UUID}
deriving (EventId -> EventId -> Bool
(EventId -> EventId -> Bool)
-> (EventId -> EventId -> Bool) -> Eq EventId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: EventId -> EventId -> Bool
== :: EventId -> EventId -> Bool
$c/= :: EventId -> EventId -> Bool
/= :: EventId -> EventId -> Bool
Eq, Eq EventId
Eq EventId =>
(EventId -> EventId -> Ordering)
-> (EventId -> EventId -> Bool)
-> (EventId -> EventId -> Bool)
-> (EventId -> EventId -> Bool)
-> (EventId -> EventId -> Bool)
-> (EventId -> EventId -> EventId)
-> (EventId -> EventId -> EventId)
-> Ord EventId
EventId -> EventId -> Bool
EventId -> EventId -> Ordering
EventId -> EventId -> EventId
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: EventId -> EventId -> Ordering
compare :: EventId -> EventId -> Ordering
$c< :: EventId -> EventId -> Bool
< :: EventId -> EventId -> Bool
$c<= :: EventId -> EventId -> Bool
<= :: EventId -> EventId -> Bool
$c> :: EventId -> EventId -> Bool
> :: EventId -> EventId -> Bool
$c>= :: EventId -> EventId -> Bool
>= :: EventId -> EventId -> Bool
$cmax :: EventId -> EventId -> EventId
max :: EventId -> EventId -> EventId
$cmin :: EventId -> EventId -> EventId
min :: EventId -> EventId -> EventId
Ord, Int -> EventId -> ShowS
[EventId] -> ShowS
EventId -> String
(Int -> EventId -> ShowS)
-> (EventId -> String) -> ([EventId] -> ShowS) -> Show EventId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> EventId -> ShowS
showsPrec :: Int -> EventId -> ShowS
$cshow :: EventId -> String
show :: EventId -> String
$cshowList :: [EventId] -> ShowS
showList :: [EventId] -> ShowS
Show, Maybe EventId
Value -> Parser [EventId]
Value -> Parser EventId
(Value -> Parser EventId)
-> (Value -> Parser [EventId]) -> Maybe EventId -> FromJSON EventId
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser EventId
parseJSON :: Value -> Parser EventId
$cparseJSONList :: Value -> Parser [EventId]
parseJSONList :: Value -> Parser [EventId]
$comittedField :: Maybe EventId
omittedField :: Maybe EventId
FromJSON, [EventId] -> Value
[EventId] -> Encoding
EventId -> Bool
EventId -> Value
EventId -> Encoding
(EventId -> Value)
-> (EventId -> Encoding)
-> ([EventId] -> Value)
-> ([EventId] -> Encoding)
-> (EventId -> Bool)
-> ToJSON EventId
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: EventId -> Value
toJSON :: EventId -> Value
$ctoEncoding :: EventId -> Encoding
toEncoding :: EventId -> Encoding
$ctoJSONList :: [EventId] -> Value
toJSONList :: [EventId] -> Value
$ctoEncodingList :: [EventId] -> Encoding
toEncodingList :: [EventId] -> Encoding
$comitField :: EventId -> Bool
omitField :: EventId -> Bool
ToJSON)
newtype CorrelationId = CorrelationId {CorrelationId -> UUID
toUUID :: UUID}
deriving (CorrelationId -> CorrelationId -> Bool
(CorrelationId -> CorrelationId -> Bool)
-> (CorrelationId -> CorrelationId -> Bool) -> Eq CorrelationId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CorrelationId -> CorrelationId -> Bool
== :: CorrelationId -> CorrelationId -> Bool
$c/= :: CorrelationId -> CorrelationId -> Bool
/= :: CorrelationId -> CorrelationId -> Bool
Eq, Eq CorrelationId
Eq CorrelationId =>
(CorrelationId -> CorrelationId -> Ordering)
-> (CorrelationId -> CorrelationId -> Bool)
-> (CorrelationId -> CorrelationId -> Bool)
-> (CorrelationId -> CorrelationId -> Bool)
-> (CorrelationId -> CorrelationId -> Bool)
-> (CorrelationId -> CorrelationId -> CorrelationId)
-> (CorrelationId -> CorrelationId -> CorrelationId)
-> Ord CorrelationId
CorrelationId -> CorrelationId -> Bool
CorrelationId -> CorrelationId -> Ordering
CorrelationId -> CorrelationId -> CorrelationId
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: CorrelationId -> CorrelationId -> Ordering
compare :: CorrelationId -> CorrelationId -> Ordering
$c< :: CorrelationId -> CorrelationId -> Bool
< :: CorrelationId -> CorrelationId -> Bool
$c<= :: CorrelationId -> CorrelationId -> Bool
<= :: CorrelationId -> CorrelationId -> Bool
$c> :: CorrelationId -> CorrelationId -> Bool
> :: CorrelationId -> CorrelationId -> Bool
$c>= :: CorrelationId -> CorrelationId -> Bool
>= :: CorrelationId -> CorrelationId -> Bool
$cmax :: CorrelationId -> CorrelationId -> CorrelationId
max :: CorrelationId -> CorrelationId -> CorrelationId
$cmin :: CorrelationId -> CorrelationId -> CorrelationId
min :: CorrelationId -> CorrelationId -> CorrelationId
Ord, Int -> CorrelationId -> ShowS
[CorrelationId] -> ShowS
CorrelationId -> String
(Int -> CorrelationId -> ShowS)
-> (CorrelationId -> String)
-> ([CorrelationId] -> ShowS)
-> Show CorrelationId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CorrelationId -> ShowS
showsPrec :: Int -> CorrelationId -> ShowS
$cshow :: CorrelationId -> String
show :: CorrelationId -> String
$cshowList :: [CorrelationId] -> ShowS
showList :: [CorrelationId] -> ShowS
Show, Maybe CorrelationId
Value -> Parser [CorrelationId]
Value -> Parser CorrelationId
(Value -> Parser CorrelationId)
-> (Value -> Parser [CorrelationId])
-> Maybe CorrelationId
-> FromJSON CorrelationId
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser CorrelationId
parseJSON :: Value -> Parser CorrelationId
$cparseJSONList :: Value -> Parser [CorrelationId]
parseJSONList :: Value -> Parser [CorrelationId]
$comittedField :: Maybe CorrelationId
omittedField :: Maybe CorrelationId
FromJSON, [CorrelationId] -> Value
[CorrelationId] -> Encoding
CorrelationId -> Bool
CorrelationId -> Value
CorrelationId -> Encoding
(CorrelationId -> Value)
-> (CorrelationId -> Encoding)
-> ([CorrelationId] -> Value)
-> ([CorrelationId] -> Encoding)
-> (CorrelationId -> Bool)
-> ToJSON CorrelationId
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: CorrelationId -> Value
toJSON :: CorrelationId -> Value
$ctoEncoding :: CorrelationId -> Encoding
toEncoding :: CorrelationId -> Encoding
$ctoJSONList :: [CorrelationId] -> Value
toJSONList :: [CorrelationId] -> Value
$ctoEncodingList :: [CorrelationId] -> Encoding
toEncodingList :: [CorrelationId] -> Encoding
$comitField :: CorrelationId -> Bool
omitField :: CorrelationId -> Bool
ToJSON)
newtype StreamVersion = StreamVersion Int64
deriving (Int -> StreamVersion -> ShowS
[StreamVersion] -> ShowS
StreamVersion -> String
(Int -> StreamVersion -> ShowS)
-> (StreamVersion -> String)
-> ([StreamVersion] -> ShowS)
-> Show StreamVersion
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> StreamVersion -> ShowS
showsPrec :: Int -> StreamVersion -> ShowS
$cshow :: StreamVersion -> String
show :: StreamVersion -> String
$cshowList :: [StreamVersion] -> ShowS
showList :: [StreamVersion] -> ShowS
Show, StreamVersion -> StreamVersion -> Bool
(StreamVersion -> StreamVersion -> Bool)
-> (StreamVersion -> StreamVersion -> Bool) -> Eq StreamVersion
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StreamVersion -> StreamVersion -> Bool
== :: StreamVersion -> StreamVersion -> Bool
$c/= :: StreamVersion -> StreamVersion -> Bool
/= :: StreamVersion -> StreamVersion -> Bool
Eq, Eq StreamVersion
Eq StreamVersion =>
(StreamVersion -> StreamVersion -> Ordering)
-> (StreamVersion -> StreamVersion -> Bool)
-> (StreamVersion -> StreamVersion -> Bool)
-> (StreamVersion -> StreamVersion -> Bool)
-> (StreamVersion -> StreamVersion -> Bool)
-> (StreamVersion -> StreamVersion -> StreamVersion)
-> (StreamVersion -> StreamVersion -> StreamVersion)
-> Ord StreamVersion
StreamVersion -> StreamVersion -> Bool
StreamVersion -> StreamVersion -> Ordering
StreamVersion -> StreamVersion -> StreamVersion
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: StreamVersion -> StreamVersion -> Ordering
compare :: StreamVersion -> StreamVersion -> Ordering
$c< :: StreamVersion -> StreamVersion -> Bool
< :: StreamVersion -> StreamVersion -> Bool
$c<= :: StreamVersion -> StreamVersion -> Bool
<= :: StreamVersion -> StreamVersion -> Bool
$c> :: StreamVersion -> StreamVersion -> Bool
> :: StreamVersion -> StreamVersion -> Bool
$c>= :: StreamVersion -> StreamVersion -> Bool
>= :: StreamVersion -> StreamVersion -> Bool
$cmax :: StreamVersion -> StreamVersion -> StreamVersion
max :: StreamVersion -> StreamVersion -> StreamVersion
$cmin :: StreamVersion -> StreamVersion -> StreamVersion
min :: StreamVersion -> StreamVersion -> StreamVersion
Ord, (forall x. StreamVersion -> Rep StreamVersion x)
-> (forall x. Rep StreamVersion x -> StreamVersion)
-> Generic StreamVersion
forall x. Rep StreamVersion x -> StreamVersion
forall x. StreamVersion -> Rep StreamVersion x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. StreamVersion -> Rep StreamVersion x
from :: forall x. StreamVersion -> Rep StreamVersion x
$cto :: forall x. Rep StreamVersion x -> StreamVersion
to :: forall x. Rep StreamVersion x -> StreamVersion
Generic, Maybe StreamVersion
Value -> Parser [StreamVersion]
Value -> Parser StreamVersion
(Value -> Parser StreamVersion)
-> (Value -> Parser [StreamVersion])
-> Maybe StreamVersion
-> FromJSON StreamVersion
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser StreamVersion
parseJSON :: Value -> Parser StreamVersion
$cparseJSONList :: Value -> Parser [StreamVersion]
parseJSONList :: Value -> Parser [StreamVersion]
$comittedField :: Maybe StreamVersion
omittedField :: Maybe StreamVersion
FromJSON, [StreamVersion] -> Value
[StreamVersion] -> Encoding
StreamVersion -> Bool
StreamVersion -> Value
StreamVersion -> Encoding
(StreamVersion -> Value)
-> (StreamVersion -> Encoding)
-> ([StreamVersion] -> Value)
-> ([StreamVersion] -> Encoding)
-> (StreamVersion -> Bool)
-> ToJSON StreamVersion
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: StreamVersion -> Value
toJSON :: StreamVersion -> Value
$ctoEncoding :: StreamVersion -> Encoding
toEncoding :: StreamVersion -> Encoding
$ctoJSONList :: [StreamVersion] -> Value
toJSONList :: [StreamVersion] -> Value
$ctoEncodingList :: [StreamVersion] -> Encoding
toEncodingList :: [StreamVersion] -> Encoding
$comitField :: StreamVersion -> Bool
omitField :: StreamVersion -> Bool
ToJSON, Integer -> StreamVersion
StreamVersion -> StreamVersion
StreamVersion -> StreamVersion -> StreamVersion
(StreamVersion -> StreamVersion -> StreamVersion)
-> (StreamVersion -> StreamVersion -> StreamVersion)
-> (StreamVersion -> StreamVersion -> StreamVersion)
-> (StreamVersion -> StreamVersion)
-> (StreamVersion -> StreamVersion)
-> (StreamVersion -> StreamVersion)
-> (Integer -> StreamVersion)
-> Num StreamVersion
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: StreamVersion -> StreamVersion -> StreamVersion
+ :: StreamVersion -> StreamVersion -> StreamVersion
$c- :: StreamVersion -> StreamVersion -> StreamVersion
- :: StreamVersion -> StreamVersion -> StreamVersion
$c* :: StreamVersion -> StreamVersion -> StreamVersion
* :: StreamVersion -> StreamVersion -> StreamVersion
$cnegate :: StreamVersion -> StreamVersion
negate :: StreamVersion -> StreamVersion
$cabs :: StreamVersion -> StreamVersion
abs :: StreamVersion -> StreamVersion
$csignum :: StreamVersion -> StreamVersion
signum :: StreamVersion -> StreamVersion
$cfromInteger :: Integer -> StreamVersion
fromInteger :: Integer -> StreamVersion
Num, Int -> StreamVersion
StreamVersion -> Int
StreamVersion -> [StreamVersion]
StreamVersion -> StreamVersion
StreamVersion -> StreamVersion -> [StreamVersion]
StreamVersion -> StreamVersion -> StreamVersion -> [StreamVersion]
(StreamVersion -> StreamVersion)
-> (StreamVersion -> StreamVersion)
-> (Int -> StreamVersion)
-> (StreamVersion -> Int)
-> (StreamVersion -> [StreamVersion])
-> (StreamVersion -> StreamVersion -> [StreamVersion])
-> (StreamVersion -> StreamVersion -> [StreamVersion])
-> (StreamVersion
-> StreamVersion -> StreamVersion -> [StreamVersion])
-> Enum StreamVersion
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: StreamVersion -> StreamVersion
succ :: StreamVersion -> StreamVersion
$cpred :: StreamVersion -> StreamVersion
pred :: StreamVersion -> StreamVersion
$ctoEnum :: Int -> StreamVersion
toEnum :: Int -> StreamVersion
$cfromEnum :: StreamVersion -> Int
fromEnum :: StreamVersion -> Int
$cenumFrom :: StreamVersion -> [StreamVersion]
enumFrom :: StreamVersion -> [StreamVersion]
$cenumFromThen :: StreamVersion -> StreamVersion -> [StreamVersion]
enumFromThen :: StreamVersion -> StreamVersion -> [StreamVersion]
$cenumFromTo :: StreamVersion -> StreamVersion -> [StreamVersion]
enumFromTo :: StreamVersion -> StreamVersion -> [StreamVersion]
$cenumFromThenTo :: StreamVersion -> StreamVersion -> StreamVersion -> [StreamVersion]
enumFromThenTo :: StreamVersion -> StreamVersion -> StreamVersion -> [StreamVersion]
Enum)
data ErrorInfo = ErrorInfo
{ ErrorInfo -> Text
errorMessage :: Text
, ErrorInfo -> Maybe SomeException
exception :: Maybe SomeException
}
deriving (Int -> ErrorInfo -> ShowS
[ErrorInfo] -> ShowS
ErrorInfo -> String
(Int -> ErrorInfo -> ShowS)
-> (ErrorInfo -> String)
-> ([ErrorInfo] -> ShowS)
-> Show ErrorInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ErrorInfo -> ShowS
showsPrec :: Int -> ErrorInfo -> ShowS
$cshow :: ErrorInfo -> String
show :: ErrorInfo -> String
$cshowList :: [ErrorInfo] -> ShowS
showList :: [ErrorInfo] -> ShowS
Show)
data ConsistencyErrorInfo backend = ConsistencyErrorInfo [VersionMismatch backend]
data VersionMismatch backend = VersionMismatch
{ forall backend. VersionMismatch backend -> StreamId
streamId :: StreamId
, forall backend. VersionMismatch backend -> ExpectedVersion backend
expectedVersion :: ExpectedVersion backend
, forall backend. VersionMismatch backend -> Maybe (Cursor backend)
actualVersion :: Maybe (Cursor backend)
}
data EventStoreError backend
=
ConsistencyError (ConsistencyErrorInfo backend)
|
BackendError ErrorInfo
|
OtherError ErrorInfo
deriving instance (Show (Cursor backend)) => Show (VersionMismatch backend)
deriving instance (Show (Cursor backend)) => Show (ConsistencyErrorInfo backend)
deriving instance (Show (Cursor backend)) => Show (EventStoreError backend)
data HandlerException = HandlerException
{ HandlerException -> SomeException
originalException :: SomeException
, HandlerException -> Text
failedEventPosition :: Text
, HandlerException -> EventId
failedEventId :: EventId
, HandlerException -> Text
failedEventName :: Text
, HandlerException -> StreamId
failedEventStreamId :: StreamId
, HandlerException -> StreamVersion
failedEventStreamVersion :: StreamVersion
, HandlerException -> Maybe CorrelationId
failedEventCorrelationId :: Maybe CorrelationId
, HandlerException -> UTCTime
failedEventCreatedAt :: UTCTime
}
deriving (Typeable)
instance Show HandlerException where
show :: HandlerException -> String
show HandlerException
e =
String
"Handler exception at position "
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack HandlerException
e.failedEventPosition
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" for event '"
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack HandlerException
e.failedEventName
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"'"
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" (eventId: "
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> EventId -> String
forall a. Show a => a -> String
show HandlerException
e.failedEventId
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
")"
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" in stream "
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> StreamId -> String
forall a. Show a => a -> String
show HandlerException
e.failedEventStreamId
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" (stream version: "
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> StreamVersion -> String
forall a. Show a => a -> String
show HandlerException
e.failedEventStreamVersion
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
")"
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
": "
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> SomeException -> String
forall e. Exception e => e -> String
displayException HandlerException
e.originalException
instance Exception HandlerException
data InsertionSuccess backend = InsertionSuccess
{ forall backend. InsertionSuccess backend -> Cursor backend
finalCursor :: Cursor backend
, forall backend.
InsertionSuccess backend -> Map StreamId (Cursor backend)
streamCursors :: Map StreamId (Cursor backend)
}
data InsertionResult backend
=
SuccessfulInsertion (InsertionSuccess backend)
|
FailedInsertion (EventStoreError backend)
data SubscriptionResult
=
Stop
|
Continue
deriving (SubscriptionResult -> SubscriptionResult -> Bool
(SubscriptionResult -> SubscriptionResult -> Bool)
-> (SubscriptionResult -> SubscriptionResult -> Bool)
-> Eq SubscriptionResult
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SubscriptionResult -> SubscriptionResult -> Bool
== :: SubscriptionResult -> SubscriptionResult -> Bool
$c/= :: SubscriptionResult -> SubscriptionResult -> Bool
/= :: SubscriptionResult -> SubscriptionResult -> Bool
Eq, Int -> SubscriptionResult -> ShowS
[SubscriptionResult] -> ShowS
SubscriptionResult -> String
(Int -> SubscriptionResult -> ShowS)
-> (SubscriptionResult -> String)
-> ([SubscriptionResult] -> ShowS)
-> Show SubscriptionResult
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SubscriptionResult -> ShowS
showsPrec :: Int -> SubscriptionResult -> ShowS
$cshow :: SubscriptionResult -> String
show :: SubscriptionResult -> String
$cshowList :: [SubscriptionResult] -> ShowS
showList :: [SubscriptionResult] -> ShowS
Show)
data SubscriptionHandle backend = SubscriptionHandle
{ forall {k} (backend :: k). SubscriptionHandle backend -> IO ()
cancel :: IO ()
, forall {k} (backend :: k). SubscriptionHandle backend -> IO ()
wait :: IO ()
}
data EventEnvelope event backend = EventWithMetadata
{ forall (event :: Symbol) backend.
EventEnvelope event backend -> Cursor backend
position :: Cursor backend
, forall (event :: Symbol) backend.
EventEnvelope event backend -> EventId
eventId :: EventId
, forall (event :: Symbol) backend.
EventEnvelope event backend -> StreamId
streamId :: StreamId
, forall (event :: Symbol) backend.
EventEnvelope event backend -> StreamVersion
streamVersion :: StreamVersion
, forall (event :: Symbol) backend.
EventEnvelope event backend -> Maybe CorrelationId
correlationId :: Maybe CorrelationId
, forall (event :: Symbol) backend.
EventEnvelope event backend -> UTCTime
createdAt :: UTCTime
, forall (event :: Symbol) backend.
EventEnvelope event backend -> CurrentPayloadType event
payload :: CurrentPayloadType event
}
deriving instance (Show (CurrentPayloadType event), Show (Cursor backend)) => Show (EventEnvelope event backend)
data EventSelector backend = EventSelector
{ forall backend. EventSelector backend -> StreamSelector
streamId :: StreamSelector
, forall backend. EventSelector backend -> StartupPosition backend
startupPosition :: StartupPosition backend
}
deriving instance (Show (StartupPosition backend)) => Show (EventSelector backend)
data StreamSelector
=
AllStreams
|
SingleStream StreamId
deriving (Int -> StreamSelector -> ShowS
[StreamSelector] -> ShowS
StreamSelector -> String
(Int -> StreamSelector -> ShowS)
-> (StreamSelector -> String)
-> ([StreamSelector] -> ShowS)
-> Show StreamSelector
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> StreamSelector -> ShowS
showsPrec :: Int -> StreamSelector -> ShowS
$cshow :: StreamSelector -> String
show :: StreamSelector -> String
$cshowList :: [StreamSelector] -> ShowS
showList :: [StreamSelector] -> ShowS
Show)
data StartupPosition backend
=
FromBeginning
|
FromLastProcessed (Cursor backend)
deriving instance (Show (Cursor backend)) => Show (StartupPosition backend)
type EventHandler event m backend = EventEnvelope event backend -> m SubscriptionResult
data EventMatcher (ts :: [Symbol]) backend m where
(:?) :: (Event event) => (Proxy event, EventHandler event m backend) -> EventMatcher ts backend m -> EventMatcher (event ': ts) backend m
MatchEnd :: EventMatcher '[] backend m
infixr 5 :?
match ::
forall event ->
forall a.
a ->
(Proxy event, a)
match :: forall {k}. forall (event :: k) -> forall a. a -> (Proxy event, a)
match event = \a
handler -> (forall (t :: k). Proxy t
forall {k} (t :: k). Proxy t
Proxy @event, a
handler)
type family Cursor backend = result | result -> backend
type family BackendHandle backend = result | result -> backend
data ExpectedVersion backend
=
NoStream
|
StreamExists
|
ExactVersion (Cursor backend)
|
ExactStreamVersion StreamVersion
|
Any
deriving instance (Show (Cursor backend)) => Show (ExpectedVersion backend)
deriving instance (Eq (Cursor backend)) => Eq (ExpectedVersion backend)
data StreamWrite t e backend = StreamWrite
{ forall {k} (t :: k -> *) (e :: k) backend.
StreamWrite t e backend -> ExpectedVersion backend
expectedVersion :: ExpectedVersion backend
, forall {k} (t :: k -> *) (e :: k) backend.
StreamWrite t e backend -> t e
events :: t e
}
deriving instance (Show (ExpectedVersion backend), Show (t e)) => Show (StreamWrite t e backend)
deriving instance (Eq (ExpectedVersion backend), Eq (t e)) => Eq (StreamWrite t e backend)
newtype Transaction t backend = Transaction
{ forall (t :: * -> *) backend.
Transaction t backend
-> Map StreamId (StreamWrite t SomeLatestEvent backend)
transactionWrites :: Map StreamId (StreamWrite t SomeLatestEvent backend)
}
deriving instance (Show (Cursor backend), Show (t SomeLatestEvent)) => Show (Transaction t backend)
deriving instance (Eq (Cursor backend), Eq (t SomeLatestEvent)) => Eq (Transaction t backend)
instance (Semigroup (t SomeLatestEvent)) => Semigroup (Transaction t backend) where
Transaction Map StreamId (StreamWrite t SomeLatestEvent backend)
m1 <> :: Transaction t backend
-> Transaction t backend -> Transaction t backend
<> Transaction Map StreamId (StreamWrite t SomeLatestEvent backend)
m2 =
Map StreamId (StreamWrite t SomeLatestEvent backend)
-> Transaction t backend
forall (t :: * -> *) backend.
Map StreamId (StreamWrite t SomeLatestEvent backend)
-> Transaction t backend
Transaction ((StreamWrite t SomeLatestEvent backend
-> StreamWrite t SomeLatestEvent backend
-> StreamWrite t SomeLatestEvent backend)
-> Map StreamId (StreamWrite t SomeLatestEvent backend)
-> Map StreamId (StreamWrite t SomeLatestEvent backend)
-> Map StreamId (StreamWrite t SomeLatestEvent backend)
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith StreamWrite t SomeLatestEvent backend
-> StreamWrite t SomeLatestEvent backend
-> StreamWrite t SomeLatestEvent backend
forall {k} {t :: k -> *} {e :: k} {backend} {backend}.
Semigroup (t e) =>
StreamWrite t e backend
-> StreamWrite t e backend -> StreamWrite t e backend
combineWrites Map StreamId (StreamWrite t SomeLatestEvent backend)
m1 Map StreamId (StreamWrite t SomeLatestEvent backend)
m2)
where
combineWrites :: StreamWrite t e backend
-> StreamWrite t e backend -> StreamWrite t e backend
combineWrites (StreamWrite ExpectedVersion backend
expectedVer t e
events1) (StreamWrite ExpectedVersion backend
_ignored t e
events2) =
ExpectedVersion backend -> t e -> StreamWrite t e backend
forall {k} (t :: k -> *) (e :: k) backend.
ExpectedVersion backend -> t e -> StreamWrite t e backend
StreamWrite ExpectedVersion backend
expectedVer (t e
events1 t e -> t e -> t e
forall a. Semigroup a => a -> a -> a
<> t e
events2)
instance (Semigroup (t SomeLatestEvent)) => Monoid (Transaction t backend) where
mempty :: Transaction t backend
mempty = Map StreamId (StreamWrite t SomeLatestEvent backend)
-> Transaction t backend
forall (t :: * -> *) backend.
Map StreamId (StreamWrite t SomeLatestEvent backend)
-> Transaction t backend
Transaction Map StreamId (StreamWrite t SomeLatestEvent backend)
forall k a. Map k a
Map.empty
singleEvent ::
StreamId ->
ExpectedVersion backend ->
SomeLatestEvent ->
Transaction [] backend
singleEvent :: forall backend.
StreamId
-> ExpectedVersion backend
-> SomeLatestEvent
-> Transaction [] backend
singleEvent StreamId
streamId ExpectedVersion backend
expectedVer SomeLatestEvent
event =
Map StreamId (StreamWrite [] SomeLatestEvent backend)
-> Transaction [] backend
forall (t :: * -> *) backend.
Map StreamId (StreamWrite t SomeLatestEvent backend)
-> Transaction t backend
Transaction (Map StreamId (StreamWrite [] SomeLatestEvent backend)
-> Transaction [] backend)
-> Map StreamId (StreamWrite [] SomeLatestEvent backend)
-> Transaction [] backend
forall a b. (a -> b) -> a -> b
$ StreamId
-> StreamWrite [] SomeLatestEvent backend
-> Map StreamId (StreamWrite [] SomeLatestEvent backend)
forall k a. k -> a -> Map k a
Map.singleton StreamId
streamId (ExpectedVersion backend
-> [SomeLatestEvent] -> StreamWrite [] SomeLatestEvent backend
forall {k} (t :: k -> *) (e :: k) backend.
ExpectedVersion backend -> t e -> StreamWrite t e backend
StreamWrite ExpectedVersion backend
expectedVer [SomeLatestEvent
event])
multiEvent ::
StreamId ->
ExpectedVersion backend ->
t SomeLatestEvent ->
Transaction t backend
multiEvent :: forall backend (t :: * -> *).
StreamId
-> ExpectedVersion backend
-> t SomeLatestEvent
-> Transaction t backend
multiEvent StreamId
streamId ExpectedVersion backend
expectedVer t SomeLatestEvent
events =
Map StreamId (StreamWrite t SomeLatestEvent backend)
-> Transaction t backend
forall (t :: * -> *) backend.
Map StreamId (StreamWrite t SomeLatestEvent backend)
-> Transaction t backend
Transaction (Map StreamId (StreamWrite t SomeLatestEvent backend)
-> Transaction t backend)
-> Map StreamId (StreamWrite t SomeLatestEvent backend)
-> Transaction t backend
forall a b. (a -> b) -> a -> b
$ StreamId
-> StreamWrite t SomeLatestEvent backend
-> Map StreamId (StreamWrite t SomeLatestEvent backend)
forall k a. k -> a -> Map k a
Map.singleton StreamId
streamId (ExpectedVersion backend
-> t SomeLatestEvent -> StreamWrite t SomeLatestEvent backend
forall {k} (t :: k -> *) (e :: k) backend.
ExpectedVersion backend -> t e -> StreamWrite t e backend
StreamWrite ExpectedVersion backend
expectedVer t SomeLatestEvent
events)
appendAfterAny ::
StreamId ->
SomeLatestEvent ->
Transaction [] backend
appendAfterAny :: forall backend.
StreamId -> SomeLatestEvent -> Transaction [] backend
appendAfterAny StreamId
streamId SomeLatestEvent
event =
StreamId
-> ExpectedVersion backend
-> SomeLatestEvent
-> Transaction [] backend
forall backend.
StreamId
-> ExpectedVersion backend
-> SomeLatestEvent
-> Transaction [] backend
singleEvent StreamId
streamId ExpectedVersion backend
forall backend. ExpectedVersion backend
StreamExists SomeLatestEvent
event
appendToOrCreateStream ::
StreamId ->
SomeLatestEvent ->
Transaction [] backend
appendToOrCreateStream :: forall backend.
StreamId -> SomeLatestEvent -> Transaction [] backend
appendToOrCreateStream StreamId
streamId SomeLatestEvent
event =
StreamId
-> ExpectedVersion backend
-> SomeLatestEvent
-> Transaction [] backend
forall backend.
StreamId
-> ExpectedVersion backend
-> SomeLatestEvent
-> Transaction [] backend
singleEvent StreamId
streamId ExpectedVersion backend
forall backend. ExpectedVersion backend
Any SomeLatestEvent
event
fromWrites ::
[(StreamId, StreamWrite t SomeLatestEvent backend)] ->
Transaction t backend
fromWrites :: forall (t :: * -> *) backend.
[(StreamId, StreamWrite t SomeLatestEvent backend)]
-> Transaction t backend
fromWrites = Map StreamId (StreamWrite t SomeLatestEvent backend)
-> Transaction t backend
forall (t :: * -> *) backend.
Map StreamId (StreamWrite t SomeLatestEvent backend)
-> Transaction t backend
Transaction (Map StreamId (StreamWrite t SomeLatestEvent backend)
-> Transaction t backend)
-> ([(StreamId, StreamWrite t SomeLatestEvent backend)]
-> Map StreamId (StreamWrite t SomeLatestEvent backend))
-> [(StreamId, StreamWrite t SomeLatestEvent backend)]
-> Transaction t backend
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(StreamId, StreamWrite t SomeLatestEvent backend)]
-> Map StreamId (StreamWrite t SomeLatestEvent backend)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
class EventStore (backend :: Type) where
type StoreConstraints backend (m :: Type -> Type) :: Constraint
insertEvents ::
(Traversable t, StoreConstraints backend m) =>
BackendHandle backend ->
Maybe CorrelationId ->
Transaction t backend ->
m (InsertionResult backend)
subscribe ::
(StoreConstraints backend m) =>
BackendHandle backend ->
EventMatcher ts backend m ->
EventSelector backend ->
m (SubscriptionHandle backend)