{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE RecordWildCards #-}
module Database.EventStore.Internal.Operation.StreamMetadata
( readMetaStream
, setMetaStream
) where
import Data.Int
import Data.Aeson (decode)
import Database.EventStore.Internal.Exec (Exec)
import Database.EventStore.Internal.Operation
import Database.EventStore.Internal.Operation.Read.Common
import Database.EventStore.Internal.Operation.ReadEvent
import Database.EventStore.Internal.Operation.Write.Common
import Database.EventStore.Internal.Operation.WriteEvents
import Database.EventStore.Internal.Prelude
import Database.EventStore.Internal.Settings
import Database.EventStore.Internal.Types
metaStream :: Text -> Text
metaStream s = "$$" <> s
readMetaStream
:: Settings
-> Exec
-> Text
-> Maybe Credentials
-> IO (Async StreamMetadataResult)
readMetaStream setts exec s cred
= async $
do as <- readEvent setts exec (metaStream s) (-1) False cred
tmp <- wait as
onReadResult tmp $ \n evtNum evt ->
do let bytes = recordedEventData $ resolvedEventOriginal evt
case decode $ fromStrict bytes of
Just pv -> pure $ StreamMetadataResult n evtNum pv
Nothing -> throw invalidFormat
setMetaStream
:: Settings
-> Exec
-> Text
-> ExpectedVersion
-> Maybe Credentials
-> StreamMetadata
-> IO (Async WriteResult)
setMetaStream setts exec s v cred meta
= let stream = metaStream s
json = streamMetadataJSON meta
evt = createEvent StreamMetadataType Nothing (withJson json) in
writeEvents setts exec stream v cred [evt]
invalidFormat :: OperationError
invalidFormat = InvalidOperation "Invalid metadata format"
streamNotFound :: OperationError
streamNotFound = InvalidOperation "Read metadata on an inexistant stream"
onReadResult :: ReadResult EventNumber ReadEvent
-> (Text -> Int64 -> ResolvedEvent -> IO a)
-> IO a
onReadResult (ReadSuccess r) k =
case r of
ReadEvent s n e -> k s n e
_ -> throw streamNotFound
onReadResult ReadNoStream _ = throw streamNotFound
onReadResult (ReadStreamDeleted s) _ = throw $ StreamDeleted s
onReadResult ReadNotModified _ = throw $ ServerError Nothing
onReadResult (ReadError e) _ = throw $ ServerError e
onReadResult (ReadAccessDenied s) _ = throw $ AccessDenied s