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:
Danny B 2013-08-08 15:51:31 +11:00
parent 83dc4a433c
commit 068ec9b1ae
4 changed files with 17 additions and 12 deletions

View File

@ -40,7 +40,7 @@ module Database.Esqueleto
-- * @esqueleto@'s Language
Esqueleto( where_, on, groupBy, orderBy, asc, desc, limit, offset, having
, 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_

View File

@ -208,6 +208,10 @@ class (Functor query, Applicative query, Monad query) =>
-- | @NULL@ value.
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.
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)
ceiling_ :: (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)
min_ :: (PersistField a) => expr (Value a) -> expr (Value a)
max_ :: (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 (Maybe a))
max_ :: (PersistField a) => expr (Value a) -> expr (Value (Maybe a))
avg_ :: (PersistField a, PersistField b) => expr (Value a) -> expr (Value b)
-- | @LIKE@ operator.

View File

@ -313,6 +313,7 @@ instance Esqueleto SqlQuery SqlExpr SqlBackend where
isNothing (ERaw p f) = ERaw Parens $ first ((<> " IS NULL") . parensM p) . f
just (ERaw p f) = ERaw p f
nothing = unsafeSqlValue "NULL"
joinV (ERaw p f) = ERaw p f
countRows = unsafeSqlValue "COUNT(*)"
count (ERaw _ f) = ERaw Never $ \conn -> let (b, vals) = f conn
in ("COUNT" <> parens b, vals)
@ -1432,7 +1433,7 @@ to16 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p)) = (a,b,c,d,e,f,g,h,i,j,k,
-- | Apply extra @SqlExpr Value@ arguments to a 'PersistField' constructor
(<&>) :: SqlExpr (Insertion (a -> b)) -> SqlExpr (Value a) -> SqlExpr (Insertion b)
(EInsert _ f) <&> (ERaw _ g) = EInsert Proxy $ \x->
(EInsert _ f) <&> (ERaw _ g) = EInsert Proxy $ \x->
let (fb, fv) = f x
(gb, gv) = g x
in (fb <> ", " <> gb, fv ++ gv)

View File

@ -274,10 +274,10 @@ main = do
_ <- insert' p4
ret <- select $
from $ \p->
return $ sum_ (p ^. PersonAge)
liftIO $ ret `shouldBe` [ Value (36 + 17 + 17 :: Int) ]
return $ joinV $ sum_ (p ^. PersonAge)
liftIO $ ret `shouldBe` [ Value $ Just (36 + 17 + 17 :: Int) ]
it "works with sum_" $
it "works with avg_" $
run $ do
_ <- insert' p1
_ <- insert' p2
@ -296,8 +296,8 @@ main = do
_ <- insert' p4
ret <- select $
from $ \p->
return $ min_ (p ^. PersonAge)
liftIO $ ret `shouldBe` [ Value (17 :: Int) ]
return $ joinV $ min_ (p ^. PersonAge)
liftIO $ ret `shouldBe` [ Value $ Just (17 :: Int) ]
it "works with max_" $
run $ do
@ -307,8 +307,8 @@ main = do
_ <- insert' p4
ret <- select $
from $ \p->
return $ max_ (p ^. PersonAge)
liftIO $ ret `shouldBe` [ Value (36 :: Int) ]
return $ joinV $ max_ (p ^. PersonAge)
liftIO $ ret `shouldBe` [ Value $ Just (36 :: Int) ]
it "works with random_" $
run $ do