{-# language FlexibleContexts #-}

module Rel8.Query.Null
  ( catNull
  , catNullTable
  )
where

-- base
import Prelude

-- rel8
import Rel8.Expr ( Expr )
import Rel8.Expr.Null ( isNonNull, unsafeUnnullify )
import Rel8.Table ( Table )
import Rel8.Table.Null ( NullTable, isNonNullTable, unsafeUnnullifyTable )
import Rel8.Query ( Query )
import Rel8.Query.Filter ( where_ )


-- | Filter a 'Query' that might return @null@ to a 'Query' without any
-- @null@s.
--
-- Corresponds to 'Data.Maybe.catMaybes'.
catNull :: Expr (Maybe a) -> Query (Expr a)
catNull :: forall a. Expr (Maybe a) -> Query (Expr a)
catNull Expr (Maybe a)
a = do
  Expr Bool -> Query ()
where_ (Expr Bool -> Query ()) -> Expr Bool -> Query ()
forall a b. (a -> b) -> a -> b
$ Expr (Maybe a) -> Expr Bool
forall a. Expr (Maybe a) -> Expr Bool
isNonNull Expr (Maybe a)
a
  Expr a -> Query (Expr a)
forall a. a -> Query a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr a -> Query (Expr a)) -> Expr a -> Query (Expr a)
forall a b. (a -> b) -> a -> b
$ Expr (Maybe a) -> Expr a
forall a. Expr (Maybe a) -> Expr a
unsafeUnnullify Expr (Maybe a)
a


-- | Filter a 'Query' that might return @nullTable@ to a 'Query' without any
-- @nullTable@s.
--
-- Corresponds to 'Data.Maybe.catMaybes'.
catNullTable :: Table Expr a => NullTable Expr a -> Query a
catNullTable :: forall a. Table Expr a => NullTable Expr a -> Query a
catNullTable NullTable Expr a
a = do
  Expr Bool -> Query ()
where_ (Expr Bool -> Query ()) -> Expr Bool -> Query ()
forall a b. (a -> b) -> a -> b
$ NullTable Expr a -> Expr Bool
forall a. Table Expr a => NullTable Expr a -> Expr Bool
isNonNullTable NullTable Expr a
a
  a -> Query a
forall a. a -> Query a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> Query a) -> a -> Query a
forall a b. (a -> b) -> a -> b
$ NullTable Expr a -> a
forall a. NullTable Expr a -> a
unsafeUnnullifyTable NullTable Expr a
a