1{-# language DataKinds #-}
2{-# language FlexibleContexts #-}
3{-# language ScopedTypeVariables #-}
4{-# language TypeApplications #-}
5{-# language TypeFamilies #-}
7{-# options_ghc -fno-warn-redundant-constraints #-}
9module Rel8.Expr.Aggregate
10 ( count, countDistinct, countStar, countWhere
16 , listAggExpr, nonEmptyAggExpr
21import Data.Int ( Int64 )
22import Data.List.NonEmpty ( NonEmpty )
23import Prelude hiding ( and, max, min, null, or, sum )
26import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye
29import Rel8.Aggregate ( Aggregate, Aggregator(..), unsafeMakeAggregate )
30import Rel8.Expr ( Expr )
31import Rel8.Expr.Bool ( caseExpr )
32import Rel8.Expr.Opaleye
38import Rel8.Expr.Null ( null )
39import Rel8.Expr.Serialize ( litExpr )
40import Rel8.Schema.Nullability ( Sql )
41import Rel8.Type.Array ( fromPrimArray )
42import Rel8.Type.Eq ( DBEq )
43import Rel8.Type.Num ( DBNum )
44import Rel8.Type.Ord ( DBMax, DBMin )
45import Rel8.Type.String ( DBString )
46import Rel8.Type.Sum ( DBSum )
49-- | Count the occurances of a single column. Corresponds to @COUNT(a)@
50count :: Expr a -> Aggregate (Expr Int64)
51count = unsafeMakeAggregate toPrimExpr fromPrimExpr $
53 { operation = Opaleye.AggrCount
55 , distinction = Opaleye.AggrAll
59-- | Count the number of distinct occurances of a single column. Corresponds to
61countDistinct :: Sql DBEq a => Expr a -> Aggregate (Expr Int64)
62countDistinct = unsafeMakeAggregate toPrimExpr fromPrimExpr $
64 { operation = Opaleye.AggrCount
66 , distinction = Opaleye.AggrDistinct
70-- | Corresponds to @COUNT(*)@.
71countStar :: Aggregate (Expr Int64)
72countStar = count (litExpr True)
75-- | A count of the number of times a given expression is @true@.
76countWhere :: Expr Bool -> Aggregate (Expr Int64)
77countWhere condition = count (caseExpr [(condition, litExpr (Just True))] null)
80-- | Corresponds to @bool_and@.
81and :: Expr Bool -> Aggregate (Expr Bool)
82and = unsafeMakeAggregate toPrimExpr fromPrimExpr $
84 { operation = Opaleye.AggrBoolAnd
86 , distinction = Opaleye.AggrAll
90-- | Corresponds to @bool_or@.
91or :: Expr Bool -> Aggregate (Expr Bool)
92or = unsafeMakeAggregate toPrimExpr fromPrimExpr $
94 { operation = Opaleye.AggrBoolOr
96 , distinction = Opaleye.AggrAll
100-- | Produce an aggregation for @Expr a@ using the @max@ function.
101max :: Sql DBMax a => Expr a -> Aggregate (Expr a)
102max = unsafeMakeAggregate toPrimExpr fromPrimExpr $
104 { operation = Opaleye.AggrSum
106 , distinction = Opaleye.AggrAll
110-- | Produce an aggregation for @Expr a@ using the @max@ function.
111min :: Sql DBMin a => Expr a -> Aggregate (Expr a)
112min = unsafeMakeAggregate toPrimExpr fromPrimExpr $
114 { operation = Opaleye.AggrSum
116 , distinction = Opaleye.AggrAll
119-- | Corresponds to @sum@. Note that in SQL, @sum@ is type changing - for
120-- example the @sum@ of @integer@ returns a @bigint@. Rel8 doesn't support
121-- this, and will add explicit cast back to the original input type. This can
122-- lead to overflows, and if you anticipate very large sums, you should upcast
124sum :: Sql DBSum a => Expr a -> Aggregate (Expr a)
125sum = unsafeMakeAggregate toPrimExpr (castExpr . fromPrimExpr) $
127 { operation = Opaleye.AggrSum
129 , distinction = Opaleye.AggrAll
133sumWhere :: (Sql DBNum a, Sql DBSum a)
134 => Expr Bool -> Expr a -> Aggregate (Expr a)
135sumWhere condition a = sum (caseExpr [(condition, a)] 0)
138-- | Corresponds to @string_agg()@.
139stringAgg :: Sql DBString a
140 => Expr db -> Expr a -> Aggregate (Expr a)
142 unsafeMakeAggregate toPrimExpr (castExpr . fromPrimExpr) $
144 { operation = Opaleye.AggrStringAggr (toPrimExpr delimiter)
146 , distinction = Opaleye.AggrAll
150-- | Aggregate a value by grouping by it.
151groupByExpr :: Sql DBEq a => Expr a -> Aggregate (Expr a)
152groupByExpr = unsafeMakeAggregate toPrimExpr fromPrimExpr Nothing
155listAggExpr :: Expr a -> Aggregate (Expr [a])
156listAggExpr = unsafeMakeAggregate toPrimExpr from $ Just
158 { operation = Opaleye.AggrArr
160 , distinction = Opaleye.AggrAll
163 from = fromPrimExpr . fromPrimArray
166nonEmptyAggExpr :: Expr a -> Aggregate (Expr (NonEmpty a))
167nonEmptyAggExpr = unsafeMakeAggregate toPrimExpr from $ Just
169 { operation = Opaleye.AggrArr
171 , distinction = Opaleye.AggrAll
174 from = fromPrimExpr . fromPrimArray
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list