on master help sign in
Add indexed combinator (#117)
7c33143Shane
Changelog.md+2
@@ -27,6 +27,8 @@
27
27
28* The new `Rel8.Tabulate` module has been added, which gives a `Map`-esque interface to writing and composing queries. ([#70](https://github.com/circuithub/rel8/pull/70))
28* The new `Rel8.Tabulate` module has been added, which gives a `Map`-esque interface to writing and composing queries. ([#70](https://github.com/circuithub/rel8/pull/70))
29
29
30+* The new `indexed` `Query -> Query` function was added. This function augments each row in a query with it's 0-based index. ([#117](https://github.com/circuithub/rel8/pull/117))
31+
30## Breaking changes
32## Breaking changes
31
33
32* `Insert`, `Delete` and `Update` have all changed. In particular, for `Insert` users should now replace `rows = xs` with `rows = values xs`. ([#85](https://github.com/circuithub/rel8/pull/85))
34* `Insert`, `Delete` and `Update` have all changed. In particular, for `Insert` users should now replace `rows = xs` with `rows = values xs`. ([#85](https://github.com/circuithub/rel8/pull/85))
rel8.cabal+1
@@ -106,6 +106,7 @@ library
106 Rel8.Query.Evaluate
106 Rel8.Query.Evaluate
107 Rel8.Query.Exists
107 Rel8.Query.Exists
108 Rel8.Query.Filter
108 Rel8.Query.Filter
109+ Rel8.Query.Indexed
109 Rel8.Query.Limit
110 Rel8.Query.Limit
110 Rel8.Query.List
111 Rel8.Query.List
111 Rel8.Query.Maybe
112 Rel8.Query.Maybe
src/Rel8.hs+4
@@ -244,6 +244,9 @@ module Rel8
244 , nullsFirst
244 , nullsFirst
245 , nullsLast
245 , nullsLast
246
246
247+ -- ** Window functions
248+ , indexed
249+
247 -- ** Bindings
250 -- ** Bindings
248 , rebind
251 , rebind
249
252
@@ -322,6 +325,7 @@ import Rel8.Query.Either
322import Rel8.Query.Evaluate
325import Rel8.Query.Evaluate
323import Rel8.Query.Exists
326import Rel8.Query.Exists
324import Rel8.Query.Filter
327import Rel8.Query.Filter
328+import Rel8.Query.Indexed
325import Rel8.Query.Limit
329import Rel8.Query.Limit
326import Rel8.Query.List
330import Rel8.Query.List
327import Rel8.Query.Maybe
331import Rel8.Query.Maybe
src/Rel8/Query/Indexed.hsnew file+34
@@ -0,0 +1,34 @@
1+module Rel8.Query.Indexed
2+ ( indexed
3+ )
4+where
5+
6+-- base
7+import Data.Int ( Int64 )
8+import Prelude
9+
10+-- opaleye
11+import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye
12+import qualified Opaleye.Internal.PackMap as Opaleye
13+import qualified Opaleye.Internal.PrimQuery as Opaleye
14+import qualified Opaleye.Internal.QueryArr as Opaleye
15+import qualified Opaleye.Internal.Tag as Opaleye
16+
17+-- rel8
18+import Rel8.Expr ( Expr )
19+import Rel8.Expr.Opaleye ( fromPrimExpr )
20+import Rel8.Query ( Query )
21+import Rel8.Query.Opaleye ( mapOpaleye )
22+
23+
24+-- | Pair each row of a query with its index within the query.
25+indexed :: Query a -> Query (Expr Int64, a)
26+indexed = mapOpaleye $ \(Opaleye.QueryArr f) -> Opaleye.QueryArr $ \(_, tag) ->
27+ let
28+ (a, query, tag') = f ((), tag)
29+ tag'' = Opaleye.next tag'
30+ window = Opaleye.ConstExpr $ Opaleye.OtherLit "ROW_NUMBER() OVER () - 1"
31+ (index, bindings) = Opaleye.run $ Opaleye.extractAttr "index" tag' window
32+ query' lateral = Opaleye.Rebind True bindings . query lateral
33+ in
34+ ((fromPrimExpr index, a), query', tag'')