polysemy-db-0.0.1.0: lib/Polysemy/Db/Interpreter/Store.hs
module Polysemy.Db.Interpreter.Store where
import Conc (interpretAtomic)
import qualified Data.Map.Strict as Map
import Exon (exon)
import Sqel.Data.Uid (Uid (Uid))
import qualified Polysemy.Db.Data.DbError as DbError
import Polysemy.Db.Data.DbError (DbError)
import Polysemy.Db.Effect.Store (QStore (..), Store)
newtype PureStore i a =
PureStore { records :: Map i (Uid i a) }
deriving stock (Eq, Show, Generic)
deriving newtype (Default, Semigroup, Monoid)
pureStore ::
Ord i =>
[Uid i a] ->
PureStore i a
pureStore =
PureStore . Map.fromList . fmap \ a@(Uid i _) -> (i, a)
interpretStoreAtomicState ::
∀ i a r .
Ord i =>
Show i =>
Member (AtomicState (PureStore i a)) r =>
InterpreterFor (Store i a !! DbError) r
interpretStoreAtomicState =
interpretResumable \case
Insert a@(Uid i _) ->
stopEither =<< atomicState' \ (PureStore records) ->
let
update = \case
Just x -> (Left (DbError.Query [exon|'#{show i}' is already in the store|]), Just x)
Nothing -> (Right (), Just a)
in first PureStore (swap (Map.alterF update i records))
Upsert a@(Uid i _) ->
atomicModify' (#records %~ Map.insert i a)
Delete i ->
atomicState' \ (PureStore as) -> (PureStore (Map.delete i as), Map.lookup i as)
DeleteAll ->
atomicState' \ (PureStore as) -> (mempty, Map.elems as)
Fetch i ->
atomicGets \ (PureStore as) -> Map.lookup i as
FetchAll ->
atomicGets \ (PureStore as) -> Map.elems as
interpretStoreConc ::
∀ i a r .
Ord i =>
Show i =>
Member (Embed IO) r =>
PureStore i a ->
InterpretersFor [Store i a !! DbError, AtomicState (PureStore i a)] r
interpretStoreConc initial =
interpretAtomic initial .
interpretStoreAtomicState
interpretStoreState ::
∀ i a r .
Ord i =>
Show i =>
Member (State (PureStore i a)) r =>
InterpreterFor (Store i a !! DbError) r
interpretStoreState =
atomicStateToState .
interpretStoreAtomicState .
raiseUnder
interpretStoreLocal ::
∀ i a r .
Ord i =>
Show i =>
PureStore i a ->
InterpretersFor [Store i a !! DbError, State (PureStore i a)] r
interpretStoreLocal initial =
evalState initial .
interpretStoreState
interpretStoreNull ::
InterpreterFor (Store i a !! e) r
interpretStoreNull =
interpretResumable \case
Insert _ ->
unit
Upsert _ ->
unit
Delete _ ->
pure Nothing
DeleteAll ->
pure []
Fetch _ ->
pure Nothing
FetchAll ->
pure []