1{-# language FlexibleContexts #-}
2{-# language NamedFieldPuns #-}
3{-# language ScopedTypeVariables #-}
4{-# language TypeApplications #-}
5{-# language TypeFamilies #-}
6{-# language ViewPatterns #-}
8module Rel8.Table.Aggregate
17import Data.Functor.Identity ( Identity( Identity ) )
21import Rel8.Aggregate ( Aggregate )
22import Rel8.Expr ( Expr )
23import Rel8.Expr.Aggregate ( listAggExpr, nonEmptyAggExpr, sgroupByExpr )
24import Rel8.Schema.Context ( Col'(..) )
25import Rel8.Schema.Dict ( Dict( Dict ) )
26import Rel8.Schema.HTable ( htabulate, hfield, hdicts, hspecs )
27import Rel8.Schema.HTable.Vectorize ( hvectorize )
28import Rel8.Schema.Spec ( SSpec(..) )
29import Rel8.Schema.Spec.ConstrainDBType ( ConstrainDBType )
30import Rel8.Table ( Table, Columns, toColumns, fromColumns )
31import Rel8.Table.Eq ( EqTable )
32import Rel8.Table.List ( ListTable )
33import Rel8.Table.NonEmpty ( NonEmptyTable )
34import Rel8.Table.Recontextualize ( Aggregates )
35import Rel8.Type.Eq ( DBEq )
38-- | Group equal tables together. This works by aggregating each column in the
39-- given table with 'groupByExpr'.
40groupBy :: forall exprs. EqTable exprs => exprs -> Aggregate exprs
41groupBy (toColumns -> exprs) = fromColumns $ htabulate $ \field ->
42 case hfield dicts field of
43 Dict -> case hfield hspecs field of
44 SSpec {nullability} -> case hfield exprs field of
45 DB expr -> Aggregation $ sgroupByExpr nullability expr
47 dicts = hdicts @(Columns exprs) @(ConstrainDBType DBEq)
50-- | Aggregate rows into a single row containing an array of all aggregated
51-- rows. This can be used to associate multiple rows with a single row, without
52-- changing the over cardinality of the query. This allows you to essentially
53-- return a tree-like structure from queries.
55-- For example, if we have a table of orders and each orders contains multiple
56-- items, we could aggregate the table of orders, pairing each order with its
60-- ordersWithItems :: Query (Order Expr, ListTable (Item Expr))
61-- ordersWithItems = do
62-- order <- each orderSchema
63-- items <- aggregate $ listAgg <$> itemsFromOrder order
64-- return (order, items)
66listAgg :: Table Expr exprs => exprs -> Aggregate (ListTable exprs)
67listAgg (toColumns -> exprs) = fromColumns $
69 (\_ (Identity (DB a)) -> Aggregation $ listAggExpr a)
73-- | Like 'listAgg', but the result is guaranteed to be a non-empty list.
74nonEmptyAgg :: Table Expr exprs => exprs -> Aggregate (NonEmptyTable exprs)
75nonEmptyAgg (toColumns -> exprs) = fromColumns $
77 (\_ (Identity (DB a)) -> Aggregation $ nonEmptyAggExpr a)
81runAggregation :: Aggregates aggregates exprs => aggregates -> Aggregate exprs
82runAggregation = fromColumns . toColumns
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