Merge pull request #62 from bigs/add-nullable-helpers
Add withNonNull helper to project nullable values
This commit is contained in:
commit
ecace06c37
@ -41,7 +41,7 @@ module Database.Esqueleto
|
|||||||
Esqueleto( where_, on, groupBy, orderBy, rand, asc, desc, limit, offset
|
Esqueleto( where_, on, groupBy, orderBy, rand, asc, desc, limit, offset
|
||||||
, distinct, distinctOn, don, distinctOnOrderBy, having, locking
|
, distinct, distinctOn, don, distinctOnOrderBy, having, locking
|
||||||
, sub_select, sub_selectDistinct, (^.), (?.)
|
, sub_select, sub_selectDistinct, (^.), (?.)
|
||||||
, val, isNothing, just, nothing, joinV
|
, val, isNothing, just, nothing, joinV, withNonNull
|
||||||
, countRows, count, countDistinct
|
, countRows, count, countDistinct
|
||||||
, not_, (==.), (>=.), (>.), (<=.), (<.), (!=.), (&&.), (||.)
|
, not_, (==.), (>=.), (>.), (<=.), (<.), (!=.), (&&.), (||.)
|
||||||
, (+.), (-.), (/.), (*.)
|
, (+.), (-.), (/.), (*.)
|
||||||
|
|||||||
@ -299,6 +299,12 @@ class (Functor query, Applicative query, Monad query) =>
|
|||||||
(^.) :: (PersistEntity val, PersistField typ) =>
|
(^.) :: (PersistEntity val, PersistField typ) =>
|
||||||
expr (Entity val) -> EntityField val typ -> expr (Value 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.
|
-- | Project a field of an entity that may be null.
|
||||||
(?.) :: (PersistEntity val, PersistField typ) =>
|
(?.) :: (PersistEntity val, PersistField typ) =>
|
||||||
expr (Maybe (Entity val)) -> EntityField val typ -> expr (Value (Maybe 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)))
|
ed = entityDef $ getEntityVal (Proxy :: Proxy (SqlExpr (Entity val)))
|
||||||
Just pdef = entityPrimary ed
|
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)
|
EMaybe r ?. field = just (r ^. field)
|
||||||
|
|
||||||
val v = ERaw Never $ const ("?", [toPersistValue v])
|
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 Control.Monad.Trans.Reader (ReaderT)
|
||||||
import Data.Char (toLower, toUpper)
|
import Data.Char (toLower, toUpper)
|
||||||
import Data.Monoid ((<>))
|
import Data.Monoid ((<>))
|
||||||
|
import qualified Data.Maybe as M
|
||||||
import Database.Esqueleto
|
import Database.Esqueleto
|
||||||
#if defined (WITH_POSTGRESQL)
|
#if defined (WITH_POSTGRESQL)
|
||||||
import Database.Persist.Postgresql (withPostgresqlConn)
|
import Database.Persist.Postgresql (withPostgresqlConn)
|
||||||
@ -688,6 +689,15 @@ main = do
|
|||||||
return p
|
return p
|
||||||
liftIO $ ret `shouldBe` [ p1e ]
|
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" $
|
it "works for a many-to-many implicit join" $
|
||||||
run $ do
|
run $ do
|
||||||
p1e@(Entity p1k _) <- insert' p1
|
p1e@(Entity p1k _) <- insert' p1
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user