Add withNonNull helper to project nullable values
Guards against null values with a where_ call.
This commit is contained in:
parent
91ea0b0fca
commit
501cf6b266
@ -41,7 +41,7 @@ module Database.Esqueleto
|
||||
Esqueleto( where_, on, groupBy, orderBy, rand, asc, desc, limit, offset
|
||||
, distinct, distinctOn, don, distinctOnOrderBy, having, locking
|
||||
, sub_select, sub_selectDistinct, (^.), (?.)
|
||||
, val, isNothing, just, nothing, joinV
|
||||
, val, isNothing, just, nothing, joinV, withNonNull
|
||||
, countRows, count, countDistinct
|
||||
, not_, (==.), (>=.), (>.), (<=.), (<.), (!=.), (&&.), (||.)
|
||||
, (+.), (-.), (/.), (*.)
|
||||
|
||||
@ -299,6 +299,12 @@ class (Functor query, Applicative query, Monad query) =>
|
||||
(^.) :: (PersistEntity val, PersistField typ) =>
|
||||
expr (Entity val) -> EntityField val typ -> expr (Value typ)
|
||||
|
||||
-- | Project an expression that may be null, guarding against null cases.
|
||||
withNonNull :: PersistField typ
|
||||
=> expr (Value (Maybe typ))
|
||||
-> (expr (Value typ) -> query a)
|
||||
-> query a
|
||||
|
||||
-- | Project a field of an entity that may be null.
|
||||
(?.) :: (PersistEntity val, PersistField typ) =>
|
||||
expr (Maybe (Entity val)) -> EntityField val typ -> expr (Value (Maybe typ))
|
||||
|
||||
@ -471,6 +471,14 @@ instance Esqueleto SqlQuery SqlExpr SqlBackend where
|
||||
ed = entityDef $ getEntityVal (Proxy :: Proxy (SqlExpr (Entity val)))
|
||||
Just pdef = entityPrimary ed
|
||||
|
||||
withNonNull :: PersistField typ
|
||||
=> SqlExpr (Value (Maybe typ))
|
||||
-> (SqlExpr (Value typ) -> SqlQuery a)
|
||||
-> SqlQuery a
|
||||
withNonNull field f = do
|
||||
where_ $ not_ $ isNothing field
|
||||
f $ veryUnsafeCoerceSqlExprValue field
|
||||
|
||||
EMaybe r ?. field = just (r ^. field)
|
||||
|
||||
val v = ERaw Never $ const ("?", [toPersistValue v])
|
||||
|
||||
10
test/Test.hs
10
test/Test.hs
@ -25,6 +25,7 @@ import Control.Monad.Trans.Control (MonadBaseControl(..))
|
||||
import Control.Monad.Trans.Reader (ReaderT)
|
||||
import Data.Char (toLower, toUpper)
|
||||
import Data.Monoid ((<>))
|
||||
import qualified Data.Maybe as M
|
||||
import Database.Esqueleto
|
||||
#if defined (WITH_POSTGRESQL)
|
||||
import Database.Persist.Postgresql (withPostgresqlConn)
|
||||
@ -688,6 +689,15 @@ main = do
|
||||
return p
|
||||
liftIO $ ret `shouldBe` [ p1e ]
|
||||
|
||||
it "works with withNonNull" $
|
||||
run $ do
|
||||
ps <- traverse insert' [p1, p2, p3, p4, p5]
|
||||
let ages = M.maybeToList =<< map (personAge . entityVal) ps
|
||||
ret <- select $
|
||||
from $ \p ->
|
||||
withNonNull (p ^. PersonAge) return
|
||||
liftIO $ ret `shouldBe` (map Value ages)
|
||||
|
||||
it "works for a many-to-many implicit join" $
|
||||
run $ do
|
||||
p1e@(Entity p1k _) <- insert' p1
|
||||
|
||||
Loading…
Reference in New Issue
Block a user