{-# language DataKinds #-}
{-# language FlexibleContexts #-}
{-# language ScopedTypeVariables #-}
{-# language TypeFamilies #-}
{-# options_ghc -fno-warn-redundant-constraints #-}
module Rel8.Expr.Aggregate
( count, countDistinct, countStar, countWhere
, and, or
, min, max
, sum, sumWhere
, stringAgg
, groupByExpr
, listAggExpr, nonEmptyAggExpr
, slistAggExpr, snonEmptyAggExpr
)
where
import Data.Int ( Int64 )
import Data.List.NonEmpty ( NonEmpty )
import Prelude hiding ( and, max, min, null, or, sum )
import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye
import Rel8.Aggregate ( Aggregate, Aggregator(..), unsafeMakeAggregate )
import Rel8.Expr ( Expr )
import Rel8.Expr.Bool ( caseExpr )
import Rel8.Expr.Opaleye
( castExpr
, fromPrimExpr
, fromPrimExpr
, toPrimExpr
)
import Rel8.Expr.Null ( null )
import Rel8.Expr.Serialize ( litExpr )
import Rel8.Schema.Null ( Sql, Unnullify )
import Rel8.Type ( DBType, typeInformation )
import Rel8.Type.Array ( encodeArrayElement )
import Rel8.Type.Eq ( DBEq )
import Rel8.Type.Information ( TypeInformation )
import Rel8.Type.Num ( DBNum )
import Rel8.Type.Ord ( DBMax, DBMin )
import Rel8.Type.String ( DBString )
import Rel8.Type.Sum ( DBSum )
count :: Expr a -> Aggregate Int64
count :: Expr a -> Aggregate Int64
count = (Expr a -> PrimExpr)
-> (PrimExpr -> Expr Int64)
-> Maybe Aggregator
-> Expr a
-> Aggregate Int64
forall k1 k2 (input :: k1) (output :: k2).
(Expr input -> PrimExpr)
-> (PrimExpr -> Expr output)
-> Maybe Aggregator
-> Expr input
-> Aggregate output
unsafeMakeAggregate Expr a -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr PrimExpr -> Expr Int64
forall a. PrimExpr -> Expr a
fromPrimExpr (Maybe Aggregator -> Expr a -> Aggregate Int64)
-> Maybe Aggregator -> Expr a -> Aggregate Int64
forall a b. (a -> b) -> a -> b
$
Aggregator -> Maybe Aggregator
forall a. a -> Maybe a
Just Aggregator :: AggrOp -> [OrderExpr] -> AggrDistinct -> Aggregator
Aggregator
{ operation :: AggrOp
operation = AggrOp
Opaleye.AggrCount
, ordering :: [OrderExpr]
ordering = []
, distinction :: AggrDistinct
distinction = AggrDistinct
Opaleye.AggrAll
}
countDistinct :: Sql DBEq a => Expr a -> Aggregate Int64
countDistinct :: Expr a -> Aggregate Int64
countDistinct = (Expr a -> PrimExpr)
-> (PrimExpr -> Expr Int64)
-> Maybe Aggregator
-> Expr a
-> Aggregate Int64
forall k1 k2 (input :: k1) (output :: k2).
(Expr input -> PrimExpr)
-> (PrimExpr -> Expr output)
-> Maybe Aggregator
-> Expr input
-> Aggregate output
unsafeMakeAggregate Expr a -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr PrimExpr -> Expr Int64
forall a. PrimExpr -> Expr a
fromPrimExpr (Maybe Aggregator -> Expr a -> Aggregate Int64)
-> Maybe Aggregator -> Expr a -> Aggregate Int64
forall a b. (a -> b) -> a -> b
$
Aggregator -> Maybe Aggregator
forall a. a -> Maybe a
Just Aggregator :: AggrOp -> [OrderExpr] -> AggrDistinct -> Aggregator
Aggregator
{ operation :: AggrOp
operation = AggrOp
Opaleye.AggrCount
, ordering :: [OrderExpr]
ordering = []
, distinction :: AggrDistinct
distinction = AggrDistinct
Opaleye.AggrDistinct
}
countStar :: Aggregate Int64
countStar :: Aggregate Int64
countStar = Expr Bool -> Aggregate Int64
forall a. Expr a -> Aggregate Int64
count (Bool -> Expr Bool
forall a. Sql DBType a => a -> Expr a
litExpr Bool
True)
countWhere :: Expr Bool -> Aggregate Int64
countWhere :: Expr Bool -> Aggregate Int64
countWhere Expr Bool
condition = Expr (Maybe Bool) -> Aggregate Int64
forall a. Expr a -> Aggregate Int64
count ([(Expr Bool, Expr (Maybe Bool))]
-> Expr (Maybe Bool) -> Expr (Maybe Bool)
forall a. [(Expr Bool, Expr a)] -> Expr a -> Expr a
caseExpr [(Expr Bool
condition, Maybe Bool -> Expr (Maybe Bool)
forall a. Sql DBType a => a -> Expr a
litExpr (Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True))] Expr (Maybe Bool)
forall a. DBType a => Expr (Maybe a)
null)
and :: Expr Bool -> Aggregate Bool
and :: Expr Bool -> Aggregate Bool
and = (Expr Bool -> PrimExpr)
-> (PrimExpr -> Expr Bool)
-> Maybe Aggregator
-> Expr Bool
-> Aggregate Bool
forall k1 k2 (input :: k1) (output :: k2).
(Expr input -> PrimExpr)
-> (PrimExpr -> Expr output)
-> Maybe Aggregator
-> Expr input
-> Aggregate output
unsafeMakeAggregate Expr Bool -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr PrimExpr -> Expr Bool
forall a. PrimExpr -> Expr a
fromPrimExpr (Maybe Aggregator -> Expr Bool -> Aggregate Bool)
-> Maybe Aggregator -> Expr Bool -> Aggregate Bool
forall a b. (a -> b) -> a -> b
$
Aggregator -> Maybe Aggregator
forall a. a -> Maybe a
Just Aggregator :: AggrOp -> [OrderExpr] -> AggrDistinct -> Aggregator
Aggregator
{ operation :: AggrOp
operation = AggrOp
Opaleye.AggrBoolAnd
, ordering :: [OrderExpr]
ordering = []
, distinction :: AggrDistinct
distinction = AggrDistinct
Opaleye.AggrAll
}
or :: Expr Bool -> Aggregate Bool
or :: Expr Bool -> Aggregate Bool
or = (Expr Bool -> PrimExpr)
-> (PrimExpr -> Expr Bool)
-> Maybe Aggregator
-> Expr Bool
-> Aggregate Bool
forall k1 k2 (input :: k1) (output :: k2).
(Expr input -> PrimExpr)
-> (PrimExpr -> Expr output)
-> Maybe Aggregator
-> Expr input
-> Aggregate output
unsafeMakeAggregate Expr Bool -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr PrimExpr -> Expr Bool
forall a. PrimExpr -> Expr a
fromPrimExpr (Maybe Aggregator -> Expr Bool -> Aggregate Bool)
-> Maybe Aggregator -> Expr Bool -> Aggregate Bool
forall a b. (a -> b) -> a -> b
$
Aggregator -> Maybe Aggregator
forall a. a -> Maybe a
Just Aggregator :: AggrOp -> [OrderExpr] -> AggrDistinct -> Aggregator
Aggregator
{ operation :: AggrOp
operation = AggrOp
Opaleye.AggrBoolOr
, ordering :: [OrderExpr]
ordering = []
, distinction :: AggrDistinct
distinction = AggrDistinct
Opaleye.AggrAll
}
max :: Sql DBMax a => Expr a -> Aggregate a
max :: Expr a -> Aggregate a
max = (Expr a -> PrimExpr)
-> (PrimExpr -> Expr a)
-> Maybe Aggregator
-> Expr a
-> Aggregate a
forall k1 k2 (input :: k1) (output :: k2).
(Expr input -> PrimExpr)
-> (PrimExpr -> Expr output)
-> Maybe Aggregator
-> Expr input
-> Aggregate output
unsafeMakeAggregate Expr a -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr PrimExpr -> Expr a
forall a. PrimExpr -> Expr a
fromPrimExpr (Maybe Aggregator -> Expr a -> Aggregate a)
-> Maybe Aggregator -> Expr a -> Aggregate a
forall a b. (a -> b) -> a -> b
$
Aggregator -> Maybe Aggregator
forall a. a -> Maybe a
Just Aggregator :: AggrOp -> [OrderExpr] -> AggrDistinct -> Aggregator
Aggregator
{ operation :: AggrOp
operation = AggrOp
Opaleye.AggrMax
, ordering :: [OrderExpr]
ordering = []
, distinction :: AggrDistinct
distinction = AggrDistinct
Opaleye.AggrAll
}
min :: Sql DBMin a => Expr a -> Aggregate a
min :: Expr a -> Aggregate a
min = (Expr a -> PrimExpr)
-> (PrimExpr -> Expr a)
-> Maybe Aggregator
-> Expr a
-> Aggregate a
forall k1 k2 (input :: k1) (output :: k2).
(Expr input -> PrimExpr)
-> (PrimExpr -> Expr output)
-> Maybe Aggregator
-> Expr input
-> Aggregate output
unsafeMakeAggregate Expr a -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr PrimExpr -> Expr a
forall a. PrimExpr -> Expr a
fromPrimExpr (Maybe Aggregator -> Expr a -> Aggregate a)
-> Maybe Aggregator -> Expr a -> Aggregate a
forall a b. (a -> b) -> a -> b
$
Aggregator -> Maybe Aggregator
forall a. a -> Maybe a
Just Aggregator :: AggrOp -> [OrderExpr] -> AggrDistinct -> Aggregator
Aggregator
{ operation :: AggrOp
operation = AggrOp
Opaleye.AggrMin
, ordering :: [OrderExpr]
ordering = []
, distinction :: AggrDistinct
distinction = AggrDistinct
Opaleye.AggrAll
}
sum :: Sql DBSum a => Expr a -> Aggregate a
sum :: Expr a -> Aggregate a
sum = (Expr a -> PrimExpr)
-> (PrimExpr -> Expr a)
-> Maybe Aggregator
-> Expr a
-> Aggregate a
forall k1 k2 (input :: k1) (output :: k2).
(Expr input -> PrimExpr)
-> (PrimExpr -> Expr output)
-> Maybe Aggregator
-> Expr input
-> Aggregate output
unsafeMakeAggregate Expr a -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr (Expr a -> Expr a
forall a. Sql DBType a => Expr a -> Expr a
castExpr (Expr a -> Expr a) -> (PrimExpr -> Expr a) -> PrimExpr -> Expr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PrimExpr -> Expr a
forall a. PrimExpr -> Expr a
fromPrimExpr) (Maybe Aggregator -> Expr a -> Aggregate a)
-> Maybe Aggregator -> Expr a -> Aggregate a
forall a b. (a -> b) -> a -> b
$
Aggregator -> Maybe Aggregator
forall a. a -> Maybe a
Just Aggregator :: AggrOp -> [OrderExpr] -> AggrDistinct -> Aggregator
Aggregator
{ operation :: AggrOp
operation = AggrOp
Opaleye.AggrSum
, ordering :: [OrderExpr]
ordering = []
, distinction :: AggrDistinct
distinction = AggrDistinct
Opaleye.AggrAll
}
sumWhere :: (Sql DBNum a, Sql DBSum a)
=> Expr Bool -> Expr a -> Aggregate a
sumWhere :: Expr Bool -> Expr a -> Aggregate a
sumWhere Expr Bool
condition Expr a
a = Expr a -> Aggregate a
forall a. Sql DBSum a => Expr a -> Aggregate a
sum ([(Expr Bool, Expr a)] -> Expr a -> Expr a
forall a. [(Expr Bool, Expr a)] -> Expr a -> Expr a
caseExpr [(Expr Bool
condition, Expr a
a)] Expr a
0)
stringAgg :: Sql DBString a
=> Expr db -> Expr a -> Aggregate a
stringAgg :: Expr db -> Expr a -> Aggregate a
stringAgg Expr db
delimiter =
(Expr a -> PrimExpr)
-> (PrimExpr -> Expr a)
-> Maybe Aggregator
-> Expr a
-> Aggregate a
forall k1 k2 (input :: k1) (output :: k2).
(Expr input -> PrimExpr)
-> (PrimExpr -> Expr output)
-> Maybe Aggregator
-> Expr input
-> Aggregate output
unsafeMakeAggregate Expr a -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr (Expr a -> Expr a
forall a. Sql DBType a => Expr a -> Expr a
castExpr (Expr a -> Expr a) -> (PrimExpr -> Expr a) -> PrimExpr -> Expr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PrimExpr -> Expr a
forall a. PrimExpr -> Expr a
fromPrimExpr) (Maybe Aggregator -> Expr a -> Aggregate a)
-> Maybe Aggregator -> Expr a -> Aggregate a
forall a b. (a -> b) -> a -> b
$
Aggregator -> Maybe Aggregator
forall a. a -> Maybe a
Just Aggregator :: AggrOp -> [OrderExpr] -> AggrDistinct -> Aggregator
Aggregator
{ operation :: AggrOp
operation = PrimExpr -> AggrOp
Opaleye.AggrStringAggr (Expr db -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr Expr db
delimiter)
, ordering :: [OrderExpr]
ordering = []
, distinction :: AggrDistinct
distinction = AggrDistinct
Opaleye.AggrAll
}
groupByExpr :: Sql DBEq a => Expr a -> Aggregate a
groupByExpr :: Expr a -> Aggregate a
groupByExpr = (Expr a -> PrimExpr)
-> (PrimExpr -> Expr a)
-> Maybe Aggregator
-> Expr a
-> Aggregate a
forall k1 k2 (input :: k1) (output :: k2).
(Expr input -> PrimExpr)
-> (PrimExpr -> Expr output)
-> Maybe Aggregator
-> Expr input
-> Aggregate output
unsafeMakeAggregate Expr a -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr PrimExpr -> Expr a
forall a. PrimExpr -> Expr a
fromPrimExpr Maybe Aggregator
forall a. Maybe a
Nothing
listAggExpr :: Sql DBType a => Expr a -> Aggregate [a]
listAggExpr :: Expr a -> Aggregate [a]
listAggExpr = TypeInformation (Unnullify a) -> Expr a -> Aggregate [a]
forall a. TypeInformation (Unnullify a) -> Expr a -> Aggregate [a]
slistAggExpr TypeInformation (Unnullify a)
forall a. DBType a => TypeInformation a
typeInformation
nonEmptyAggExpr :: Sql DBType a => Expr a -> Aggregate (NonEmpty a)
nonEmptyAggExpr :: Expr a -> Aggregate (NonEmpty a)
nonEmptyAggExpr = TypeInformation (Unnullify a) -> Expr a -> Aggregate (NonEmpty a)
forall a.
TypeInformation (Unnullify a) -> Expr a -> Aggregate (NonEmpty a)
snonEmptyAggExpr TypeInformation (Unnullify a)
forall a. DBType a => TypeInformation a
typeInformation
slistAggExpr :: ()
=> TypeInformation (Unnullify a) -> Expr a -> Aggregate [a]
slistAggExpr :: TypeInformation (Unnullify a) -> Expr a -> Aggregate [a]
slistAggExpr TypeInformation (Unnullify a)
info = (Expr a -> PrimExpr)
-> (PrimExpr -> Expr [a])
-> Maybe Aggregator
-> Expr a
-> Aggregate [a]
forall k1 k2 (input :: k1) (output :: k2).
(Expr input -> PrimExpr)
-> (PrimExpr -> Expr output)
-> Maybe Aggregator
-> Expr input
-> Aggregate output
unsafeMakeAggregate Expr a -> PrimExpr
to PrimExpr -> Expr [a]
forall a. PrimExpr -> Expr a
fromPrimExpr (Maybe Aggregator -> Expr a -> Aggregate [a])
-> Maybe Aggregator -> Expr a -> Aggregate [a]
forall a b. (a -> b) -> a -> b
$ Aggregator -> Maybe Aggregator
forall a. a -> Maybe a
Just
Aggregator :: AggrOp -> [OrderExpr] -> AggrDistinct -> Aggregator
Aggregator
{ operation :: AggrOp
operation = AggrOp
Opaleye.AggrArr
, ordering :: [OrderExpr]
ordering = []
, distinction :: AggrDistinct
distinction = AggrDistinct
Opaleye.AggrAll
}
where
to :: Expr a -> PrimExpr
to = TypeInformation (Unnullify a) -> PrimExpr -> PrimExpr
forall a. TypeInformation a -> PrimExpr -> PrimExpr
encodeArrayElement TypeInformation (Unnullify a)
info (PrimExpr -> PrimExpr)
-> (Expr a -> PrimExpr) -> Expr a -> PrimExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr a -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr
snonEmptyAggExpr :: ()
=> TypeInformation (Unnullify a) -> Expr a -> Aggregate (NonEmpty a)
snonEmptyAggExpr :: TypeInformation (Unnullify a) -> Expr a -> Aggregate (NonEmpty a)
snonEmptyAggExpr TypeInformation (Unnullify a)
info = (Expr a -> PrimExpr)
-> (PrimExpr -> Expr (NonEmpty a))
-> Maybe Aggregator
-> Expr a
-> Aggregate (NonEmpty a)
forall k1 k2 (input :: k1) (output :: k2).
(Expr input -> PrimExpr)
-> (PrimExpr -> Expr output)
-> Maybe Aggregator
-> Expr input
-> Aggregate output
unsafeMakeAggregate Expr a -> PrimExpr
to PrimExpr -> Expr (NonEmpty a)
forall a. PrimExpr -> Expr a
fromPrimExpr (Maybe Aggregator -> Expr a -> Aggregate (NonEmpty a))
-> Maybe Aggregator -> Expr a -> Aggregate (NonEmpty a)
forall a b. (a -> b) -> a -> b
$ Aggregator -> Maybe Aggregator
forall a. a -> Maybe a
Just
Aggregator :: AggrOp -> [OrderExpr] -> AggrDistinct -> Aggregator
Aggregator
{ operation :: AggrOp
operation = AggrOp
Opaleye.AggrArr
, ordering :: [OrderExpr]
ordering = []
, distinction :: AggrDistinct
distinction = AggrDistinct
Opaleye.AggrAll
}
where
to :: Expr a -> PrimExpr
to = TypeInformation (Unnullify a) -> PrimExpr -> PrimExpr
forall a. TypeInformation a -> PrimExpr -> PrimExpr
encodeArrayElement TypeInformation (Unnullify a)
info (PrimExpr -> PrimExpr)
-> (Expr a -> PrimExpr) -> Expr a -> PrimExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr a -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr