Merge pull request #22 from db81/less_general_max

Less general aggregate functions and NULL handling.
This commit is contained in:
Felipe Lessa 2013-08-08 10:39:28 -07:00
commit 4056e13bef
4 changed files with 23 additions and 16 deletions

View File

@ -40,10 +40,11 @@ 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_
, random_, round_, ceiling_, floor_
, min_, max_,_sum_, avg_,
, like, (%), concat_, (++.)
, subList_select, subList_selectDistinct, valList
, in_, notIn, exists, notExists

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,10 +240,11 @@ 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, PersistField b) => expr (Value a) -> expr (Value b)
min_ :: (PersistField a, PersistField b) => expr (Value a) -> expr (Value b)
max_ :: (PersistField a, PersistField b) => expr (Value a) -> expr (Value b)
avg_ :: (PersistField a, PersistField b) => expr (Value a) -> expr (Value b)
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 (Maybe b))
-- | @LIKE@ operator.
like :: (PersistField s, IsString s) => expr (Value s) -> expr (Value s) -> expr (Value Bool)

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
@ -285,8 +285,8 @@ main = do
_ <- insert' p4
ret <- select $
from $ \p->
return $ avg_ (p ^. PersonAge)
liftIO $ ret `shouldBe` [ Value ((36 + 17 + 17) / 3 :: Double) ]
return $ joinV $ avg_ (p ^. PersonAge)
liftIO $ ret `shouldBe` [ Value $ Just ((36 + 17 + 17) / 3 :: Double) ]
it "works with min_" $
run $ do
@ -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