{-# OPTIONS_GHC -fno-warn-duplicate-exports #-}
-- | Do not use.  Will be deprecated in version 0.8.  Use
-- "Opaleye.Field" instead.
--
-- Functions for working directly with 'Column's.
--
-- Please note that numeric 'Column' types are instances of 'Num', so
-- you can use '*', '/', '+', '-' on them.
--
-- 'Column' will be renamed to 'Opaleye.Field.Field_' in version 0.8,
-- so you might want to use the latter as much as you can.

module Opaleye.Column (-- * 'Column'
                       Column,
                       -- * Working with @NULL@
                       Nullable,
                       null,
                       isNull,
                       matchNullable,
                       fromNullable,
                       toNullable,
                       maybeToNullable,
                       -- * Unsafe operations
                       unsafeCast,
                       unsafeCoerceColumn,
                       unsafeCompositeField,
                       -- * Entire module
                       module Opaleye.Column)  where

import           Opaleye.Internal.Column (Column, Nullable, unsafeCoerceColumn,
                                          unsafeCast, unsafeCompositeField)
import qualified Opaleye.Internal.Column as C
import qualified Opaleye.Internal.HaskellDB.PrimQuery as HPQ
import qualified Opaleye.Internal.PGTypesExternal as T
import           Prelude hiding (null)

-- | A NULL of any type
null :: Column (Nullable a)
null :: Column (Nullable a)
null = PrimExpr -> Column (Nullable a)
forall pgType. PrimExpr -> Column pgType
C.Column (Literal -> PrimExpr
HPQ.ConstExpr Literal
HPQ.NullLit)

-- | @TRUE@ if the value of the column is @NULL@, @FALSE@ otherwise.
isNull :: Column (Nullable a) -> Column T.PGBool
isNull :: Column (Nullable a) -> Column PGBool
isNull = UnOp -> Column (Nullable a) -> Column PGBool
forall a b. UnOp -> Column a -> Column b
C.unOp UnOp
HPQ.OpIsNull

-- | If the @Column (Nullable a)@ is NULL then return the @Column b@
-- otherwise map the underlying @Column a@ using the provided
-- function.
--
-- The Opaleye equivalent of 'Data.Maybe.maybe'.
matchNullable :: Column b -> (Column a -> Column b) -> Column (Nullable a)
              -> Column b
matchNullable :: Column b
-> (Column a -> Column b) -> Column (Nullable a) -> Column b
matchNullable Column b
replacement Column a -> Column b
f Column (Nullable a)
x = Column PGBool -> Column b -> Column b -> Column b
forall pgBool a. Column pgBool -> Column a -> Column a -> Column a
C.unsafeIfThenElse (Column (Nullable a) -> Column PGBool
forall a. Column (Nullable a) -> Column PGBool
isNull Column (Nullable a)
x) Column b
replacement
                                                   (Column a -> Column b
f (Column (Nullable a) -> Column a
forall a b. Column a -> Column b
unsafeCoerceColumn Column (Nullable a)
x))

-- | If the @Column (Nullable a)@ is NULL then return the provided
-- @Column a@ otherwise return the underlying @Column a@.
--
-- The Opaleye equivalent of 'Data.Maybe.fromMaybe' and very similar
-- to PostgreSQL's @COALESCE@.
fromNullable :: Column a -> Column (Nullable a) -> Column a
fromNullable :: Column a -> Column (Nullable a) -> Column a
fromNullable = (Column a
 -> (Column a -> Column a) -> Column (Nullable a) -> Column a)
-> (Column a -> Column a)
-> Column a
-> Column (Nullable a)
-> Column a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Column a
-> (Column a -> Column a) -> Column (Nullable a) -> Column a
forall b a.
Column b
-> (Column a -> Column b) -> Column (Nullable a) -> Column b
matchNullable Column a -> Column a
forall a. a -> a
id

-- | Treat a column as though it were nullable.  This is always safe.
--
-- The Opaleye equivalent of 'Data.Maybe.Just'.
toNullable :: Column a -> Column (Nullable a)
toNullable :: Column a -> Column (Nullable a)
toNullable = Column a -> Column (Nullable a)
forall a b. Column a -> Column b
unsafeCoerceColumn

-- | If the argument is 'Data.Maybe.Nothing' return NULL otherwise return the
-- provided value coerced to a nullable type.
maybeToNullable :: Maybe (Column a) -> Column (Nullable a)
maybeToNullable :: Maybe (Column a) -> Column (Nullable a)
maybeToNullable = Column (Nullable a)
-> (Column a -> Column (Nullable a))
-> Maybe (Column a)
-> Column (Nullable a)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Column (Nullable a)
forall a. Column (Nullable a)
null Column a -> Column (Nullable a)
forall a. Column a -> Column (Nullable a)
toNullable

joinNullable :: Column (Nullable (Nullable a)) -> Column (Nullable a)
joinNullable :: Column (Nullable (Nullable a)) -> Column (Nullable a)
joinNullable = Column (Nullable (Nullable a)) -> Column (Nullable a)
forall a b. Column a -> Column b
unsafeCoerceColumn