{-# LANGUAGE TypeFamilies, TypeOperators, ConstraintKinds, FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Database.Selda.Nullable
( NonNull, (:?~)
, nonNull, restrict', (?!)
, (?==), (?/=), (?>), (?<), (?>=), (?<=), (?+), (?-), (?*), (?/)
) where
import Database.Selda
import Database.Selda.Unsafe (cast)
import Database.Selda.Selectors
import Database.Selda.Column
import Unsafe.Coerce
type a :?~ b =
( NonNull a ~ NonNull b
, SqlType (NonNull a)
, SqlType (NonNull b)
)
type family NonNull a where
NonNull (Maybe a) = a
NonNull a = a
fromNullable :: SqlType (NonNull a) => Col s a -> Col s (NonNull a)
fromNullable = unsafeCoerce
(?==), (?/=) :: (a :?~ b, SqlType a, Same s t) => Col s a -> Col t b -> Col s (Maybe Bool)
(?>), (?<), (?>=), (?<=) :: (a :?~ b, SqlOrd (NonNull a), Same s t)
=> Col s a -> Col t b -> Col s (Maybe Bool)
(?+), (?-), (?*) :: (a :?~ b, Num (NonNull a), Same s t)
=> Col s a -> Col t b -> Col s (Maybe (NonNull a))
(?/) :: (a :?~ b, Fractional (Col s (NonNull a)), Same s t)
=> Col s a -> Col t b -> Col s (Maybe (NonNull a))
a ?== b = cast $ fromNullable a .== fromNullable b
a ?/= b = cast $ fromNullable a ./= fromNullable b
a ?> b = cast $ fromNullable a .> fromNullable b
a ?< b = cast $ fromNullable a .< fromNullable b
a ?>= b = cast $ fromNullable a .>= fromNullable b
a ?<= b = cast $ fromNullable a .<= fromNullable b
a ?+ b = cast $ fromNullable a + fromNullable b
a ?- b = cast $ fromNullable a - fromNullable b
a ?* b = cast $ fromNullable a * fromNullable b
a ?/ b = cast $ fromNullable a / fromNullable b
infixl 4 ?==
infixl 4 ?/=
infixl 4 ?>
infixl 4 ?<
infixl 4 ?>=
infixl 4 ?<=
infixl 6 ?+
infixl 6 ?-
infixl 7 ?*
infixl 7 ?/
(?!) :: forall s t a. SqlType a
=> Row s t -> Selector (NonNull t) a -> Col s (Coalesce (Maybe a))
(Many xs) ?! i = case xs !! (selectorIndex i) of Untyped x -> One (unsafeCoerce x)
infixl 9 ?!
nonNull :: (Same s t, SqlType a) => Col s (Maybe a) -> Query t (Col t a)
nonNull x = do
restrict (not_ $ isNull x)
return (fromNullable x)
restrict' :: Same s t => Col s (Maybe Bool) -> Query t ()
restrict' = restrict . fromNullable