on 06f67cf help sign in
rel8/src/Rel8/Query/Maybe.hs
60 lines 1.8 kB history raw
1module Rel8.Query.Maybe
2 ( optional
3 , catMaybeTable
4 , bindMaybeTable
5 , traverseMaybeTable
6 )
7where
9-- base
10import Prelude
12-- opaleye
13import qualified Opaleye.Internal.PackMap as Opaleye
14import qualified Opaleye.Internal.PrimQuery as Opaleye
15import qualified Opaleye.Internal.QueryArr as Opaleye
16import qualified Opaleye.Internal.Tag as Opaleye
17import qualified Opaleye.Internal.Unpackspec as Opaleye
19-- rel8
20import Rel8.Expr.Bool ( true )
21import Rel8.Expr.Eq ( (==.) )
22import Rel8.Expr.Opaleye ( toPrimExpr )
23import Rel8.Query ( Query )
24import Rel8.Query.Filter ( where_ )
25import Rel8.Query.Opaleye ( mapOpaleye )
26import Rel8.Table.Maybe ( MaybeTable( MaybeTable ), isJustTable )
27import Rel8.Table.Opaleye ( unpackspec )
30optional :: Query a -> Query (MaybeTable a)
31optional = mapOpaleye $ Opaleye.QueryArr . go
32 where
33 go query (i, left, tag) = (MaybeTable t' a, join, Opaleye.next tag')
34 where
35 (MaybeTable t a, right, tag') =
36 Opaleye.runSimpleQueryArr (pure <$> query) (i, tag)
37 (t', bindings) = Opaleye.run $
38 Opaleye.runUnpackspec unpackspec (Opaleye.extractAttr "maybe" tag') t
39 join = Opaleye.Join Opaleye.LeftJoin condition [] bindings left right
40 condition = toPrimExpr true
43catMaybeTable :: MaybeTable a -> Query a
44catMaybeTable ma@(MaybeTable _ a) = do
45 where_ $ isJustTable ma
46 pure a
49bindMaybeTable :: Monad m
50 => (a -> m (MaybeTable b)) -> MaybeTable a -> m (MaybeTable b)
51bindMaybeTable query (MaybeTable input a) = do
52 MaybeTable output b <- query a
53 pure $ MaybeTable (input <> output) b
56traverseMaybeTable :: (a -> Query b) -> MaybeTable a -> Query (MaybeTable b)
57traverseMaybeTable query ma@(MaybeTable input _) = do
58 MaybeTable output b <- optional (query =<< catMaybeTable ma)
59 where_ $ output ==. input
60 pure $ MaybeTable input b