Proper NULL handling in max_, min_ and sum_.
- return expr (Value (Maybe a)) - add joinV to join nested Maybes in an expr
This commit is contained in:
parent
83dc4a433c
commit
068ec9b1ae
@ -40,7 +40,7 @@ module Database.Esqueleto
|
|||||||
-- * @esqueleto@'s Language
|
-- * @esqueleto@'s Language
|
||||||
Esqueleto( where_, on, groupBy, orderBy, asc, desc, limit, offset, having
|
Esqueleto( where_, on, groupBy, orderBy, asc, desc, limit, offset, having
|
||||||
, sub_select, sub_selectDistinct, (^.), (?.)
|
, sub_select, sub_selectDistinct, (^.), (?.)
|
||||||
, val, isNothing, just, nothing, countRows, count, not_
|
, val, isNothing, just, nothing, joinV, countRows, count, not_
|
||||||
, (==.), (>=.), (>.), (<=.), (<.), (!=.), (&&.), (||.)
|
, (==.), (>=.), (>.), (<=.), (<.), (!=.), (&&.), (||.)
|
||||||
, (+.), (-.), (/.), (*.)
|
, (+.), (-.), (/.), (*.)
|
||||||
, random_, sum_, round_, ceiling_, floor_, avg_, min_, max_
|
, random_, sum_, round_, ceiling_, floor_, avg_, min_, max_
|
||||||
|
|||||||
@ -208,6 +208,10 @@ class (Functor query, Applicative query, Monad query) =>
|
|||||||
-- | @NULL@ value.
|
-- | @NULL@ value.
|
||||||
nothing :: expr (Value (Maybe typ))
|
nothing :: expr (Value (Maybe typ))
|
||||||
|
|
||||||
|
-- | Join nested 'Maybe's in a 'Value' into one. This is useful when
|
||||||
|
-- calling aggregate functions on nullable fields.
|
||||||
|
joinV :: expr (Value (Maybe (Maybe typ))) -> expr (Value (Maybe typ))
|
||||||
|
|
||||||
-- | @COUNT(*)@ value.
|
-- | @COUNT(*)@ value.
|
||||||
countRows :: Num a => expr (Value a)
|
countRows :: Num a => expr (Value a)
|
||||||
|
|
||||||
@ -236,9 +240,9 @@ class (Functor query, Applicative query, Monad query) =>
|
|||||||
round_ :: (PersistField a, PersistField b) => expr (Value a) -> expr (Value b)
|
round_ :: (PersistField a, PersistField b) => expr (Value a) -> expr (Value b)
|
||||||
ceiling_ :: (PersistField a, PersistField b) => expr (Value a) -> expr (Value b)
|
ceiling_ :: (PersistField a, PersistField b) => expr (Value a) -> expr (Value b)
|
||||||
floor_ :: (PersistField a, PersistField b) => expr (Value a) -> expr (Value b)
|
floor_ :: (PersistField a, PersistField b) => expr (Value a) -> expr (Value b)
|
||||||
sum_ :: (PersistField a) => expr (Value a) -> expr (Value a)
|
sum_ :: (PersistField a) => expr (Value a) -> expr (Value (Maybe a))
|
||||||
min_ :: (PersistField a) => expr (Value a) -> expr (Value a)
|
min_ :: (PersistField a) => expr (Value a) -> expr (Value (Maybe a))
|
||||||
max_ :: (PersistField a) => expr (Value a) -> expr (Value a)
|
max_ :: (PersistField a) => expr (Value a) -> expr (Value (Maybe a))
|
||||||
avg_ :: (PersistField a, PersistField b) => expr (Value a) -> expr (Value b)
|
avg_ :: (PersistField a, PersistField b) => expr (Value a) -> expr (Value b)
|
||||||
|
|
||||||
-- | @LIKE@ operator.
|
-- | @LIKE@ operator.
|
||||||
|
|||||||
@ -313,6 +313,7 @@ instance Esqueleto SqlQuery SqlExpr SqlBackend where
|
|||||||
isNothing (ERaw p f) = ERaw Parens $ first ((<> " IS NULL") . parensM p) . f
|
isNothing (ERaw p f) = ERaw Parens $ first ((<> " IS NULL") . parensM p) . f
|
||||||
just (ERaw p f) = ERaw p f
|
just (ERaw p f) = ERaw p f
|
||||||
nothing = unsafeSqlValue "NULL"
|
nothing = unsafeSqlValue "NULL"
|
||||||
|
joinV (ERaw p f) = ERaw p f
|
||||||
countRows = unsafeSqlValue "COUNT(*)"
|
countRows = unsafeSqlValue "COUNT(*)"
|
||||||
count (ERaw _ f) = ERaw Never $ \conn -> let (b, vals) = f conn
|
count (ERaw _ f) = ERaw Never $ \conn -> let (b, vals) = f conn
|
||||||
in ("COUNT" <> parens b, vals)
|
in ("COUNT" <> parens b, vals)
|
||||||
|
|||||||
14
test/Test.hs
14
test/Test.hs
@ -274,10 +274,10 @@ main = do
|
|||||||
_ <- insert' p4
|
_ <- insert' p4
|
||||||
ret <- select $
|
ret <- select $
|
||||||
from $ \p->
|
from $ \p->
|
||||||
return $ sum_ (p ^. PersonAge)
|
return $ joinV $ sum_ (p ^. PersonAge)
|
||||||
liftIO $ ret `shouldBe` [ Value (36 + 17 + 17 :: Int) ]
|
liftIO $ ret `shouldBe` [ Value $ Just (36 + 17 + 17 :: Int) ]
|
||||||
|
|
||||||
it "works with sum_" $
|
it "works with avg_" $
|
||||||
run $ do
|
run $ do
|
||||||
_ <- insert' p1
|
_ <- insert' p1
|
||||||
_ <- insert' p2
|
_ <- insert' p2
|
||||||
@ -296,8 +296,8 @@ main = do
|
|||||||
_ <- insert' p4
|
_ <- insert' p4
|
||||||
ret <- select $
|
ret <- select $
|
||||||
from $ \p->
|
from $ \p->
|
||||||
return $ min_ (p ^. PersonAge)
|
return $ joinV $ min_ (p ^. PersonAge)
|
||||||
liftIO $ ret `shouldBe` [ Value (17 :: Int) ]
|
liftIO $ ret `shouldBe` [ Value $ Just (17 :: Int) ]
|
||||||
|
|
||||||
it "works with max_" $
|
it "works with max_" $
|
||||||
run $ do
|
run $ do
|
||||||
@ -307,8 +307,8 @@ main = do
|
|||||||
_ <- insert' p4
|
_ <- insert' p4
|
||||||
ret <- select $
|
ret <- select $
|
||||||
from $ \p->
|
from $ \p->
|
||||||
return $ max_ (p ^. PersonAge)
|
return $ joinV $ max_ (p ^. PersonAge)
|
||||||
liftIO $ ret `shouldBe` [ Value (36 :: Int) ]
|
liftIO $ ret `shouldBe` [ Value $ Just (36 :: Int) ]
|
||||||
|
|
||||||
it "works with random_" $
|
it "works with random_" $
|
||||||
run $ do
|
run $ do
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user