on master help sign in
5 files changed+31−92
since splitsnapshots
unifiedsplit
rel8.cabal+1−1 shell.nix+1−1 src/Rel8/Aggregate.hs+11−19 src/Rel8/Expr/Aggregate.hs+16−70 src/Rel8/Expr/Sequence.hs+2−1
rel8.cabal+1−1
@@ -27,7 +27,7 @@ library
2727 , comonad
2828 , contravariant
2929 , hasql ^>= 1.4.5.1 || ^>= 1.5.0.0 || ^>= 1.6.0.0
30− , opaleye ^>= 0.9.6.0
30+ , opaleye ^>= 0.9.6.1
3131 , pretty
3232 , profunctors
3333 , product-profunctors
shell.nix+1−1
@@ -1,6 +1,6 @@
11let
22 sources = import ./nix/sources.nix;
3− pkgs = import sources.nixpkgs {};
3+ pkgs = import sources.nixpkgs {overlays = [];};
44 hsPkgs = import ./default.nix;
55in
66 hsPkgs.shellFor {
src/Rel8/Aggregate.hs+11−19
@@ -2,7 +2,6 @@
22{-# language FlexibleContexts #-}
33{-# language FlexibleInstances #-}
44{-# language MultiParamTypeClasses #-}
5−{-# language NamedFieldPuns #-}
65{-# language RankNTypes #-}
76{-# language StandaloneKindSignatures #-}
87{-# language TypeFamilies #-}
@@ -10,7 +9,7 @@
109
1110module Rel8.Aggregate
1211 ( Aggregate(..), zipOutputs
13− , Aggregator(..), unsafeMakeAggregate
12+ , unsafeMakeAggregate
1413 , Aggregates
1514 )
1615where
@@ -21,10 +20,13 @@ import Data.Functor.Identity ( Identity( Identity ) )
2120import Data.Kind ( Constraint, Type )
2221import Prelude
2322
23+-- profunctors
24+import Data.Profunctor ( dimap )
25+
2426-- opaleye
25−import qualified Opaleye.Internal.Aggregate as Opaleye
27+import qualified Opaleye.Aggregate as Opaleye
2628import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye
27−import qualified Opaleye.Internal.PackMap as Opaleye
29+import qualified Opaleye.Internal.Column as Opaleye
2830
2931-- rel8
3032import Rel8.Expr ( Expr )
@@ -69,23 +71,13 @@ zipOutputs :: ()
6971zipOutputs f (Aggregate a) (Aggregate b) = Aggregate (liftA2 f a b)
7072
7173
72−type Aggregator :: Type
73−data Aggregator = Aggregator
74− { operation :: Opaleye.AggrOp
75− , ordering :: [Opaleye.OrderExpr]
76− , distinction :: Opaleye.AggrDistinct
77− }
78−
79−
80−unsafeMakeAggregate :: forall (input :: Type) (output :: Type). ()
74+unsafeMakeAggregate :: forall (input :: Type) (output :: Type) n n' a a'. ()
8175 => (Expr input -> Opaleye.PrimExpr)
8276 -> (Opaleye.PrimExpr -> Expr output)
83− -> Maybe Aggregator
77+ -> Opaleye.Aggregator (Opaleye.Field_ n a) (Opaleye.Field_ n' a')
8478 -> Expr input
8579 -> Aggregate output
8680unsafeMakeAggregate input output aggregator expr =
87− Aggregate $ Opaleye.Aggregator $ Opaleye.PackMap $ \f _ ->
88− output <$> f (tuplize <$> aggregator, input expr)
89− where
90− tuplize Aggregator {operation, ordering, distinction} =
91− (operation, ordering, distinction)
81+ Aggregate $ dimap in_ out aggregator
82+ where out = output . Opaleye.unColumn
83+ in_ = Opaleye.Column . input . const expr
src/Rel8/Expr/Aggregate.hs+16−70
@@ -24,10 +24,12 @@ import Data.List.NonEmpty ( NonEmpty )
2424import Prelude hiding ( and, max, min, null, or, sum )
2525
2626-- opaleye
27−import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye
27+import qualified Opaleye.Internal.Aggregate as Opaleye
28+import Opaleye.Internal.Column ( Field_( Column ) )
29+import qualified Opaleye.Aggregate as Opaleye
2830
2931-- rel8
30−import Rel8.Aggregate ( Aggregate, Aggregator(..), unsafeMakeAggregate )
32+import Rel8.Aggregate ( Aggregate, unsafeMakeAggregate )
3133import Rel8.Expr ( Expr )
3234import Rel8.Expr.Bool ( caseExpr )
3335import Rel8.Expr.Opaleye
@@ -51,23 +53,13 @@ import Rel8.Type.Sum ( DBSum )
5153
5254-- | Count the occurances of a single column. Corresponds to @COUNT(a)@
5355count :: Expr a -> Aggregate Int64
54−count = unsafeMakeAggregate toPrimExpr fromPrimExpr $
55− Just Aggregator
56− { operation = Opaleye.AggrCount
57− , ordering = []
58− , distinction = Opaleye.AggrAll
59− }
60−
56+count = unsafeMakeAggregate toPrimExpr fromPrimExpr Opaleye.count
6157
6258-- | Count the number of distinct occurances of a single column. Corresponds to
6359-- @COUNT(DISTINCT a)@
6460countDistinct :: Sql DBEq a => Expr a -> Aggregate Int64
6561countDistinct = unsafeMakeAggregate toPrimExpr fromPrimExpr $
66− Just Aggregator
67− { operation = Opaleye.AggrCount
68− , ordering = []
69− , distinction = Opaleye.AggrDistinct
70− }
62+ Opaleye.distinctAggregator Opaleye.count
7163
7264
7365-- | Corresponds to @COUNT(*)@.
@@ -82,42 +74,22 @@ countWhere condition = count (caseExpr [(condition, litExpr (Just True))] null)
8274
8375-- | Corresponds to @bool_and@.
8476and :: Expr Bool -> Aggregate Bool
85−and = unsafeMakeAggregate toPrimExpr fromPrimExpr $
86− Just Aggregator
87− { operation = Opaleye.AggrBoolAnd
88− , ordering = []
89− , distinction = Opaleye.AggrAll
90− }
77+and = unsafeMakeAggregate toPrimExpr fromPrimExpr Opaleye.boolAnd
9178
9279
9380-- | Corresponds to @bool_or@.
9481or :: Expr Bool -> Aggregate Bool
95−or = unsafeMakeAggregate toPrimExpr fromPrimExpr $
96− Just Aggregator
97− { operation = Opaleye.AggrBoolOr
98− , ordering = []
99− , distinction = Opaleye.AggrAll
100− }
82+or = unsafeMakeAggregate toPrimExpr fromPrimExpr Opaleye.boolOr
10183
10284
10385-- | Produce an aggregation for @Expr a@ using the @max@ function.
10486max :: Sql DBMax a => Expr a -> Aggregate a
105−max = unsafeMakeAggregate toPrimExpr fromPrimExpr $
106− Just Aggregator
107− { operation = Opaleye.AggrMax
108− , ordering = []
109− , distinction = Opaleye.AggrAll
110− }
87+max = unsafeMakeAggregate toPrimExpr fromPrimExpr Opaleye.unsafeMax
11188
11289
11390-- | Produce an aggregation for @Expr a@ using the @max@ function.
11491min :: Sql DBMin a => Expr a -> Aggregate a
115−min = unsafeMakeAggregate toPrimExpr fromPrimExpr $
116− Just Aggregator
117− { operation = Opaleye.AggrMin
118− , ordering = []
119− , distinction = Opaleye.AggrAll
120− }
92+min = unsafeMakeAggregate toPrimExpr fromPrimExpr Opaleye.unsafeMin
12193
12294-- | Corresponds to @sum@. Note that in SQL, @sum@ is type changing - for
12395-- example the @sum@ of @integer@ returns a @bigint@. Rel8 doesn't support
@@ -125,12 +97,7 @@ min = unsafeMakeAggregate toPrimExpr fromPrimExpr $
12597-- lead to overflows, and if you anticipate very large sums, you should upcast
12698-- your input.
12799sum :: Sql DBSum a => Expr a -> Aggregate a
128−sum = unsafeMakeAggregate toPrimExpr (castExpr . fromPrimExpr) $
129− Just Aggregator
130− { operation = Opaleye.AggrSum
131− , ordering = []
132− , distinction = Opaleye.AggrAll
133− }
100+sum = unsafeMakeAggregate toPrimExpr (castExpr . fromPrimExpr) Opaleye.unsafeSum
134101
135102
136103-- | Corresponds to @avg@. Note that in SQL, @avg@ is type changing - for
@@ -139,13 +106,7 @@ sum = unsafeMakeAggregate toPrimExpr (castExpr . fromPrimExpr) $
139106-- need a fractional result on an integral column, you should cast your input
140107-- to 'Double' or 'Data.Scientific.Scientific' before calling 'avg'.
141108avg :: Sql DBSum a => Expr a -> Aggregate a
142−avg = unsafeMakeAggregate toPrimExpr (castExpr . fromPrimExpr) $
143− Just Aggregator
144− { operation = Opaleye.AggrAvg
145− , ordering = []
146− , distinction = Opaleye.AggrAll
147− }
148−
109+avg = unsafeMakeAggregate toPrimExpr (castExpr . fromPrimExpr) Opaleye.unsafeAvg
149110
150111-- | Take the sum of all expressions that satisfy a predicate.
151112sumWhere :: (Sql DBNum a, Sql DBSum a)
@@ -157,17 +118,12 @@ sumWhere condition a = sum (caseExpr [(condition, a)] 0)
157118stringAgg :: Sql DBString a
158119 => Expr db -> Expr a -> Aggregate a
159120stringAgg delimiter =
160− unsafeMakeAggregate toPrimExpr (castExpr . fromPrimExpr) $
161− Just Aggregator
162− { operation = Opaleye.AggrStringAggr (toPrimExpr delimiter)
163− , ordering = []
164− , distinction = Opaleye.AggrAll
165− }
121+ unsafeMakeAggregate toPrimExpr (castExpr . fromPrimExpr) (Opaleye.stringAgg (Column (toPrimExpr delimiter)))
166122
167123
168124-- | Aggregate a value by grouping by it.
169125groupByExpr :: Sql DBEq a => Expr a -> Aggregate a
170−groupByExpr = unsafeMakeAggregate toPrimExpr fromPrimExpr Nothing
126+groupByExpr = unsafeMakeAggregate toPrimExpr fromPrimExpr Opaleye.groupBy
171127
172128
173129-- | Collect expressions values as a list.
@@ -182,23 +138,13 @@ nonEmptyAggExpr = snonEmptyAggExpr typeInformation
182138
183139slistAggExpr :: ()
184140 => TypeInformation (Unnullify a) -> Expr a -> Aggregate [a]
185−slistAggExpr info = unsafeMakeAggregate to fromPrimExpr $ Just
186− Aggregator
187− { operation = Opaleye.AggrArr
188− , ordering = []
189− , distinction = Opaleye.AggrAll
190− }
141+slistAggExpr info = unsafeMakeAggregate to fromPrimExpr Opaleye.arrayAgg
191142 where
192143 to = encodeArrayElement info . toPrimExpr
193144
194145
195146snonEmptyAggExpr :: ()
196147 => TypeInformation (Unnullify a) -> Expr a -> Aggregate (NonEmpty a)
197−snonEmptyAggExpr info = unsafeMakeAggregate to fromPrimExpr $ Just
198− Aggregator
199− { operation = Opaleye.AggrArr
200− , ordering = []
201− , distinction = Opaleye.AggrAll
202− }
148+snonEmptyAggExpr info = unsafeMakeAggregate to fromPrimExpr Opaleye.arrayAgg
203149 where
204150 to = encodeArrayElement info . toPrimExpr
src/Rel8/Expr/Sequence.hs+2−1
@@ -11,6 +11,7 @@ import Prelude
1111import Rel8.Expr ( Expr )
1212import Rel8.Expr.Function ( function )
1313import Rel8.Expr.Serialize ( litExpr )
14+import Rel8.Expr.Text ( quoteIdent )
1415
1516-- text
1617import Data.Text ( pack )
@@ -18,4 +19,4 @@ import Data.Text ( pack )
1819
1920-- | See https://www.postgresql.org/docs/current/functions-sequence.html
2021nextval :: String -> Expr Int64
21−nextval = function "nextval" . litExpr . pack
22+nextval = function "nextval" . quoteIdent . litExpr . pack